allow having {.noinit.} on a complex type avoid memsets to 0 for its … (#23388)

…instantiations (C/C++ backend)

AFAIK, #22802 expanded `noinit`'s utility by allowing the pragma to be
attached to types (thanks @jmgomez !).
I suggest broadening the scope a bit further: try to avoid `nimZeroMem`s
on a type level beyond imported C/C++ types[^1], saving us from
annotating the type instantiations with `noinit`.

If this change is deemed acceptable, I will also adjust the docs, of
course.

Adding tests for this change seems a bit problematic, as the effect of
this type annotation will be to work with uninitialized memory, which
*might* match 0 patterns.

[^1]: "complex value types" as already defined here:
94c5996877/compiler/cgen.nim (L470-L471)
This commit is contained in:
heterodoxic
2024-04-18 21:58:01 +02:00
committed by GitHub
parent 558bbb7426
commit 318b2cfc5e
2 changed files with 4 additions and 1 deletions

View File

@@ -245,6 +245,9 @@ proc isImportedCppType(t: PType): bool =
proc isOrHasImportedCppType(typ: PType): bool =
searchTypeFor(typ.skipTypes({tyRef}), isImportedCppType)
proc hasNoInit(t: PType): bool =
result = t.sym != nil and sfNoInit in t.sym.flags
proc getTypeDescAux(m: BModule; origTyp: PType, check: var IntSet; kind: TypeDescKind): Rope
proc isObjLackingTypeField(typ: PType): bool {.inline.} =

View File

@@ -532,7 +532,7 @@ proc constructLoc(p: BProc, loc: var TLoc, isTemp = false) =
linefmt(p, cpsStmts, "$1 = ($2)0;$n", [rdLoc(loc),
getTypeDesc(p.module, typ, descKindFromSymKind mapTypeChooser(loc))])
else:
if not isTemp or containsGarbageCollectedRef(loc.t):
if (not isTemp or containsGarbageCollectedRef(loc.t)) and not hasNoInit(loc.t):
# don't use nimZeroMem for temporary values for performance if we can
# avoid it:
if not isOrHasImportedCppType(typ):