cmd/compile: skip array bounds errors when type is broken

This avoids false positives
like those found in #19880.

Fixes #19880

Change-Id: I583c16cc3c71e7462a72500db9ea2547c468f8c1
Reviewed-on: https://go-review.googlesource.com/40255
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2017-04-10 13:43:36 -07:00
parent 97b89dc055
commit 423e7e6037
6 changed files with 54 additions and 7 deletions

View file

@ -369,9 +369,12 @@ OpSwitch:
n.Left = indexlit(typecheck(n.Left, Erv)) n.Left = indexlit(typecheck(n.Left, Erv))
l := n.Left l := n.Left
if consttype(l) != CTINT { if consttype(l) != CTINT {
if l.Type != nil && l.Type.IsInteger() && l.Op != OLITERAL { switch {
case l.Type == nil:
// Error already reported elsewhere.
case l.Type.IsInteger() && l.Op != OLITERAL:
yyerror("non-constant array bound %v", l) yyerror("non-constant array bound %v", l)
} else { default:
yyerror("invalid array bound %v", l) yyerror("invalid array bound %v", l)
} }
n.Type = nil n.Type = nil

View file

@ -11,7 +11,7 @@ var b [1e1]int // ok
var c [1.5]int // ERROR "truncated" var c [1.5]int // ERROR "truncated"
var d ["abc"]int // ERROR "invalid array bound|not numeric" var d ["abc"]int // ERROR "invalid array bound|not numeric"
var e [nil]int // ERROR "use of untyped nil|invalid array bound|not numeric" var e [nil]int // ERROR "use of untyped nil|invalid array bound|not numeric"
var f [e]int // ERROR "invalid array bound|not constant" var f [e]int // ok: error already reported for e
var g [1 << 65]int // ERROR "array bound is too large|overflows" var g [1 << 65]int // ERROR "array bound is too large|overflows"
var h [len(a)]int // ok var h [len(a)]int // ok

View file

@ -0,0 +1,20 @@
// 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.
package p
type T struct {
f [1]int
}
func a() {
_ = T // ERROR "type T is not an expression"
}
func b() {
var v [len(T{}.f)]int // ok
_ = v
}

View file

@ -11,9 +11,7 @@ package main
import "unsafe" import "unsafe"
var x struct { var x struct {
a [unsafe.Sizeof(x.a)]int // ERROR "array bound|typechecking loop|invalid expression" a [unsafe.Sizeof(x.a)]int // ERROR "array bound|typechecking loop|invalid expression"
b [unsafe.Offsetof(x.b)]int // ERROR "array bound" b [unsafe.Offsetof(x.b)]int // ERROR "array bound"
c [unsafe.Alignof(x.c)]int // ERROR "array bound|invalid expression" c [unsafe.Alignof(x.c)]int // ERROR "array bound|invalid expression"
d [len(x.d)]int // ERROR "array bound|invalid array"
e [cap(x.e)]int // ERROR "array bound|invalid array"
} }

View file

@ -0,0 +1,13 @@
// 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 7525: self-referential array types.
package main
var y struct {
d [len(y.d)]int // ERROR "array bound|typechecking loop|invalid array"
}

View file

@ -0,0 +1,13 @@
// 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 7525: self-referential array types.
package main
var z struct {
e [cap(z.e)]int // ERROR "array bound|typechecking loop|invalid array"
}