From e854e0228e2ef1cc6e42bbfde1951925096a1272 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Thu, 14 Apr 2022 11:55:07 -0700 Subject: [PATCH] go/ssa: fix miscompilation of <<= and >>= statements Unlike other binary operations, the RHS operand of a shift operation does not need to have the same type as the LHS operand. In particular, for "x <<= y" and "x >>= y" statements, coercing y to have the same type as x can lead to miscompilation. Fixes golang/go#52342. Change-Id: I3ff139afa18f5637d527bd4a0b10d6b40ce53ab4 Reviewed-on: https://go-review.googlesource.com/c/tools/+/400394 Run-TryBot: Matthew Dempsky Reviewed-by: Zvonimir Pavlinovic gopls-CI: kokoro TryBot-Result: Gopher Robot Reviewed-by: Tim King --- go/ssa/builder.go | 3 +-- go/ssa/interp/interp_test.go | 2 ++ go/ssa/interp/testdata/fixedbugs/issue52342.go | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 go/ssa/interp/testdata/fixedbugs/issue52342.go diff --git a/go/ssa/builder.go b/go/ssa/builder.go index 45a837617cb..4a3eed97177 100644 --- a/go/ssa/builder.go +++ b/go/ssa/builder.go @@ -1026,8 +1026,7 @@ func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) { // assignOp emits to fn code to perform loc = val. func (b *builder) assignOp(fn *Function, loc lvalue, val Value, op token.Token, pos token.Pos) { - oldv := loc.load(fn) - loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, val, oldv.Type()), loc.typ(), pos)) + loc.store(fn, emitArith(fn, op, loc.load(fn), val, loc.typ(), pos)) } // localValueSpec emits to fn code to define all of the vars in the diff --git a/go/ssa/interp/interp_test.go b/go/ssa/interp/interp_test.go index c78d0d29e0e..91ecb97934e 100644 --- a/go/ssa/interp/interp_test.go +++ b/go/ssa/interp/interp_test.go @@ -124,6 +124,8 @@ var testdataTests = []string{ "reflect.go", "static.go", "width32.go", + + "fixedbugs/issue52342.go", } // Specific GOARCH to use for a test case in go.tools/go/ssa/interp/testdata/. diff --git a/go/ssa/interp/testdata/fixedbugs/issue52342.go b/go/ssa/interp/testdata/fixedbugs/issue52342.go new file mode 100644 index 00000000000..2e1cc63cfe8 --- /dev/null +++ b/go/ssa/interp/testdata/fixedbugs/issue52342.go @@ -0,0 +1,17 @@ +package main + +func main() { + var d byte + + d = 1 + d <<= 256 + if d != 0 { + panic(d) + } + + d = 1 + d >>= 256 + if d != 0 { + panic(d) + } +}