]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/gc: detect bad append(f()) during type check
authorRuss Cox <rsc@golang.org>
Mon, 11 May 2015 20:12:01 +0000 (16:12 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 12 May 2015 16:26:35 +0000 (16:26 +0000)
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>
src/cmd/internal/gc/typecheck.go
test/fixedbugs/issue9521.go

index fdd393d0cf7a96519ea3c39cb44204c907e5fa6e..185cfecc685874bda54c91a067b6488bfd211be5 100644 (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
index 51b5204e7a4e5474c541f851a8e0c1366505f5dc..ef0a5a654700ec373c7106abe647f5555060e80a 100644 (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"
 }