From 23573d0ea225d4b93ccd2b946b1de121c3a6cee5 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Mon, 21 Sep 2020 12:00:24 +0700 Subject: [PATCH] cmd/compile: clearer error when non-bool used as "||" and "&&" operand Fixes #41500 Change-Id: I658d8921b7769b6e4288ca781cbdca5ff14a84ee Reviewed-on: https://go-review.googlesource.com/c/go/+/255899 Trust: Cuong Manh Le Run-TryBot: Cuong Manh Le TryBot-Result: Go Bot Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/gc/typecheck.go | 16 ++++++++++++++++ test/fixedbugs/issue41500.go | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/fixedbugs/issue41500.go diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index 12c99bf48f..2c445567de 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -630,6 +630,22 @@ func typecheck1(n *Node, top int) (res *Node) { break } + // 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). + if n.Op == OANDAND || n.Op == OOROR { + if !n.Left.Type.IsBoolean() { + yyerror("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(n.Left.Type)) + n.Type = nil + return n + } + if !n.Right.Type.IsBoolean() { + yyerror("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(n.Right.Type)) + n.Type = nil + return n + } + } + // ideal mixed with non-ideal l, r = defaultlit2(l, r, false) diff --git a/test/fixedbugs/issue41500.go b/test/fixedbugs/issue41500.go new file mode 100644 index 0000000000..d1e4efc8fd --- /dev/null +++ b/test/fixedbugs/issue41500.go @@ -0,0 +1,20 @@ +// errorcheck + +// Copyright 2020 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 s struct { + slice []int +} + +func f() { + var x *s + + _ = x == nil || len(x.slice) // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)" + _ = len(x.slice) || x == nil // ERROR "invalid operation: .+ \(operator \|\| not defined on int\)" + _ = x == nil && len(x.slice) // ERROR "invalid operation: .+ \(operator && not defined on int\)" + _ = len(x.slice) && x == nil // ERROR "invalid operation: .+ \(operator && not defined on int\)" +} -- 2.50.0