mirror of
https://github.com/golang/go
synced 2024-11-02 13:21:55 +00:00
cmd/compile: suppress callsite signatures if any type is unknown
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>
This commit is contained in:
parent
ffb3b3698c
commit
19d2061d50
2 changed files with 47 additions and 5 deletions
|
@ -2700,17 +2700,18 @@ out:
|
||||||
|
|
||||||
notenough:
|
notenough:
|
||||||
if n == nil || !n.Diag {
|
if n == nil || !n.Diag {
|
||||||
|
details := errorDetails(nl, tstruct, isddd)
|
||||||
if call != nil {
|
if call != nil {
|
||||||
// call is the expression being called, not the overall call.
|
// call is the expression being called, not the overall call.
|
||||||
// Method expressions have the form T.M, and the compiler has
|
// Method expressions have the form T.M, and the compiler has
|
||||||
// rewritten those to ONAME nodes but left T in Left.
|
// rewritten those to ONAME nodes but left T in Left.
|
||||||
if call.Op == ONAME && call.Left != nil && call.Left.Op == OTYPE {
|
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 {
|
} 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 {
|
} 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 {
|
if n != nil {
|
||||||
n.Diag = true
|
n.Diag = true
|
||||||
|
@ -2720,14 +2721,30 @@ notenough:
|
||||||
goto out
|
goto out
|
||||||
|
|
||||||
toomany:
|
toomany:
|
||||||
|
details := errorDetails(nl, tstruct, isddd)
|
||||||
if call != nil {
|
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 {
|
} 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
|
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,
|
// sigrepr is a type's representation to the outside world,
|
||||||
// in string representations of return signatures
|
// in string representations of return signatures
|
||||||
// e.g in error messages about wrong arguments to return.
|
// e.g in error messages about wrong arguments to return.
|
||||||
|
|
25
test/fixedbugs/issue19012.go
Normal file
25
test/fixedbugs/issue19012.go
Normal file
|
@ -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\)"
|
||||||
|
}
|
Loading…
Reference in a new issue