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 Index: test/CodeGenCXX/dllexport-members.cpp =================================================================== --- test/CodeGenCXX/dllexport-members.cpp +++ test/CodeGenCXX/dllexport-members.cpp @@ -110,9 +110,9 @@ // MSC-DAG: @"\01?StaticField@ExportMembers@@2HA" = dllexport global i32 1, align 4 // MSC-DAG: @"\01?StaticConstField@ExportMembers@@2HB" = dllexport constant i32 1, align 4 - // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 - // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 - // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?ConstexprField@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@Nested@ExportMembers@@2HA" = dllexport global i32 1, align 4 // MSC-DAG: @"\01?StaticConstField@Nested@ExportMembers@@2HB" = dllexport constant i32 1, align 4 - // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 - // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 - // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?ConstexprField@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@S@@2HB" = linkonce_odr constant i32 5, comdat, align 4 +// Inline initialization, no real definiton, not referenced. +// CHECK-INLINE-NODEF-NOTREF-NOT: @"\01?x@S@@2HB" = {{.*}} constant i32 5 + +// Inline initialization, no real definiton, referenced. +// CHECK-INLINE-NODEF-REF: @"\01?x@S@@2HB" = linkonce_odr constant i32 5, comdat, align 4 + +// Inline initialization, real definiton, not referenced. +// CHECK-INLINE-DEF-NOTREF: @"\01?x@S@@2HB" = constant i32 5, align 4 + +// Inline initialization, real definiton, referenced. +// CHECK-INLINE-DEF-REF: @"\01?x@S@@2HB" = constant i32 5, comdat, align 4 // Out-of-line initialization. // CHECK-OUTOFLINE: @"\01?x@S@@2HB" = constant i32 5, align 4