summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorheterodoxic <122719743+heterodoxic@users.noreply.github.com>2023-03-27 17:20:20 +0200
committerGitHub <noreply@github.com>2023-03-27 17:20:20 +0200
commit7d83dfd0d1a416cdf36a23b61c87a1ad2c234909 (patch)
tree0cca200920b3e9c0639bf8de1dad293de804983b /compiler
parent3936071772d648f98c36e5aad16a341b86344e6c (diff)
downloadNim-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.nim8
-rw-r--r--compiler/cgen.nim21
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: