From 96b943a483dca715ea0164644e1192052105881a Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 18 Nov 2020 17:05:02 -0800 Subject: [PATCH] go/types: report an error for invalid constant values The parser reports syntactic errors in constant literals. The go/constant package produces an "unknown" value for syntactically correct numeric constants that are too small or too large. Check for the unknown value and report an error rather than silently continuing. Fixes #42695. Change-Id: I414214559a285d67ed50184dc750f106960b5620 Reviewed-on: https://go-review.googlesource.com/c/go/+/271377 Trust: Robert Griesemer Run-TryBot: Robert Griesemer Reviewed-by: Matthew Dempsky TryBot-Result: Go Bot --- src/go/types/expr.go | 6 +++++- src/go/types/fixedbugs/issue42695.src | 17 +++++++++++++++++ src/go/types/operand.go | 8 +++++++- 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/go/types/fixedbugs/issue42695.src diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 11f94112846..b026e99ce28 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -1073,7 +1073,11 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { case *ast.BasicLit: x.setConst(e.Kind, e.Value) if x.mode == invalid { - check.invalidAST(e, "invalid literal %v", e.Value) + // The parser already establishes syntactic correctness. + // If we reach here it's because of number under-/overflow. + // TODO(gri) setConst (and in turn the go/constant package) + // should return an error describing the issue. + check.errorf(e, _InvalidConstVal, "malformed constant: %s", e.Value) goto Error } diff --git a/src/go/types/fixedbugs/issue42695.src b/src/go/types/fixedbugs/issue42695.src new file mode 100644 index 00000000000..d0d62009696 --- /dev/null +++ b/src/go/types/fixedbugs/issue42695.src @@ -0,0 +1,17 @@ +// 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 issue42695 + +const _ = 6e5518446744 // ERROR malformed constant +const _ uint8 = 6e5518446744 // ERROR malformed constant + +var _ = 6e5518446744 // ERROR malformed constant +var _ uint8 = 6e5518446744 // ERROR malformed constant + +func f(x int) int { + return x + 6e5518446744 // ERROR malformed constant +} + +var _ = f(6e5518446744 /* ERROR malformed constant */ ) diff --git a/src/go/types/operand.go b/src/go/types/operand.go index 2d30dbd024c..3e1ac312d9a 100644 --- a/src/go/types/operand.go +++ b/src/go/types/operand.go @@ -195,9 +195,15 @@ func (x *operand) setConst(tok token.Token, lit string) { unreachable() } + val := constant.MakeFromLiteral(lit, tok, 0) + if val.Kind() == constant.Unknown { + x.mode = invalid + x.typ = Typ[Invalid] + return + } x.mode = constant_ x.typ = Typ[kind] - x.val = constant.MakeFromLiteral(lit, tok, 0) + x.val = val } // isNil reports whether x is the nil value.