From a683f639c7e24408409c6d07979ba171e2581653 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 11 Feb 2014 06:29:29 +0000 Subject: [PATCH] Fix PCH deserialization bug with local static symbols being treated as local extern. 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 and . llvm-svn: 201130 --- clang/lib/Serialization/ASTReaderDecl.cpp | 2 +- clang/test/PCH/local_static.cpp | 20 ++++++++++++++++++++ clang/test/PCH/local_static.h | 7 +++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 clang/test/PCH/local_static.cpp create mode 100644 clang/test/PCH/local_static.h diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 943328b..18dbb05 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -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/clang/test/PCH/local_static.cpp b/clang/test/PCH/local_static.cpp new file mode 100644 index 0000000..1085d81 --- /dev/null +++ b/clang/test/PCH/local_static.cpp @@ -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(); + 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/clang/test/PCH/local_static.h b/clang/test/PCH/local_static.h new file mode 100644 index 0000000..a69382a --- /dev/null +++ b/clang/test/PCH/local_static.h @@ -0,0 +1,7 @@ +class Bar { +public: + template + void f() { + static const T y = 0; + } +}; -- 2.7.4