]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: suppress callsite signatures if any type is unknown
authorEmmanuel Odeke <emm.odeke@gmail.com>
Sat, 11 Feb 2017 06:41:53 +0000 (23:41 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 22 Feb 2017 17:55:45 +0000 (17:55 +0000)
Fixes #19012.

Fallback to return signatures without detailed types.
These error message will be of the form of issue:
* https://golang.org/issues/4215
* https://golang.org/issues/6750

So:
func f(x int, y uint) {
    return x > y
}

f(10, "a" < 3)

will give errors:
too many errors to return
too many arguments in call to f

instead of:

too many errors to return
  have (<T>)
  want ()
too many arguments in call to f
  have (number, <T>)
  want (number, number)

Change-Id: I680abc7cdd8444400e234caddf3ff49c2d69f53d
Reviewed-on: https://go-review.googlesource.com/36806
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/gc/typecheck.go
test/fixedbugs/issue19012.go [new file with mode: 0644]

index a6acb6a776e6cd225187385b05bc0d18f122c2df..d13182568870cea4bb7fac67ed5a1640de757180 100644 (file)
@@ -2700,17 +2700,18 @@ out:
 
 notenough:
        if n == nil || !n.Diag {
+               details := errorDetails(nl, tstruct, isddd)
                if call != nil {
                        // call is the expression being called, not the overall call.
                        // Method expressions have the form T.M, and the compiler has
                        // rewritten those to ONAME nodes but left T in Left.
                        if call.Op == ONAME && call.Left != nil && call.Left.Op == OTYPE {
-                               yyerror("not enough arguments in call to method expression %v\n\thave %s\n\twant %v", call, nl.retsigerr(isddd), tstruct)
+                               yyerror("not enough arguments in call to method expression %v%s", call, details)
                        } else {
-                               yyerror("not enough arguments in call to %v\n\thave %s\n\twant %v", call, nl.retsigerr(isddd), tstruct)
+                               yyerror("not enough arguments in call to %v%s", call, details)
                        }
                } else {
-                       yyerror("not enough arguments to %v\n\thave %s\n\twant %v", op, nl.retsigerr(isddd), tstruct)
+                       yyerror("not enough arguments to %v%s", op, details)
                }
                if n != nil {
                        n.Diag = true
@@ -2720,14 +2721,30 @@ notenough:
        goto out
 
 toomany:
+       details := errorDetails(nl, tstruct, isddd)
        if call != nil {
-               yyerror("too many arguments in call to %v\n\thave %s\n\twant %v", call, nl.retsigerr(isddd), tstruct)
+               yyerror("too many arguments in call to %v%s", call, details)
        } else {
-               yyerror("too many arguments to %v\n\thave %s\n\twant %v", op, nl.retsigerr(isddd), tstruct)
+               yyerror("too many arguments to %v%s", op, details)
        }
        goto out
 }
 
+func errorDetails(nl Nodes, tstruct *Type, isddd bool) string {
+       // If we don't know any type at a call site, let's suppress any return
+       // message signatures. See Issue https://golang.org/issues/19012.
+       if tstruct == nil {
+               return ""
+       }
+       // If any node has an unknown type, suppress it as well
+       for _, n := range nl.Slice() {
+               if n.Type == nil {
+                       return ""
+               }
+       }
+       return fmt.Sprintf("\n\thave %s\n\twant %v", nl.retsigerr(isddd), tstruct)
+}
+
 // sigrepr is a type's representation to the outside world,
 // in string representations of return signatures
 // e.g in error messages about wrong arguments to return.
diff --git a/test/fixedbugs/issue19012.go b/test/fixedbugs/issue19012.go
new file mode 100644 (file)
index 0000000..636bf06
--- /dev/null
@@ -0,0 +1,25 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 19012: if we have any unknown type at a call site,
+// we must ensure that we return to the user a suppressed
+// error message saying instead of including <T> in
+// the message.
+
+package main
+
+func f(x int, y uint) {
+       if true {
+               return "a" > 10 // ERROR "^too many arguments to return$" "."
+       }
+       return "gopher" == true, 10 // ERROR "^too many arguments to return$" "."
+}
+
+func main() {
+       f(2, 3 < "x", 10) // ERROR "^too many arguments in call to f$" "."
+
+       f(10, 10, "a") // ERROR "too many arguments in call to f\n\thave \(number, number, string\)\n\twant \(int, uint\)"
+}