]> granicus.if.org Git - clang/commitdiff
Fix bug in code for avoiding dynamic initialization of dllimport globals
authorHans Wennborg <hans@hanshq.net>
Wed, 18 Jun 2014 01:21:33 +0000 (01:21 +0000)
committerHans Wennborg <hans@hanshq.net>
Wed, 18 Jun 2014 01:21:33 +0000 (01:21 +0000)
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

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CodeGenCXX/microsoft-abi-static-initializers.cpp

index bce2fd552e3de87b4b0cd8a06c77e8f2efa82ba8..29a10d0daac710bbc64e3ddabe8fca717dcbbc8e 100644 (file)
@@ -3688,7 +3688,6 @@ void Sema::InstantiateVariableInitializer(
       if (Var->hasAttr<DLLImportAttr>() && InitExpr &&
           !InitExpr->isConstantInitializer(getASTContext(), false)) {
         // Do not dynamically initialize dllimport variables.
-        return;
       } else if (InitExpr) {
         bool DirectInit = OldVar->isDirectInit();
         AddInitializerToDecl(Var, InitExpr, DirectInit, TypeMayContainAuto);
index b353d0c9c2c7591b40ab0d6466cf3004923a2a92..a3127c79372b2bbf4831c25d3f2fb7d1c6cdc96c 100644 (file)
@@ -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 <typename T> struct A { static NonPOD x; };
+  template <typename T> NonPOD A<T>::x;
+  template struct __declspec(dllimport) A<int>;
+
+  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"()