[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