Skip to content

Commit

Permalink
fixes #12264 [backport]
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq committed Sep 30, 2019
1 parent 86de2cd commit c2eee4e
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 10 deletions.
9 changes: 9 additions & 0 deletions compiler/int128.nim
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ proc toInt64*(arg: Int128): int64 =

cast[int64](bitconcat(arg.udata[1], arg.udata[0]))

proc toInt64Checked*(arg: Int128; onError: int64): int64 =
if isNegative(arg):
if arg.sdata(3) != -1 or arg.sdata(2) != -1:
return onError
else:
if arg.sdata(3) != 0 or arg.sdata(2) != 0:
return onError
return cast[int64](bitconcat(arg.udata[1], arg.udata[0]))

proc toInt32*(arg: Int128): int32 =
if isNegative(arg):
assert(arg.sdata(3) == -1, "out of range")
Expand Down
11 changes: 6 additions & 5 deletions compiler/sizealignoffsetimpl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const
szUnknownSize* = -3
szIllegalRecursion* = -2
szUncomputedSize* = -1
szTooBigSize* = -4

type IllegalTypeRecursionError = object of Exception

Expand All @@ -33,14 +34,14 @@ type
offset: int

proc inc(arg: var OffsetAccum; value: int) =
if unlikely(value == szIllegalRecursion): raiseIllegalTypeRecursion()
if unlikely(value == szIllegalRecursion): raiseIllegalTypeRecursion()
if value == szUnknownSize or arg.offset == szUnknownSize:
arg.offset = szUnknownSize
else:
arg.offset += value

proc alignmentMax(a,b: int): int =
if unlikely(a == szIllegalRecursion or b == szIllegalRecursion): raiseIllegalTypeRecursion()
if unlikely(a == szIllegalRecursion or b == szIllegalRecursion): raiseIllegalTypeRecursion()
if a == szUnknownSize or b == szUnknownSize:
szUnknownSize
else:
Expand All @@ -57,7 +58,7 @@ proc align(arg: var OffsetAccum; value: int) =

proc mergeBranch(arg: var OffsetAccum; value: OffsetAccum) =
if value.maxAlign == szUnknownSize or arg.maxAlign == szUnknownSize or
value.offset == szUnknownSize or arg.offset == szUnknownSize:
value.offset == szUnknownSize or arg.offset == szUnknownSize:
arg.maxAlign = szUnknownSize
arg.offset = szUnknownSize
else:
Expand Down Expand Up @@ -111,7 +112,7 @@ proc setOffsetsToUnknown(n: PNode) =
for i in 0 ..< safeLen(n):
setOffsetsToUnknown(n[i])

proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, packed: bool, accum: var OffsetAccum): void =
proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, packed: bool, accum: var OffsetAccum) =
## ``offset`` is the offset within the object, after the node has been written, no padding bytes added
## ``align`` maximum alignment from all sub nodes
assert n != nil
Expand Down Expand Up @@ -256,7 +257,7 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
typ.size = elemSize
typ.align = int16(elemSize)
else:
typ.size = toInt64(lengthOrd(conf, typ.sons[0]) * int32(elemSize))
typ.size = toInt64Checked(lengthOrd(conf, typ.sons[0]) * int32(elemSize), szTooBigSize)
typ.align = typ.sons[1].align

of tyUncheckedArray:
Expand Down
7 changes: 2 additions & 5 deletions compiler/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -814,11 +814,8 @@ proc floatRangeCheck*(x: BiggestFloat, t: PType): bool =
false

proc lengthOrd*(conf: ConfigRef; t: PType): Int128 =
case t.skipTypes(tyUserTypeClasses).kind
of tyInt64, tyInt32, tyInt:
# XXX: this is just wrong
result = lastOrd(conf, t)
of tyDistinct: result = lengthOrd(conf, t.sons[0])
if t.skipTypes(tyUserTypeClasses).kind == tyDistinct:
result = lengthOrd(conf, t.sons[0])
else:
let last = lastOrd(conf, t)
let first = firstOrd(conf, t)
Expand Down

0 comments on commit c2eee4e

Please sign in to comment.