tyInt tyUint fit target int bit width (#20829)
This commit is contained in:
parent
a70d3abd37
commit
658b28dc57
17 changed files with 306 additions and 267 deletions
|
|
@ -373,14 +373,16 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
|
|||
else:
|
||||
result = t # Note: empty is valid here
|
||||
|
||||
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||
proc handleRange(c: PContext, f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||
if a.kind == f.kind:
|
||||
result = isEqual
|
||||
else:
|
||||
let ab = skipTypes(a, {tyRange})
|
||||
let k = ab.kind
|
||||
let nf = c.config.normalizeKind(f.kind)
|
||||
let na = c.config.normalizeKind(k)
|
||||
if k == f.kind: result = isSubrange
|
||||
elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64,
|
||||
elif k == tyInt and f.kind in {tyRange, tyInt..tyInt64,
|
||||
tyUInt..tyUInt64} and
|
||||
isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and
|
||||
getInt(ab.n) <= lastOrd(nil, f):
|
||||
|
|
@ -389,9 +391,13 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
|||
# integer literal in the proper range; we want ``i16 + 4`` to stay an
|
||||
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16
|
||||
result = isFromIntLit
|
||||
elif f.kind == tyInt and k in {tyInt8..tyInt32}:
|
||||
elif a.kind == tyInt and nf == c.config.targetSizeSignedToKind:
|
||||
result = isIntConv
|
||||
elif f.kind == tyUInt and k in {tyUInt8..tyUInt32}:
|
||||
elif a.kind == tyUInt and nf == c.config.targetSizeUnsignedToKind:
|
||||
result = isIntConv
|
||||
elif f.kind == tyInt and na in {tyInt8 .. c.config.targetSizeSignedToKind}:
|
||||
result = isIntConv
|
||||
elif f.kind == tyUInt and na in {tyUInt8 .. c.config.targetSizeUnsignedToKind}:
|
||||
result = isIntConv
|
||||
elif k >= min and k <= max:
|
||||
result = isConvertible
|
||||
|
|
@ -405,7 +411,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
|||
result = isConvertible
|
||||
else: result = isNone
|
||||
|
||||
proc isConvertibleToRange(f, a: PType): bool =
|
||||
proc isConvertibleToRange(c: PContext, f, a: PType): bool =
|
||||
if f.kind in {tyInt..tyInt64, tyUInt..tyUInt64} and
|
||||
a.kind in {tyInt..tyInt64, tyUInt..tyUInt64}:
|
||||
case f.kind
|
||||
|
|
@ -413,13 +419,14 @@ proc isConvertibleToRange(f, a: PType): bool =
|
|||
of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
|
||||
of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
|
||||
# This is wrong, but seems like there's a lot of code that relies on it :(
|
||||
of tyInt, tyUInt, tyUInt64: result = true
|
||||
of tyInt, tyUInt: result = true
|
||||
# of tyInt: result = isIntLit(a) or a.kind in {tyInt8 .. c.config.targetSizeSignedToKind}
|
||||
of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
|
||||
of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
|
||||
of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
|
||||
of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
|
||||
#of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
|
||||
#of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64}
|
||||
# of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8 .. c.config.targetSizeUnsignedToKind}
|
||||
of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt64}
|
||||
else: result = false
|
||||
elif f.kind in {tyFloat..tyFloat128}:
|
||||
# `isIntLit` is correct and should be used above as well, see PR:
|
||||
|
|
@ -1148,18 +1155,18 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
|||
let f = skipTypes(f, {tyRange})
|
||||
if f.kind == a.kind and (f.kind != tyEnum or sameEnumTypes(f, a)):
|
||||
result = isIntConv
|
||||
elif isConvertibleToRange(f, a):
|
||||
elif isConvertibleToRange(c.c, f, a):
|
||||
result = isConvertible # a convertible to f
|
||||
of tyInt: result = handleRange(f, a, tyInt8, tyInt32)
|
||||
of tyInt8: result = handleRange(f, a, tyInt8, tyInt8)
|
||||
of tyInt16: result = handleRange(f, a, tyInt8, tyInt16)
|
||||
of tyInt32: result = handleRange(f, a, tyInt8, tyInt32)
|
||||
of tyInt64: result = handleRange(f, a, tyInt, tyInt64)
|
||||
of tyUInt: result = handleRange(f, a, tyUInt8, tyUInt32)
|
||||
of tyUInt8: result = handleRange(f, a, tyUInt8, tyUInt8)
|
||||
of tyUInt16: result = handleRange(f, a, tyUInt8, tyUInt16)
|
||||
of tyUInt32: result = handleRange(f, a, tyUInt8, tyUInt32)
|
||||
of tyUInt64: result = handleRange(f, a, tyUInt, tyUInt64)
|
||||
of tyInt: result = handleRange(c.c, f, a, tyInt8, c.c.config.targetSizeSignedToKind)
|
||||
of tyInt8: result = handleRange(c.c, f, a, tyInt8, tyInt8)
|
||||
of tyInt16: result = handleRange(c.c, f, a, tyInt8, tyInt16)
|
||||
of tyInt32: result = handleRange(c.c, f, a, tyInt8, tyInt32)
|
||||
of tyInt64: result = handleRange(c.c, f, a, tyInt, tyInt64)
|
||||
of tyUInt: result = handleRange(c.c, f, a, tyUInt8, c.c.config.targetSizeUnsignedToKind)
|
||||
of tyUInt8: result = handleRange(c.c, f, a, tyUInt8, tyUInt8)
|
||||
of tyUInt16: result = handleRange(c.c, f, a, tyUInt8, tyUInt16)
|
||||
of tyUInt32: result = handleRange(c.c, f, a, tyUInt8, tyUInt32)
|
||||
of tyUInt64: result = handleRange(c.c, f, a, tyUInt, tyUInt64)
|
||||
of tyFloat: result = handleFloatRange(f, a)
|
||||
of tyFloat32: result = handleFloatRange(f, a)
|
||||
of tyFloat64: result = handleFloatRange(f, a)
|
||||
|
|
@ -2114,6 +2121,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
|
|||
of isIntConv:
|
||||
# I'm too lazy to introduce another ``*matches`` field, so we conflate
|
||||
# ``isIntConv`` and ``isIntLit`` here:
|
||||
if f.skipTypes({tyRange}).kind notin {tyInt, tyUInt}:
|
||||
inc(m.intConvMatches)
|
||||
inc(m.intConvMatches)
|
||||
result = implicitConv(nkHiddenStdConv, f, arg, m, c)
|
||||
of isSubtype:
|
||||
|
|
|
|||
|
|
@ -753,8 +753,13 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 =
|
|||
assert(t.n.kind == nkRange)
|
||||
result = getOrdValue(t.n[0])
|
||||
of tyInt:
|
||||
if conf != nil and conf.target.intSize == 4:
|
||||
result = toInt128(-2147483648)
|
||||
if conf != nil:
|
||||
case conf.target.intSize
|
||||
of 8: result = toInt128(0x8000000000000000'i64)
|
||||
of 4: result = toInt128(-2147483648)
|
||||
of 2: result = toInt128(-32768)
|
||||
of 1: result = toInt128(-128)
|
||||
else: discard
|
||||
else:
|
||||
result = toInt128(0x8000000000000000'i64)
|
||||
of tyInt8: result = toInt128(-128)
|
||||
|
|
@ -797,6 +802,29 @@ proc firstFloat*(t: PType): BiggestFloat =
|
|||
internalError(newPartialConfigRef(), "invalid kind for firstFloat(" & $t.kind & ')')
|
||||
NaN
|
||||
|
||||
proc targetSizeSignedToKind*(conf: ConfigRef): TTypeKind =
|
||||
case conf.target.intSize
|
||||
of 8: result = tyInt64
|
||||
of 4: result = tyInt32
|
||||
of 2: result = tyInt16
|
||||
else: discard
|
||||
|
||||
proc targetSizeUnsignedToKind*(conf: ConfigRef): TTypeKind =
|
||||
case conf.target.intSize
|
||||
of 8: result = tyUInt64
|
||||
of 4: result = tyUInt32
|
||||
of 2: result = tyUInt16
|
||||
else: discard
|
||||
|
||||
proc normalizeKind*(conf: ConfigRef, k: TTypeKind): TTypeKind =
|
||||
case k
|
||||
of tyInt:
|
||||
result = conf.targetSizeSignedToKind()
|
||||
of tyUInt:
|
||||
result = conf.targetSizeUnsignedToKind()
|
||||
else:
|
||||
result = k
|
||||
|
||||
proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
|
||||
case t.kind
|
||||
of tyBool: result = toInt128(1'u)
|
||||
|
|
@ -808,7 +836,13 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
|
|||
assert(t.n.kind == nkRange)
|
||||
result = getOrdValue(t.n[1])
|
||||
of tyInt:
|
||||
if conf != nil and conf.target.intSize == 4: result = toInt128(0x7FFFFFFF)
|
||||
if conf != nil:
|
||||
case conf.target.intSize
|
||||
of 8: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
|
||||
of 4: result = toInt128(0x7FFFFFFF)
|
||||
of 2: result = toInt128(0x00007FFF)
|
||||
of 1: result = toInt128(0x0000007F)
|
||||
else: discard
|
||||
else: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
|
||||
of tyInt8: result = toInt128(0x0000007F)
|
||||
of tyInt16: result = toInt128(0x00007FFF)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue