Skip to content

Commit 80eca3a

Browse files
committed
go/types: don't crash for erroneous program involving a shift in a declaration cycle
R=1.6 Fixes #11347. Change-Id: Ic6b09f38682500ffcc8d1f96e58f7237a7528806 Reviewed-on: https://go-review.googlesource.com/12812 Reviewed-by: Alan Donovan <[email protected]>
1 parent f1b5bb9 commit 80eca3a

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

src/go/types/expr.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -681,13 +681,24 @@ func (check *Checker) shift(x, y *operand, op token.Token) {
681681
// constant is what it would be if the shift expression
682682
// were replaced by its left operand alone.".
683683
//
684-
// Delay operand checking until we know the final type:
685-
// The lhs expression must be in the untyped map, mark
686-
// the entry as lhs shift operand.
687-
info, found := check.untyped[x.expr]
688-
assert(found)
689-
info.isLhs = true
690-
check.untyped[x.expr] = info
684+
// Delay operand checking until we know the final type
685+
// by marking the lhs expression as lhs shift operand.
686+
//
687+
// Usually (in correct programs), the lhs expression
688+
// is in the untyped map. However, it is possible to
689+
// create incorrect programs where the same expression
690+
// is evaluated twice (via a declaration cycle) such
691+
// that the lhs expression type is determined in the
692+
// first round and thus deleted from the map, and then
693+
// not found in the second round (double insertion of
694+
// the same expr node still just leads to one entry for
695+
// that node, and it can only be deleted once).
696+
// Be cautious and check for presence of entry.
697+
// Example: var e, f = int(1<<""[f]) // issue 11347
698+
if info, found := check.untyped[x.expr]; found {
699+
info.isLhs = true
700+
check.untyped[x.expr] = info
701+
}
691702
// keep x's type
692703
x.mode = value
693704
return

src/go/types/testdata/issues.src

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,9 @@ func issue10979() {
9595
m()
9696
}
9797
}
98+
99+
// issue11347
100+
// These should not crash.
101+
var a1, b1 /* ERROR cycle */ , c1 /* ERROR cycle */ b1 = 0 > 0<<""[""[c1]]>c1
102+
var a2, b2 /* ERROR cycle */ = 0 /* ERROR mismatch */ /* ERROR mismatch */ > 0<<""[b2]
103+
var a3, b3 /* ERROR cycle */ = int /* ERROR mismatch */ /* ERROR mismatch */ (1<<""[b3])

0 commit comments

Comments
 (0)