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 <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Robert Griesemer 2020-11-18 17:05:02 -08:00
parent 35693d037f
commit 96b943a483
3 changed files with 29 additions and 2 deletions

View file

@ -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
}

View file

@ -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 */ )

View file

@ -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.