]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix typechecking logical operators panic with non-boolean operand
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 27 Apr 2021 16:01:16 +0000 (23:01 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 28 Apr 2021 00:49:58 +0000 (00:49 +0000)
In CL 255899, we added code to make clearer error when non-bool used
as operand to logical operators. The code is safe, because node type
is guaranteed to be non-nil.

In CL 279442, we refactored typechecking arith, including moving
typechecking logical operators to separate case. Now we have to
explicitly check if operand type is not nil, because calling Expr can
set operand type nil for non-bool operands.

Fixes #45804

Change-Id: Ie2b6e18f65c0614a803b343f60e78ee1d660bbeb
Reviewed-on: https://go-review.googlesource.com/c/go/+/314209
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/typecheck/typecheck.go
test/fixedbugs/issue45804.go [new file with mode: 0644]

index ab493e0caa48dd84940cbe4aa750c9d22399a065..00dd44b96b1a73366c98deefbc7d1f29b3d6bddb 100644 (file)
@@ -596,6 +596,10 @@ func typecheck1(n ir.Node, top int) ir.Node {
        case ir.OANDAND, ir.OOROR:
                n := n.(*ir.LogicalExpr)
                n.X, n.Y = Expr(n.X), Expr(n.Y)
+               if n.X.Type() == nil || n.Y.Type() == nil {
+                       n.SetType(nil)
+                       return n
+               }
                // For "x == x && len(s)", it's better to report that "len(s)" (type int)
                // can't be used with "&&" than to report that "x == x" (type untyped bool)
                // can't be converted to int (see issue #41500).
diff --git a/test/fixedbugs/issue45804.go b/test/fixedbugs/issue45804.go
new file mode 100644 (file)
index 0000000..28d42c8
--- /dev/null
@@ -0,0 +1,19 @@
+// errorcheck
+
+// Copyright 2021 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
+
+func g() int
+func h(int)
+
+var b bool
+
+func f() {
+       did := g()
+       if !did && b { // ERROR "invalid operation"
+               h(x) // ERROR "undefined"
+       }
+}