]> granicus.if.org Git - clang/commitdiff
Fix PCH deserialization bug with local static symbols being treated as local extern.
authorTed Kremenek <kremenek@apple.com>
Tue, 11 Feb 2014 06:29:29 +0000 (06:29 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 11 Feb 2014 06:29:29 +0000 (06:29 +0000)
This triggered a miscompilation of code using Boost's function_template.hpp
when it was included inside a PCH file.  A local static within
that header would be treated as local extern, resulting in the wrong
mangling.  This only occurred during PCH deserialization.

Fixes <rdar://problem/15975816> and <rdar://problem/15926311>.

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

lib/Serialization/ASTReaderDecl.cpp
test/PCH/local_static.cpp [new file with mode: 0644]
test/PCH/local_static.h [new file with mode: 0644]

index 943328b9cdc7fc1340fab6616890a0a0b0f0b85a..18dbb053b99b1f4b234af7c7efdf693e9d714476 100644 (file)
@@ -973,7 +973,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
   VD->setCachedLinkage(VarLinkage);
 
   // Reconstruct the one piece of the IdentifierNamespace that we need.
-  if (VarLinkage != NoLinkage &&
+  if (VD->getStorageClass() == SC_Extern && VarLinkage != NoLinkage &&
       VD->getLexicalDeclContext()->isFunctionOrMethod())
     VD->setLocalExternDecl();
 
diff --git a/test/PCH/local_static.cpp b/test/PCH/local_static.cpp
new file mode 100644 (file)
index 0000000..1085d81
--- /dev/null
@@ -0,0 +1,20 @@
+// Test this without PCH.
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -include %S/local_static.h -fsyntax-only %s -emit-llvm -o %t.no_pch.ll %s
+// RUN: FileCheck --input-file %t.no_pch.ll %s
+
+// Test with PCH.
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -x c++-header -emit-pch -o %t.pch %S/local_static.h
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -include-pch %t.pch -emit-llvm -o %t.pch.ll %s
+// RUN: FileCheck --input-file %t.pch.ll %s
+
+void test(Bar &b) {
+  b.f<int>();
+  static int s;
+}
+
+// Check if the mangling of static and local extern variables
+// are correct and preserved by PCH.
+
+// CHECK: @_ZZ4testR3BarE1s = internal global i32 0, align 4
+// CHECK: @_ZZN3Bar1fIiEEvvE1y = linkonce_odr constant i32 0, align 4
+
diff --git a/test/PCH/local_static.h b/test/PCH/local_static.h
new file mode 100644 (file)
index 0000000..a69382a
--- /dev/null
@@ -0,0 +1,7 @@
+class Bar {
+public:
+  template<typename T>
+  void f() {
+    static const T y = 0;
+  }
+};