package types
import (
.
)
func ( *Checker) ( *operand, token.Pos) {
assert(.mode == constant_)
if .val.Kind() == constant.Unknown {
.error(atPos(), InvalidConstVal, "constant result is not representable")
return
}
if isTyped(.typ) {
.representable(, under(.typ).(*Basic))
return
}
const = 512
if .val.Kind() == constant.Int && constant.BitLen(.val) > {
:= opName(.expr)
if != "" {
+= " "
}
.errorf(atPos(), InvalidConstVal, "constant %soverflow", )
.val = constant.MakeUnknown()
}
}
func ( constant.Value, *Checker, *Basic, *constant.Value) bool {
if .Kind() == constant.Unknown {
return true
}
var *Config
if != nil {
= .conf
}
:= func( Type) int64 {
:= .sizeof()
return
}
switch {
case isInteger():
:= constant.ToInt()
if .Kind() != constant.Int {
return false
}
if != nil {
* =
}
if , := constant.Int64Val(); {
switch .kind {
case Int:
var = uint(()) * 8
return int64(-1)<<(-1) <= && <= int64(1)<<(-1)-1
case Int8:
const = 8
return -1<<(-1) <= && <= 1<<(-1)-1
case Int16:
const = 16
return -1<<(-1) <= && <= 1<<(-1)-1
case Int32:
const = 32
return -1<<(-1) <= && <= 1<<(-1)-1
case Int64, UntypedInt:
return true
case Uint, Uintptr:
if := uint(()) * 8; < 64 {
return 0 <= && <= int64(1)<<-1
}
return 0 <=
case Uint8:
const = 8
return 0 <= && <= 1<<-1
case Uint16:
const = 16
return 0 <= && <= 1<<-1
case Uint32:
const = 32
return 0 <= && <= 1<<-1
case Uint64:
return 0 <=
default:
panic("unreachable")
}
}
switch := constant.BitLen(); .kind {
case Uint, Uintptr:
var = uint(()) * 8
return constant.Sign() >= 0 && <= int()
case Uint64:
return constant.Sign() >= 0 && <= 64
case UntypedInt:
return true
}
case isFloat():
:= constant.ToFloat()
if .Kind() != constant.Float {
return false
}
switch .kind {
case Float32:
if == nil {
return fitsFloat32()
}
:= roundFloat32()
if != nil {
* =
return true
}
case Float64:
if == nil {
return fitsFloat64()
}
:= roundFloat64()
if != nil {
* =
return true
}
case UntypedFloat:
return true
default:
panic("unreachable")
}
case isComplex():
:= constant.ToComplex()
if .Kind() != constant.Complex {
return false
}
switch .kind {
case Complex64:
if == nil {
return fitsFloat32(constant.Real()) && fitsFloat32(constant.Imag())
}
:= roundFloat32(constant.Real())
:= roundFloat32(constant.Imag())
if != nil && != nil {
* = constant.BinaryOp(, token.ADD, constant.MakeImag())
return true
}
case Complex128:
if == nil {
return fitsFloat64(constant.Real()) && fitsFloat64(constant.Imag())
}
:= roundFloat64(constant.Real())
:= roundFloat64(constant.Imag())
if != nil && != nil {
* = constant.BinaryOp(, token.ADD, constant.MakeImag())
return true
}
case UntypedComplex:
return true
default:
panic("unreachable")
}
case isString():
return .Kind() == constant.String
case isBoolean():
return .Kind() == constant.Bool
}
return false
}
func ( constant.Value) bool {
, := constant.Float32Val()
:= float64()
return !math.IsInf(, 0)
}
func ( constant.Value) constant.Value {
, := constant.Float32Val()
:= float64()
if !math.IsInf(, 0) {
return constant.MakeFloat64()
}
return nil
}
func ( constant.Value) bool {
, := constant.Float64Val()
return !math.IsInf(, 0)
}
func ( constant.Value) constant.Value {
, := constant.Float64Val()
if !math.IsInf(, 0) {
return constant.MakeFloat64()
}
return nil
}
func ( *Checker) ( *operand, *Basic) {
, := .representation(, )
if != 0 {
.invalidConversion(, , )
.mode = invalid
return
}
assert( != nil)
.val =
}
func ( *Checker) ( *operand, *Basic) (constant.Value, Code) {
assert(.mode == constant_)
:= .val
if !representableConst(.val, , , &) {
if isNumeric(.typ) && isNumeric() {
if !isInteger(.typ) && isInteger() {
return nil, TruncatedFloat
} else {
return nil, NumericOverflow
}
}
return nil, InvalidConstVal
}
return , 0
}
func ( *Checker) ( Code, *operand, Type) {
:= "cannot convert %s to type %s"
switch {
case TruncatedFloat:
= "%s truncated to %s"
case NumericOverflow:
= "%s overflows %s"
}
.errorf(, , , , )
}
func ( *Checker) ( *operand, Type) {
, , := .implicitTypeAndValue(, )
if != 0 {
:=
if !isTypeParam() {
= safeUnderlying()
}
.invalidConversion(, , )
.mode = invalid
return
}
if != nil {
.val =
.updateExprVal(.expr, )
}
if != .typ {
.typ =
.updateExprType(.expr, , false)
}
}