[PATCH] [MSVC] Handle out-of-line definition of static data member correctly (fix for http://llvm.org/PR21164)
Alexey Frolov
alexfrolov1878 at yandex.ru
Tue May 19 05:39:01 PDT 2015
Hi majnemer, rnk,
There are 3 cases of defining static const member:
1) //initialized// inside the class, //not defined// outside the class.
2) //initialized// inside the class, //defined// outside the class.
3) //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.
REPOSITORY
rL LLVM
http://reviews.llvm.org/D9850
Files:
lib/AST/ASTContext.cpp
test/CodeGenCXX/dllexport-members.cpp
test/CodeGenCXX/ms-integer-static-data-members.cpp
Index: test/CodeGenCXX/dllexport-members.cpp
===================================================================
--- test/CodeGenCXX/dllexport-members.cpp
+++ test/CodeGenCXX/dllexport-members.cpp
@@ -110,9 +110,9 @@
// 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?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
@@ -233,9 +233,9 @@
// 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?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
Index: test/CodeGenCXX/ms-integer-static-data-members.cpp
===================================================================
--- test/CodeGenCXX/ms-integer-static-data-members.cpp
+++ test/CodeGenCXX/ms-integer-static-data-members.cpp
@@ -1,7 +1,13 @@
-// 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 -DREFERENCED -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-NODEF-NOTREF
+// RUN: %clang_cc1 -DINLINE_INIT -DREFERENCED -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-INLINE-NODEF-REF
+
+// RUN: %clang_cc1 -DINLINE_INIT -DREAL_DEFINITION -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-INLINE-DEF-NOTREF
+// RUN: %clang_cc1 -DINLINE_INIT -DREAL_DEFINITION -DREFERENCED -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-INLINE-DEF-REF
+
// 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
+// RUN: %clang_cc1 -DREAL_DEFINITION -DREFERENCED -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-OUTOFLINE
struct S {
// For MS ABI, we emit a linkonce_odr definition here, even though it's really just a declaration.
@@ -12,9 +18,11 @@
#endif
};
+#ifdef REFERENCED
const int *f() {
return &S::x;
};
+#endif
#ifdef REAL_DEFINITION
#ifdef INLINE_INIT
@@ -25,8 +33,17 @@
#endif
-// Inline initialization.
-// CHECK-INLINE: @"\01?x at S@@2HB" = linkonce_odr constant i32 5, comdat, align 4
+// Inline initialization, no real definiton, not referenced.
+// CHECK-INLINE-NODEF-NOTREF-NOT: @"\01?x at S@@2HB" = {{.*}} constant i32 5
+
+// Inline initialization, no real definiton, referenced.
+// CHECK-INLINE-NODEF-REF: @"\01?x at S@@2HB" = linkonce_odr constant i32 5, comdat, align 4
+
+// Inline initialization, real definiton, not referenced.
+// CHECK-INLINE-DEF-NOTREF: @"\01?x at S@@2HB" = constant i32 5, align 4
+
+// Inline initialization, real definiton, referenced.
+// CHECK-INLINE-DEF-REF: @"\01?x at S@@2HB" = constant i32 5, comdat, align 4
// Out-of-line initialization.
// CHECK-OUTOFLINE: @"\01?x at S@@2HB" = constant i32 5, align 4
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -4906,7 +4906,8 @@
bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const {
return getLangOpts().MSVCCompat && VD->isStaticDataMember() &&
VD->getType()->isIntegralOrEnumerationType() &&
- !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit();
+ !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit() &&
+ VD->getFirstDecl() == VD;
}
static inline
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9850.26051.patch
Type: text/x-patch
Size: 6080 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150519/4409d9c7/attachment.bin>
More information about the cfe-commits
mailing list