r237787 - [MSVC] Handle out-of-line definition of static data member correctly (fix for http://llvm.org/PR21164), by Alexey Frolov
Alexey Bataev
a.bataev at hotmail.com
Wed May 20 04:57:04 PDT 2015
Author: abataev
Date: Wed May 20 06:57:02 2015
New Revision: 237787
URL: http://llvm.org/viewvc/llvm-project?rev=237787&view=rev
Log:
[MSVC] Handle out-of-line definition of static data member correctly (fix for http://llvm.org/PR21164), by Alexey Frolov
There are 3 cases of defining static const member:
initialized inside the class, not defined outside the class.
initialized inside the class, defined outside the class.
not initialized inside the class, defined outside the class.
Revision r213304 was supposed to fix the linkage problem of case (1), but mistakenly it made case (2) behave the same.
As a result, out-of-line definition of static data member is not handled correctly.
Proposed patch distinguishes between cases (1) and (2) and allows to properly emit static const members under –fms-compatibility option.
This fixes http://llvm.org/PR21164.
Differential Revision: http://reviews.llvm.org/D9850
Modified:
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/test/CodeGenCXX/dllexport-members.cpp
cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=237787&r1=237786&r2=237787&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed May 20 06:57:02 2015
@@ -4931,7 +4931,7 @@ CharUnits ASTContext::getObjCEncodingTyp
bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const {
return getLangOpts().MSVCCompat && VD->isStaticDataMember() &&
VD->getType()->isIntegralOrEnumerationType() &&
- !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit();
+ VD->isFirstDecl() && !VD->isOutOfLine() && VD->hasInit();
}
static inline
Modified: cfe/trunk/test/CodeGenCXX/dllexport-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport-members.cpp?rev=237787&r1=237786&r2=237787&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllexport-members.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllexport-members.cpp Wed May 20 06:57:02 2015
@@ -110,9 +110,10 @@ public:
// MSC-DAG: @"\01?StaticField at ExportMembers@@2HA" = dllexport global i32 1, align 4
// MSC-DAG: @"\01?StaticConstField at ExportMembers@@2HB" = dllexport constant i32 1, align 4
- // MSC-DAG: @"\01?StaticConstFieldEqualInit at ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
- // MSC-DAG: @"\01?StaticConstFieldBraceInit at ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
- // MSC-DAG: @"\01?ConstexprField at ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?StaticConstFieldEqualInit at ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?StaticConstFieldBraceInit at ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?StaticConstFieldRefNotDef at ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?ConstexprField at ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4
// GNU-DAG: @_ZN13ExportMembers11StaticFieldE = dllexport global i32 1, align 4
// GNU-DAG: @_ZN13ExportMembers16StaticConstFieldE = dllexport constant i32 1, align 4
// GNU-DAG: @_ZN13ExportMembers25StaticConstFieldEqualInitE = dllexport constant i32 1, align 4
@@ -122,6 +123,7 @@ public:
__declspec(dllexport) static const int StaticConstField;
__declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
__declspec(dllexport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllexport) static const int StaticConstFieldRefNotDef = 1;
__declspec(dllexport) constexpr static int ConstexprField = 1;
};
@@ -144,6 +146,7 @@ inline void ExportMembers::staticInlineD
const int ExportMembers::StaticConstField = 1;
const int ExportMembers::StaticConstFieldEqualInit;
const int ExportMembers::StaticConstFieldBraceInit;
+int foo() { return ExportMembers::StaticConstFieldRefNotDef; }
constexpr int ExportMembers::ConstexprField;
@@ -233,9 +236,10 @@ public:
// MSC-DAG: @"\01?StaticField at Nested@ExportMembers@@2HA" = dllexport global i32 1, align 4
// MSC-DAG: @"\01?StaticConstField at Nested@ExportMembers@@2HB" = dllexport constant i32 1, align 4
- // MSC-DAG: @"\01?StaticConstFieldEqualInit at Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
- // MSC-DAG: @"\01?StaticConstFieldBraceInit at Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
- // MSC-DAG: @"\01?ConstexprField at Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?StaticConstFieldEqualInit at Nested@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?StaticConstFieldBraceInit at Nested@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?StaticConstFieldRefNotDef at Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4
+ // MSC-DAG: @"\01?ConstexprField at Nested@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4
// GNU-DAG: @_ZN13ExportMembers6Nested11StaticFieldE = dllexport global i32 1, align 4
// GNU-DAG: @_ZN13ExportMembers6Nested16StaticConstFieldE = dllexport constant i32 1, align 4
// GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldEqualInitE = dllexport constant i32 1, align 4
@@ -245,6 +249,7 @@ public:
__declspec(dllexport) static const int StaticConstField;
__declspec(dllexport) static const int StaticConstFieldEqualInit = 1;
__declspec(dllexport) static const int StaticConstFieldBraceInit{1};
+ __declspec(dllexport) static const int StaticConstFieldRefNotDef = 1;
__declspec(dllexport) constexpr static int ConstexprField = 1;
};
@@ -267,6 +272,7 @@ inline void ExportMembers::Nested::stati
const int ExportMembers::Nested::StaticConstField = 1;
const int ExportMembers::Nested::StaticConstFieldEqualInit;
const int ExportMembers::Nested::StaticConstFieldBraceInit;
+int fooNested() { return ExportMembers::Nested::StaticConstFieldRefNotDef; }
constexpr int ExportMembers::Nested::ConstexprField;
Modified: cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp?rev=237787&r1=237786&r2=237787&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp Wed May 20 06:57:02 2015
@@ -1,35 +1,52 @@
// RUN: %clang_cc1 -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s
-// RUN: %clang_cc1 -DINLINE_INIT -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-INLINE
-// RUN: %clang_cc1 -DREAL_DEFINITION -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-OUTOFLINE
-// RUN: %clang_cc1 -DINLINE_INIT -DREAL_DEFINITION -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-INLINE
struct S {
- // For MS ABI, we emit a linkonce_odr definition here, even though it's really just a declaration.
-#ifdef INLINE_INIT
- static const int x = 5;
-#else
- static const int x;
-#endif
+ static const int NoInit_Ref;
+ static const int Inline_NotDef_NotRef = 5;
+ static const int Inline_NotDef_Ref = 5;
+ static const int Inline_Def_NotRef = 5;
+ static const int Inline_Def_Ref = 5;
+ static const int OutOfLine_Def_NotRef;
+ static const int OutOfLine_Def_Ref;
};
-const int *f() {
- return &S::x;
+const int *foo1() {
+ return &S::NoInit_Ref;
};
-#ifdef REAL_DEFINITION
-#ifdef INLINE_INIT
-const int S::x;
-#else
-const int S::x = 5;
-#endif
-#endif
+const int *foo2() {
+ return &S::Inline_NotDef_Ref;
+};
+
+const int *foo3() {
+ return &S::Inline_Def_Ref;
+};
+const int *foo4() {
+ return &S::OutOfLine_Def_Ref;
+};
-// Inline initialization.
-// CHECK-INLINE: @"\01?x at S@@2HB" = linkonce_odr constant i32 5, comdat, align 4
+const int S::Inline_Def_NotRef;
+const int S::Inline_Def_Ref;
+const int S::OutOfLine_Def_NotRef = 5;
+const int S::OutOfLine_Def_Ref = 5;
-// Out-of-line initialization.
-// CHECK-OUTOFLINE: @"\01?x at S@@2HB" = constant i32 5, align 4
// No initialization.
-// CHECK: @"\01?x at S@@2HB" = external constant i32
+// CHECK-DAG: @"\01?NoInit_Ref at S@@2HB" = external constant i32
+
+// Inline initialization, no real definiton, not referenced.
+// CHECK-NOT: @"\01?Inline_NotDef_NotRef at S@@2HB" = {{.*}} constant i32 5
+
+// Inline initialization, no real definiton, referenced.
+// CHECK-DAG: @"\01?Inline_NotDef_Ref at S@@2HB" = linkonce_odr constant i32 5, comdat, align 4
+
+// Inline initialization, real definiton, not referenced.
+// CHECK-DAG: @"\01?Inline_Def_NotRef at S@@2HB" = constant i32 5, align 4
+
+// Inline initialization, real definiton, referenced.
+// CHECK-DAG: @"\01?Inline_Def_Ref at S@@2HB" = constant i32 5, comdat, align 4
+
+// Out-of-line initialization.
+// CHECK-DAG: @"\01?OutOfLine_Def_NotRef at S@@2HB" = constant i32 5, align 4
+// CHECK-DAG: @"\01?OutOfLine_Def_Ref at S@@2HB" = constant i32 5, align 4
More information about the cfe-commits
mailing list