patch-r278788-clang-r201130-pch-miscompilation.diff revision 278789
1Pull in r201130 from upstream clang trunk (by Ted Kremenek):
2
3  Fix PCH deserialization bug with local static symbols being treated
4  as local extern.
5
6  This triggered a miscompilation of code using Boost's
7  function_template.hpp when it was included inside a PCH file.  A
8  local static within that header would be treated as local extern,
9  resulting in the wrong mangling.  This only occurred during PCH
10  deserialization.
11
12  Fixes <rdar://problem/15975816> and <rdar://problem/15926311>.
13
14This fixes a crash in audio/murmur, which is using both PCH and Boost.
15
16Introduced here: http://svnweb.freebsd.org/changeset/base/278788
17
18Index: tools/clang/lib/Serialization/ASTReaderDecl.cpp
19===================================================================
20--- tools/clang/lib/Serialization/ASTReaderDecl.cpp
21+++ tools/clang/lib/Serialization/ASTReaderDecl.cpp
22@@ -971,7 +971,7 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::V
23   VD->setCachedLinkage(VarLinkage);
24 
25   // Reconstruct the one piece of the IdentifierNamespace that we need.
26-  if (VarLinkage != NoLinkage &&
27+  if (VD->getStorageClass() == SC_Extern && VarLinkage != NoLinkage &&
28       VD->getLexicalDeclContext()->isFunctionOrMethod())
29     VD->setLocalExternDecl();
30 
31Index: tools/clang/test/PCH/local_static.cpp
32===================================================================
33--- tools/clang/test/PCH/local_static.cpp
34+++ tools/clang/test/PCH/local_static.cpp
35@@ -0,0 +1,20 @@
36+// Test this without PCH.
37+// 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
38+// RUN: FileCheck --input-file %t.no_pch.ll %s
39+
40+// Test with PCH.
41+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -x c++-header -emit-pch -o %t.pch %S/local_static.h
42+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -include-pch %t.pch -emit-llvm -o %t.pch.ll %s
43+// RUN: FileCheck --input-file %t.pch.ll %s
44+
45+void test(Bar &b) {
46+  b.f<int>();
47+  static int s;
48+}
49+
50+// Check if the mangling of static and local extern variables
51+// are correct and preserved by PCH.
52+
53+// CHECK: @_ZZ4testR3BarE1s = internal global i32 0, align 4
54+// CHECK: @_ZZN3Bar1fIiEEvvE1y = linkonce_odr constant i32 0, align 4
55+
56Index: tools/clang/test/PCH/local_static.h
57===================================================================
58--- tools/clang/test/PCH/local_static.h
59+++ tools/clang/test/PCH/local_static.h
60@@ -0,0 +1,7 @@
61+class Bar {
62+public:
63+  template<typename T>
64+  void f() {
65+    static const T y = 0;
66+  }
67+};
68