diff options
author | heterodoxic <122719743+heterodoxic@users.noreply.github.com> | 2023-03-27 17:20:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-27 17:20:20 +0200 |
commit | 7d83dfd0d1a416cdf36a23b61c87a1ad2c234909 (patch) | |
tree | 0cca200920b3e9c0639bf8de1dad293de804983b /compiler | |
parent | 3936071772d648f98c36e5aad16a341b86344e6c (diff) | |
download | Nim-7d83dfd0d1a416cdf36a23b61c87a1ad2c234909.tar.gz |
fixes #21505 (overload resolution of explicit constructors for imported C++ types) (#21511)
hacky attempt to reconcile default explicit constructors with enforcement of brace initialization, instead of memsetting imported objects to 0
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgtypes.nim | 8 | ||||
-rw-r--r-- | compiler/cgen.nim | 21 |
2 files changed, 24 insertions, 5 deletions
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 98c1fc55f..6cc009bb9 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -200,6 +200,9 @@ proc isImportedCppType(t: PType): bool = result = (t.sym != nil and sfInfixCall in t.sym.flags) or (x.sym != nil and sfInfixCall in x.sym.flags) +proc isOrHasImportedCppType(typ: PType): bool = + searchTypeFor(typ.skipTypes({tyRef}), isImportedCppType) + proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKind): Rope proc isObjLackingTypeField(typ: PType): bool {.inline.} = @@ -553,7 +556,10 @@ proc genRecordFieldsAux(m: BModule, n: PNode, else: # don't use fieldType here because we need the # tyGenericInst for C++ template support - result.addf("$1$3 $2;$n", [getTypeDescAux(m, field.loc.t, check, skField), sname, noAlias]) + if fieldType.isOrHasImportedCppType(): + result.addf("$1$3 $2{};$n", [getTypeDescAux(m, field.loc.t, check, skField), sname, noAlias]) + else: + result.addf("$1$3 $2;$n", [getTypeDescAux(m, field.loc.t, check, skField), sname, noAlias]) else: internalError(m.config, n.info, "genRecordFieldsAux()") proc getRecordFields(m: BModule, typ: PType, check: var IntSet): Rope = diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 5ba68580d..cc673d082 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -487,9 +487,6 @@ proc resetLoc(p: BProc, loc: var TLoc) = # on the bytes following the m_type field? genObjectInit(p, cpsStmts, loc.t, loc, constructObj) -proc isOrHasImportedCppType(typ: PType): bool = - searchTypeFor(typ.skipTypes({tyRef}), isImportedCppType) - proc constructLoc(p: BProc, loc: var TLoc, isTemp = false) = let typ = loc.t if optSeqDestructors in p.config.globalOptions and skipTypes(typ, abstractInst + {tyStatic}).kind in {tyString, tySequence}: @@ -644,7 +641,23 @@ proc assignGlobalVar(p: BProc, n: PNode; value: Rope) = if sfVolatile in s.flags: decl.add(" volatile") if sfNoalias in s.flags: decl.add(" NIM_NOALIAS") if value != "": - decl.addf(" $1 = $2;$n", [s.loc.r, value]) + if p.module.compileToCpp and value.startsWith "{{}": + # TODO: taking this branch, re"\{\{\}(,\s\{\})*\}" might be emitted, resulting in + # either warnings (GCC 12.2+) or errors (Clang 15, MSVC 19.3+) of C++11+ compilers **when + # explicit constructors are around** due to overload resolution rules in place [^0][^1][^2] + # *Workaround* here: have C++'s static initialization mechanism do the default init work, + # for us lacking a deeper knowledge of an imported object's constructors' ex-/implicitness + # (so far) *and yet* trying to achieve default initialization. + # Still, generating {}s in genConstObjConstr() just to omit them here is faaaar from ideal; + # need to figure out a better way, possibly by keeping around more data about the + # imported objects' contructors? + # + # [^0]: https://en.cppreference.com/w/cpp/language/aggregate_initialization + # [^1]: https://cplusplus.github.io/CWG/issues/1518.html + # [^2]: https://eel.is/c++draft/over.match.ctor + decl.addf(" $1;$n", [s.loc.r]) + else: + decl.addf(" $1 = $2;$n", [s.loc.r, value]) else: decl.addf(" $1;$n", [s.loc.r]) else: |