]> granicus.if.org Git - clang/commitdiff
AST: Fix the linkage of static vars in fn template specializations
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 16 Dec 2014 04:52:14 +0000 (04:52 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 16 Dec 2014 04:52:14 +0000 (04:52 +0000)
We that static variables in function template specializations were
externally visible.  The manglers assumed that externally visible static
variables were numbered in Sema.  We would end up mangling static
variables in the same specialization with the same mangling number which
would give all of them the same name.

This fixes PR21904.

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

lib/AST/Decl.cpp
test/CodeGenCXX/function-template-specialization.cpp

index 1c0c6f766729270a66d6dca2db48d1cfb6a67f71..e43c28af9b699b01c612eeb13bda69ee55aeba04 100644 (file)
@@ -1192,7 +1192,7 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
   } else {
     const FunctionDecl *FD = cast<FunctionDecl>(OuterD);
     if (!FD->isInlined() &&
-        FD->getTemplateSpecializationKind() == TSK_Undeclared)
+        !isTemplateInstantiation(FD->getTemplateSpecializationKind()))
       return LinkageInfo::none();
 
     LV = getLVForDecl(FD, computation);
index eb099df14d0022659b29c9156dde2f19a53bce07..7728f3dc746244ba0474980d114578f370e8cd36 100644 (file)
@@ -1,4 +1,8 @@
 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// CHECK-DAG: _ZZN7PR219047GetDataIiEERKibE1i = internal global i32 4
+// CHECK-DAG: _ZZN7PR219047GetDataIiEERKibE1i_0 = internal global i32 2
+
 template<typename T, typename U>
 T* next(T* ptr, const U& diff);
 
@@ -24,3 +28,18 @@ void test2(int *iptr, double *dptr, int diff) {
   // CHECK: _Z4nextIdiEPT_S1_RKT0_
   dptr = next(dptr, diff);
 }
+
+namespace PR21904 {
+template <typename>
+const int &GetData(bool);
+
+template <>
+const int &GetData<int>(bool b) {
+  static int i = 4;
+  if (b) {
+    static int i = 2;
+    return i;
+  }
+  return i;
+}
+}