diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-06-29 16:51:18 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-29 10:51:18 +0200 |
commit | d139d99946c97dca9c864709726841855a089496 (patch) | |
tree | a305b0bcaa18e365bfe2bfb059cd7c69a40dba2f | |
parent | 57de460437924a951d393ced8b7c88418fe2541a (diff) | |
download | Nim-d139d99946c97dca9c864709726841855a089496.tar.gz |
fixes #19101; zero initialization union casts (#22185)
* zero initialization union casts * cleans up and adds a test case for #19101 * uses nimZeroMem
-rw-r--r-- | compiler/ccgexprs.nim | 11 | ||||
-rw-r--r-- | compiler/condsyms.nim | 2 | ||||
-rw-r--r-- | compiler/lineinfos.nim | 4 | ||||
-rw-r--r-- | compiler/nim.cfg | 3 | ||||
-rw-r--r-- | compiler/semexprs.nim | 5 | ||||
-rw-r--r-- | tests/stdlib/tcasts.nim | 26 |
6 files changed, 38 insertions, 13 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 978ca8db8..e2498b57b 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2205,8 +2205,15 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) = var lbl = p.labels.rope var tmp: TLoc tmp.r = "LOC$1.source" % [lbl] - linefmt(p, cpsLocals, "union { $1 source; $2 dest; } LOC$3;$n", - [getTypeDesc(p.module, e[1].typ), getTypeDesc(p.module, e.typ), lbl]) + let destsize = getSize(p.config, destt) + let srcsize = getSize(p.config, srct) + + if destsize > srcsize: + linefmt(p, cpsLocals, "union { $1 dest; $2 source; } LOC$3;$n #nimZeroMem(&LOC$3, sizeof(LOC$3));$n", + [getTypeDesc(p.module, e.typ), getTypeDesc(p.module, e[1].typ), lbl]) + else: + linefmt(p, cpsLocals, "union { $1 source; $2 dest; } LOC$3;$n", + [getTypeDesc(p.module, e[1].typ), getTypeDesc(p.module, e.typ), lbl]) tmp.k = locExpr tmp.lode = lodeTyp srct tmp.storage = OnStack diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 4ff588852..12634248c 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -145,7 +145,7 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimHasCallsitePragma") defineSymbol("nimHasAmbiguousEnumHint") - defineSymbol("nimHasWarnCastSizes") + defineSymbol("nimHasWarnCastSizes") # deadcode defineSymbol("nimHasOutParams") defineSymbol("nimHasSystemRaisesDefect") defineSymbol("nimHasWarnUnnamedBreak") diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index 7c5a99c79..37adc5660 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -83,7 +83,7 @@ type warnCstringConv = "CStringConv", warnPtrToCstringConv = "PtrToCstringConv", warnEffect = "Effect", - warnCastSizes = "CastSizes" + warnCastSizes = "CastSizes", # deadcode warnAboveMaxSizeSet = "AboveMaxSizeSet", warnImplicitTemplateRedefinition = "ImplicitTemplateRedefinition", warnUnnamedBreak = "UnnamedBreak", @@ -185,7 +185,7 @@ const warnCstringConv: "$1", warnPtrToCstringConv: "unsafe conversion to 'cstring' from '$1'; this will become a compile time error in the future", warnEffect: "$1", - warnCastSizes: "$1", + warnCastSizes: "$1", # deadcode warnAboveMaxSizeSet: "$1", warnImplicitTemplateRedefinition: "template '$1' is implicitly redefined; this is deprecated, add an explicit .redefine pragma", warnUnnamedBreak: "Using an unnamed break in a block is deprecated; Use a named block with a named break instead", diff --git a/compiler/nim.cfg b/compiler/nim.cfg index 5b418cfd3..c32dba4d1 100644 --- a/compiler/nim.cfg +++ b/compiler/nim.cfg @@ -31,9 +31,6 @@ define:useStdoutAsStdmsg warning[ObservableStores]:off @end -@if nimHasWarnCastSizes: - warning[CastSizes]:on -@end @if nimHasWarningAsError: warningAsError[GcUnsafe2]:on diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 3b40425cf..1d917f00d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -288,11 +288,6 @@ proc isCastable(c: PContext; dst, src: PType, info: TLineInfo): bool = result = (dstSize >= srcSize) or (skipTypes(dst, abstractInst).kind in IntegralTypes) or (skipTypes(src, abstractInst-{tyTypeDesc}).kind in IntegralTypes) - if result and (dstSize > srcSize): - var warnMsg = "target type is larger than source type" - warnMsg.add("\n target type: '$1' ($2)" % [$dst, if dstSize == 1: "1 byte" else: $dstSize & " bytes"]) - warnMsg.add("\n source type: '$1' ($2)" % [$src, if srcSize == 1: "1 byte" else: $srcSize & " bytes"]) - message(conf, info, warnCastSizes, warnMsg) if result and src.kind == tyNil: return dst.size <= conf.target.ptrSize diff --git a/tests/stdlib/tcasts.nim b/tests/stdlib/tcasts.nim new file mode 100644 index 000000000..e01c7e940 --- /dev/null +++ b/tests/stdlib/tcasts.nim @@ -0,0 +1,26 @@ +import std/[strutils] +import std/[assertions, objectdollar] + +# bug #19101 +type + Small = object + a: int + + Big = object + a, b, c, d: int + +proc main = + var + n = 1'i8 + f = 2.0 + s = Small(a: 1) + b = Big(a: 12345, b: 23456, c: 34567, d: 45678) + + doAssert $cast[int](f).toBin(64) == "0100000000000000000000000000000000000000000000000000000000000000" + f = cast[float](n) + doAssert $cast[int](f).toBin(64) == "0000000000000000000000000000000000000000000000000000000000000001" + + doAssert $b == "(a: 12345, b: 23456, c: 34567, d: 45678)" + b = cast[Big](s) + doAssert $b == "(a: 1, b: 0, c: 0, d: 0)" +main() |