From: Hans Wennborg Date: Wed, 18 Jun 2014 01:21:33 +0000 (+0000) Subject: Fix bug in code for avoiding dynamic initialization of dllimport globals X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ceddfe355d53662af717edaf7fbb1222f0b7cec9;p=clang Fix bug in code for avoiding dynamic initialization of dllimport globals When instantiating dllimport variables with dynamic initializers, don't bail out of Sema::InstantiateVariableInitializer without calling PopExpressionEvaluationContext(). This was causing a stale object to stay on the ExprEvalContexts stack, causing subsequent calls to getCurrentMangleNumberContext() to fail, resulting in incorrect numbering of static locals (and probably other broken things). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211137 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index bce2fd552e..29a10d0daa 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3688,7 +3688,6 @@ void Sema::InstantiateVariableInitializer( if (Var->hasAttr() && InitExpr && !InitExpr->isConstantInitializer(getASTContext(), false)) { // Do not dynamically initialize dllimport variables. - return; } else if (InitExpr) { bool DirectInit = OldVar->isDirectInit(); AddInitializerToDecl(Var, InitExpr, DirectInit, TypeMayContainAuto); diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp index b353d0c9c2..a3127c7937 100644 --- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp +++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp @@ -189,6 +189,23 @@ inline void switch_test2() { switch (1) default: static int x = f(); } +namespace DynamicDLLImportInitVSMangling { + // Failing to pop the ExprEvalContexts when instantiating a dllimport var with + // dynamic initializer would cause subsequent static local numberings to be + // incorrect. + struct NonPOD { NonPOD(); }; + template struct A { static NonPOD x; }; + template NonPOD A::x; + template struct __declspec(dllimport) A; + + inline int switch_test3() { + // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ" + static int local; + // CHECK: @"\01?local@?1??switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ@4HA" + return local++; + } +} + void force_usage() { UnreachableStatic(); getS(); @@ -197,6 +214,7 @@ void force_usage() { (void)&T::enum_in_struct; switch_test(1); switch_test2(); + DynamicDLLImportInitVSMangling::switch_test3(); } // CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"()