]> granicus.if.org Git - clang/commitdiff
Make __declspec(selectany) turn variable declartions into definitions.
authorNico Weber <nicolasweber@gmx.de>
Wed, 15 Apr 2015 21:50:06 +0000 (21:50 +0000)
committerNico Weber <nicolasweber@gmx.de>
Wed, 15 Apr 2015 21:50:06 +0000 (21:50 +0000)
Fixes PR23242.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235046 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Decl.cpp
test/CodeGen/ms-declspecs.c
test/CodeGen/ms-declspecs.cpp [new file with mode: 0644]

index 2ae73de5074643e01a565a94e29a78cffcba2d8a..349b7b43d1a4f9e1875182156240ba5508f75008 100644 (file)
@@ -1926,14 +1926,14 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition(
       getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
     return DeclarationOnly;
 
-  if (hasExternalStorage())
+  if (!hasAttr<SelectAnyAttr>() && hasExternalStorage())
     return DeclarationOnly;
 
   // [dcl.link] p7:
   //   A declaration directly contained in a linkage-specification is treated
   //   as if it contains the extern specifier for the purpose of determining
   //   the linkage of the declared name and whether it is a definition.
-  if (isSingleLineLanguageLinkage(*this))
+  if (!hasAttr<SelectAnyAttr>() && isSingleLineLanguageLinkage(*this))
     return DeclarationOnly;
 
   // C99 6.9.2p2:
index 328fc835d3475d8f5499d9f2a6f3fc8033a76310..985c227faa36b147f5586c625262880a43566dbb 100644 (file)
@@ -5,6 +5,10 @@ const __declspec(selectany) int x2 = 2;
 // CHECK: @x1 = weak_odr global i32 1, comdat, align 4
 // CHECK: @x2 = weak_odr constant i32 2, comdat, align 4
 
+// selectany turns extern variable declarations into definitions.
+extern __declspec(selectany) int x3;
+// CHECK: @x3 = weak_odr global i32 0, comdat, align 4
+
 struct __declspec(align(16)) S {
   char x;
 };
diff --git a/test/CodeGen/ms-declspecs.cpp b/test/CodeGen/ms-declspecs.cpp
new file mode 100644 (file)
index 0000000..f77c7cb
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s
+
+// selectany turns extern "C" variable declarations into definitions.
+extern __declspec(selectany) int x1;
+extern "C" __declspec(selectany) int x2;
+extern "C++" __declspec(selectany) int x3;
+extern "C" {
+__declspec(selectany) int x4;
+}
+// CHECK: @"\01?x1@@3HA" = weak_odr global i32 0, comdat, align 4
+// CHECK: @x2 = weak_odr global i32 0, comdat, align 4
+// CHECK: @"\01?x3@@3HA"  = weak_odr global i32 0, comdat, align 4
+// CHECK: @x4 = weak_odr global i32 0, comdat, align 4