Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gofmt falls into an infinite loop when using rewrite feature #1667

Closed
stevvooe opened this issue Apr 6, 2011 · 2 comments
Closed

gofmt falls into an infinite loop when using rewrite feature #1667

stevvooe opened this issue Apr 6, 2011 · 2 comments

Comments

@stevvooe
Copy link

stevvooe commented Apr 6, 2011

What steps will reproduce the problem?

**Be careful reproducing this as this will take all of the memory on your machine very
quickly.

1. cd into src/pkg/contianer/vector
2. run make generate
3. ???
4. All your cpu and memory are gone.

You can ^C out of the make call, but it will overwrite your intvector.go file in that
directory. So, make sure to revert intvector.go.

Simplified reproduction:

// foo.go

package main

type Foo int

func main() {
    var a Foo
    println(a)
}

$ gofmt -r='Foo -> Bar' foo.go 

What is the expected output?

gofmt should change type Foo to type Bar.

What do you see instead?

No output. Memory usage and cpu usage is unbounded. Gofmt gets locked in an infinite
loop.

Which compiler are you using (5g, 6g, 8g, gccgo)?

6g

Which operating system are you using?

Mac OS X 10.5.7

Which revision are you using?  (hg identify)

$ hg identify
b002b8e25d25 tip

Please provide any additional information below.

I isolated this problem to a change between weekly.2011-03-15 and weekly.2011-03-28
(sorry this is so wide). It doesn't seem to be related to the cpuprofiler addition to
gofmt because when I compile the 03-15 version with the 03-28 tree, we still see the
problem. I isolated the loop down to the following function in rewrite.go (in the gofmt
cmd dir):

 49 // rewriteFile applies the rewrite rule 'pattern -> replace' to an entire file.
 50 func rewriteFile(pattern, replace ast.Expr, p *ast.File) *ast.File {
 51     m := make(map[string]reflect.Value)
 52     pat := reflect.NewValue(pattern)
 53     repl := reflect.NewValue(replace)
 54     var f func(val reflect.Value) reflect.Value // f is recursive
 55     f = func(val reflect.Value) reflect.Value {
 56         for k := range m {
 57             m[k] = nil, false
 58         }
 59         val = apply(f, val)
 60         if match(m, pat, val) {
 61             val = subst(m, repl, reflect.NewValue(val.Interface().(ast.Node).Pos()))
 62         }
 63         return val
 64     }
 65     return apply(f, reflect.NewValue(p)).Interface().(*ast.File)
 66 }

Please let me know if you need anything else.
@griesemer
Copy link
Contributor

Comment 1:

Owner changed to @griesemer.

Status changed to Accepted.

@griesemer
Copy link
Contributor

Comment 2:

This issue was closed by revision a5ca635.

Status changed to Fixed.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants