From 7ec0ec3645a481155728020c07685992444a9e4f Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 15 Aug 2022 15:37:22 -0700 Subject: [PATCH] go/types, types2: skip comparison for operands with invalid types Fixes #54405. Change-Id: Ia7b2709b83966fa080e41e3d4818527d1e8b49f9 Reviewed-on: https://go-review.googlesource.com/c/go/+/424054 TryBot-Result: Gopher Robot Reviewed-by: Cuong Manh Le Reviewed-by: Robert Griesemer Run-TryBot: Robert Griesemer Reviewed-by: Robert Findley Auto-Submit: Robert Griesemer --- src/cmd/compile/internal/types2/expr.go | 6 ++++++ .../types2/testdata/fixedbugs/issue54405.go | 16 ++++++++++++++++ src/go/types/expr.go | 6 ++++++ src/go/types/testdata/fixedbugs/issue54405.go | 16 ++++++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 src/cmd/compile/internal/types2/testdata/fixedbugs/issue54405.go create mode 100644 src/go/types/testdata/fixedbugs/issue54405.go diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go index b11cd1e9d8..ee0792e61c 100644 --- a/src/cmd/compile/internal/types2/expr.go +++ b/src/cmd/compile/internal/types2/expr.go @@ -783,6 +783,12 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const // If switchCase is true, the operator op is ignored. func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase bool) { + // Avoid spurious errors if any of the operands has an invalid type (issue #54405). + if x.typ == Typ[Invalid] || y.typ == Typ[Invalid] { + x.mode = invalid + return + } + if switchCase { op = syntax.Eql } diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue54405.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue54405.go new file mode 100644 index 0000000000..e89d5e1b80 --- /dev/null +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue54405.go @@ -0,0 +1,16 @@ +// Copyright 2022 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. + +// Test that we don't see spurious errors for == +// for values with invalid types due to prior errors. + +package p + +var x struct { + f *NotAType /* ERROR undeclared name */ +} +var _ = x.f == nil // no error expected here + +var y *NotAType /* ERROR undeclared name */ +var _ = y == nil // no error expected here diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 0e8dca3247..4b60123499 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -736,6 +736,12 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const // If switchCase is true, the operator op is ignored. func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool) { + // Avoid spurious errors if any of the operands has an invalid type (issue #54405). + if x.typ == Typ[Invalid] || y.typ == Typ[Invalid] { + x.mode = invalid + return + } + if switchCase { op = token.EQL } diff --git a/src/go/types/testdata/fixedbugs/issue54405.go b/src/go/types/testdata/fixedbugs/issue54405.go new file mode 100644 index 0000000000..e89d5e1b80 --- /dev/null +++ b/src/go/types/testdata/fixedbugs/issue54405.go @@ -0,0 +1,16 @@ +// Copyright 2022 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. + +// Test that we don't see spurious errors for == +// for values with invalid types due to prior errors. + +package p + +var x struct { + f *NotAType /* ERROR undeclared name */ +} +var _ = x.f == nil // no error expected here + +var y *NotAType /* ERROR undeclared name */ +var _ = y == nil // no error expected here