Cannot reduce program that doesn't type-check (internal compiler error)
ALTree opened this issue · 9 comments
I'm on go version devel +5e954047bc Fri Mar 24 20:07:15 2017 +0000 linux/amd64
.
The following code:
package b
func Func2107() {
if false {
Var2528 := (**[1]*int)(nil)
(func() map[interface{}]uint {
return map[interface{}]uint{}
})()[interface{}(nil)]--
}
}
crashes goreduce when run as goreduce -match="cannot inline" . Func2107
with:
panic: types.Check should not error here
goroutine 1 [running]:
main.(*reducer).reduceLoop(0xc4200ac8c0, 0x0)
/home/alberto/gocode/src/github.com/mvdan/goreduce/reduce.go:230 +0x2b8
main.reduce(0x7ffceafc94ad, 0x1, 0x7ffceafc94af, 0x8, 0x7ffceafc949f, 0xd, 0x7ff880, 0xc42000c020, 0xc42000e220, 0x0, ...)
/home/alberto/gocode/src/github.com/mvdan/goreduce/reduce.go:150 +0x1213
main.main()
/home/alberto/gocode/src/github.com/mvdan/goreduce/main.go:44 +0x10e
Thanks for reporting! Not sure why this would happen.
Ah, this is a weird one. The issue is that go/types
finds Var2528
is declared but not used, but cmd/compile
does not. I was relying on the fact that if cmd/compile
correctly type-checked a program, go/types
would accept it too.
Seems like we can't tell go/types
to ignore unused variables - only unused imports.
The only other solution I can think of right now is to ignore go/types
errors and try our best without them. A quick test makes goreduce
get to:
package b
func Func2107() {
if false {
Var2528 := (*[0]int)(nil)
func() map[interface{}]uint {
return map[interface{}]uint{}
}()[interface{}(nil)]--
}
}
This is a slippery slope though, as the reducer can't do much without type information.
@josharian do you know why cmd/compile
and go/types
diverge like this? Or is this a cmd/compile
bug and I should file an issue?
Another insight: cmd/compile
does error properly on this:
func f() {
if false {
foo := 1
}
}
So it seems like the issue is that cmd/compile
got to the internal error before getting to the type checker (unused var) error. Not sure what to do here, if we want the tool to be able to work with these compiler errors.
I see two ways: either you want goreduce to work on programs that crash the compiler (and I don't know if that's feasible); or you can just say "yeah if it crashes the compiler don't run goreduce on it" and in that case I guess you could just fix goreduce so that it reports what's wrong (i.e. compiler error) instead of panicking.
@ALTree while reducing runtime crashes or simpler compiler errors is useful, I would like the tool to also be able to work on internal compiler errors. After all, these are the ones that are likely to be found by tools like gosmith.
IMO the question is: is there anything to be done to be able to get type info (like get go/types
to get past soft errors), or should it just do its best with just the AST if type info is not available?
Ah, I believe we can indeed get go/types
to ignore soft errors by using the types.Config.Error
callback func. Will run some tests.
Okay, that worked. Thanks for reporting, I hadn't thought about internal compiler errors much yet (I didn't have any to test on, to begin with).
Also, if either of you has any idea on how to have unit/regression tests for compiler crashes, that would be great. I obviously can't rely on real ones, as they would be fixed sooner than later.