cmd/internal/gc: detect bad append(f()) during type check

Today's earlier fix can stay, but it's a band-aid over the real problem,
which is that bad code was slipping through the type checker
into the back end (and luckily causing a type error there).

I discovered this because my new append does not use the same
temporaries and failed the test as written.

Fixes #9521.

Change-Id: I7e33e2ea15743406e15c6f3fdf73e1edecda69bd
Reviewed-on: https://go-review.googlesource.com/9921
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Russ Cox 2015-05-11 16:12:01 -04:00
parent 29dc4b40f8
commit 3f209abb29
2 changed files with 19 additions and 10 deletions

View file

@ -1636,11 +1636,10 @@ OpSwitch:
}
// Unpack multiple-return result before type-checking.
var funarg *Type
if Istype(t, TSTRUCT) && t.Funarg != 0 {
t = t.Type
if Istype(t, TFIELD) {
t = t.Type
}
funarg = t
t = t.Type.Type
}
n.Type = t
@ -1678,11 +1677,19 @@ OpSwitch:
break OpSwitch
}
for args = args.Next; args != nil; args = args.Next {
if args.N.Type == nil {
continue
if funarg != nil {
for t := funarg.Type.Down; t != nil; t = t.Down {
if assignop(t.Type, n.Type.Type, nil) == 0 {
Yyerror("cannot append %v value to []%v", t.Type, n.Type.Type)
}
}
} else {
for args = args.Next; args != nil; args = args.Next {
if args.N.Type == nil {
continue
}
args.N = assignconv(args.N, t.Type, "append")
}
args.N = assignconv(args.N, t.Type, "append")
}
break OpSwitch

View file

@ -9,8 +9,10 @@
package main
func f() (_, _ []int) { return }
func f() (_, _ []int) { return }
func g() (x []int, y float64) { return }
func main() {
_ = append(f()) // ERROR "cannot use _"
_ = append(f()) // ERROR "cannot append \[\]int value to \[\]int"
_ = append(g()) // ERROR "cannot append float64 value to \[\]int"
}