[cfe-commits] r125268 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/AST/Decl.cpp test/SemaCXX/linkage.cpp test/SemaCXX/warn-unused-filescoped.cpp
John McCall
rjmccall at apple.com
Wed Feb 9 22:50:24 PST 2011
Author: rjmccall
Date: Thu Feb 10 00:50:24 2011
New Revision: 125268
URL: http://llvm.org/viewvc/llvm-project?rev=125268&view=rev
Log:
Move the check that gives functions with unique-external types unique-external
linkage into Decl.cpp. Disable this logic for extern "C" functions, because
the operative rule there is weaker. Fixes rdar://problem/8898466
Modified:
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/test/SemaCXX/linkage.cpp
cfe/trunk/test/SemaCXX/warn-unused-filescoped.cpp
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=125268&r1=125267&r2=125268&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Feb 10 00:50:24 2011
@@ -5859,10 +5859,6 @@
GVALinkage External = GVA_StrongExternal;
Linkage L = FD->getLinkage();
- if (L == ExternalLinkage && getLangOptions().CPlusPlus &&
- FD->getType()->getLinkage() == UniqueExternalLinkage)
- L = UniqueExternalLinkage;
-
switch (L) {
case NoLinkage:
case InternalLinkage:
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=125268&r1=125267&r2=125268&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu Feb 10 00:50:24 2011
@@ -392,6 +392,14 @@
}
}
+ // In C++, then if the type of the function uses a type with
+ // unique-external linkage, it's not legally usable from outside
+ // this translation unit. However, we should use the C linkage
+ // rules instead for extern "C" declarations.
+ if (Context.getLangOptions().CPlusPlus && !Function->isExternC() &&
+ Function->getType()->getLinkage() == UniqueExternalLinkage)
+ return LinkageInfo::uniqueExternal();
+
if (FunctionTemplateSpecializationInfo *SpecInfo
= Function->getTemplateSpecializationInfo()) {
LV.merge(getLVForDecl(SpecInfo->getTemplate(),
@@ -512,6 +520,11 @@
return LinkageInfo::uniqueExternal();
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ // If the type of the function uses a type with unique-external
+ // linkage, it's not legally usable from outside this translation unit.
+ if (MD->getType()->getLinkage() == UniqueExternalLinkage)
+ return LinkageInfo::uniqueExternal();
+
TemplateSpecializationKind TSK = TSK_Undeclared;
// If this is a method template specialization, use the linkage for
Modified: cfe/trunk/test/SemaCXX/linkage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage.cpp?rev=125268&r1=125267&r2=125268&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/linkage.cpp (original)
+++ cfe/trunk/test/SemaCXX/linkage.cpp Thu Feb 10 00:50:24 2011
@@ -53,5 +53,16 @@
}
}
+namespace test3 {
+ namespace { struct A {}; }
+
+ // CHECK: define internal void @_ZN5test34testENS_12_GLOBAL__N_11AE(
+ void test(A a) {}
+ void force() { test(A()); }
+
+ // CHECK: define void @test3(
+ extern "C" void test3(A a) {}
+}
+
// CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv(
// CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv(
Modified: cfe/trunk/test/SemaCXX/warn-unused-filescoped.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unused-filescoped.cpp?rev=125268&r1=125267&r2=125268&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-unused-filescoped.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-unused-filescoped.cpp Thu Feb 10 00:50:24 2011
@@ -66,7 +66,15 @@
template <typename T> void template_test(X<T> x) {
(void)(x == x);
}
- void test(X<int> x) {
+ void test() {
+ X<int> x;
template_test(x);
}
}
+
+namespace test4 {
+ namespace { struct A {}; }
+
+ void test(A a); // expected-warning {{unused function}}
+ extern "C" void test4(A a);
+}
More information about the cfe-commits
mailing list