@@ -681,13 +681,24 @@ func (check *Checker) shift(x, y *operand, op token.Token) {
681
681
// constant is what it would be if the shift expression
682
682
// were replaced by its left operand alone.".
683
683
//
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
+ }
691
702
// keep x's type
692
703
x .mode = value
693
704
return
0 commit comments