diff --git a/CodeGenerator.cpp b/CodeGenerator.cpp index ef5b9e9c..b2e081c1 100644 --- a/CodeGenerator.cpp +++ b/CodeGenerator.cpp @@ -1386,13 +1386,24 @@ void CodeGenerator::InsertArg(const VarDecl* stmt) // if(not ctorExpr->getConstructor()->isTrivial()) { if(stmt->hasGlobalStorage()) { - // push to __cxx_global_var_init - auto* callExpr = CallConstructor( - stmt->getType(), stmt, ArgsToExprVector(ctorExpr), DoCast::No, AsReference::Yes); + if(ctorExpr->getConstructor()->isDefaultConstructor() and + ctorExpr->getConstructor()->getParent()->hasTrivialDefaultConstructor()) { - PushGlobalVariable(callExpr); + auto* callMemset = Call("memset"sv, {Ref(stmt), Int32(0), Sizeof(stmt->getType())}); - PushGlobalVariableDtor(CallDestructor(stmt)); + EnableGlobalInsert(GlobalInserts::FuncMemset); + PushGlobalVariable(callMemset); + + } else { + + // push to __cxx_global_var_init + auto* callExpr = CallConstructor( + stmt->getType(), stmt, ArgsToExprVector(ctorExpr), DoCast::No, AsReference::Yes); + + PushGlobalVariable(callExpr); + + PushGlobalVariableDtor(CallDestructor(stmt)); + } } else { mOutputFormatHelper.AppendSemiNewLine(); @@ -1456,6 +1467,11 @@ void CodeGenerator::InsertArg(const VarDecl* stmt) } } } + } else if(GetInsightsOptions().UseShow2C and stmt->hasGlobalStorage() and + (stmt->getStorageDuration() == SD_Static) and + (stmt->getDeclContext()->isNamespace() or + (is{stmt->getStorageClass()}.any_of(SC_Static, SC_Extern)))) { + PushGlobalVariable(Assign(stmt, Int32(0))); } if(stmt->isNRVOVariable()) { diff --git a/tests/Issue607.cpp b/tests/Issue607.cpp new file mode 100644 index 00000000..ad7f63bc --- /dev/null +++ b/tests/Issue607.cpp @@ -0,0 +1,27 @@ +// cmdlineinsights:-edu-show-cfront +namespace X +{ + int initInNamespace; +} + +extern int initDueToExtern; + +int unInitGlobal; +int initGlobalWitValue = 3; + +static int initGlobalStatic; + +struct A{}; + +A initGlobalCtor; + +namespace +{ + int initInAnonNamespace; + A initCtorInAnonNamespace; +} + +int main() +{ + ++X::initInNamespace; +} diff --git a/tests/Issue607.expect b/tests/Issue607.expect new file mode 100644 index 00000000..995d314b --- /dev/null +++ b/tests/Issue607.expect @@ -0,0 +1,65 @@ +/************************************************************************************* + * NOTE: This an educational hand-rolled transformation. Things can be incorrect or * + * buggy. * + *************************************************************************************/ +void __cxa_start(void); +void __cxa_atexit(void); +extern "C" void* memset(void*, int, unsigned int); + +namespace X +{ + int initInNamespace; + +} + +extern int initDueToExtern; + +int unInitGlobal; +int initGlobalWitValue = 3; + +static int initGlobalStatic; + +typedef struct A +{ + char __dummy; +} A; + + +A initGlobalCtor; + +namespace +{ + int initInAnonNamespace; + A initCtorInAnonNamespace; + +} + +int __main(void) +{ + ++X::initInNamespace; + return 0; +} + +int main(void) +{ + __cxa_start(); + int ret = __main(); + __cxa_atexit(); + return ret; + /* ret // lifetime ends here */ +} + +void __cxa_start(void) +{ + X::initInNamespace = 0; + initDueToExtern = 0; + initGlobalStatic = 0; + memset(&initGlobalCtor, 0, sizeof(A)); + ::initInAnonNamespace = 0; + memset(&::initCtorInAnonNamespace, 0, sizeof(A)); +} + +void __cxa_atexit(void) +{ +} +