Skip to content

Commit

Permalink
Don't dynamically initialize dllimport vars (PR19933)
Browse files Browse the repository at this point in the history
They should be initialized when they're exported.

Differential Revision: http://reviews.llvm.org/D4020

llvm-svn: 210217
  • Loading branch information
zmodem committed Jun 4, 2014
1 parent a1b6200 commit 910640b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
6 changes: 6 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Expand Up @@ -3671,6 +3671,12 @@ void Sema::InstantiateVariableInitializer(
// We already have an initializer in the class.
return;

if (Var->hasAttr<DLLImportAttr>() &&
!(OldVar->getInit() && OldVar->checkInitIsICE())) {
// Do not dynamically initialize dllimport variables.
return;
}

if (OldVar->getInit()) {
if (Var->isStaticDataMember() && !OldVar->isOutOfLine())
PushExpressionEvaluationContext(Sema::ConstantEvaluated, OldVar);
Expand Down
42 changes: 32 additions & 10 deletions clang/test/CodeGenCXX/dllimport.cpp
Expand Up @@ -5,6 +5,10 @@
// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s | FileCheck --check-prefix=GO1 %s

// CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC2 %s
// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU2 %s

// Helper structs to make templates more expressive.
struct ImplicitInst_Imported {};
struct ImplicitInst_NotImported {};
Expand Down Expand Up @@ -219,6 +223,11 @@ USE(inlineDef)
__declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
USE(noinline)

// MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
// GNU2-NOT: @_Z12alwaysInlinev()
__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
USE(alwaysInline)

// Redeclarations
// MSC-DAG: declare dllimport void @"\01?redecl1@@YAXXZ"()
// GNU-DAG: declare dllimport void @_Z7redecl1v()
Expand Down Expand Up @@ -580,13 +589,26 @@ namespace ClassTemplateStaticDef {
int f() { return S<int>::x; }
}

//===----------------------------------------------------------------------===//
// Negative checks
//===----------------------------------------------------------------------===//

// These checks are at the end to avoid interference with the DAG checks.

// MSC-NOT: @"\01?alwaysInline@@YAXXZ"()
// GNU-NOT: @_Z12alwaysInlinev()
__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
USE(alwaysInline)
namespace PR19933 {
// Don't dynamically initialize dllimport vars.
// MSC2-NOT: @llvm.global_ctors
// GNU2-NOT: @llvm.global_ctors

struct NonPOD { NonPOD(); };
template <typename T> struct A { static NonPOD x; };
template <typename T> NonPOD A<T>::x;
template struct __declspec(dllimport) A<int>;
// MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer

int f();
template <typename T> struct B { static int x; };
template <typename T> int B<T>::x = f();
template struct __declspec(dllimport) B<int>;
// MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0

constexpr int g() { return 42; }
template <typename T> struct C { static int x; };
template <typename T> int C<T>::x = g();
template struct __declspec(dllimport) C<int>;
// MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
}

0 comments on commit 910640b

Please sign in to comment.