diff options
| author | John McCall <rjmccall@apple.com> | 2011-02-10 06:50:24 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2011-02-10 06:50:24 +0000 |
| commit | f768aa7613f0705bc32e226f12fe58be9fb5b0b7 (patch) | |
| tree | 84ea1b7ad66bf5402dcc103a88c95205e6203124 | |
| parent | 6b657aed3365d6bf77b0eda4020eeea5661535e7 (diff) | |
| download | bcm5719-llvm-f768aa7613f0705bc32e226f12fe58be9fb5b0b7.tar.gz bcm5719-llvm-f768aa7613f0705bc32e226f12fe58be9fb5b0b7.zip | |
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
llvm-svn: 125268
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/AST/Decl.cpp | 13 | ||||
| -rw-r--r-- | clang/test/SemaCXX/linkage.cpp | 11 | ||||
| -rw-r--r-- | clang/test/SemaCXX/warn-unused-filescoped.cpp | 10 |
4 files changed, 33 insertions, 5 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d6c89c947ce..6b267432586 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5859,10 +5859,6 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) { 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: diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 11614df5003..9aeb04fa448 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -392,6 +392,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { } } + // 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 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) { 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 diff --git a/clang/test/SemaCXX/linkage.cpp b/clang/test/SemaCXX/linkage.cpp index fb21f94e92e..ba56318fbd6 100644 --- a/clang/test/SemaCXX/linkage.cpp +++ b/clang/test/SemaCXX/linkage.cpp @@ -53,5 +53,16 @@ namespace test2 { } } +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( diff --git a/clang/test/SemaCXX/warn-unused-filescoped.cpp b/clang/test/SemaCXX/warn-unused-filescoped.cpp index 628075ac04d..c32acb0b48b 100644 --- a/clang/test/SemaCXX/warn-unused-filescoped.cpp +++ b/clang/test/SemaCXX/warn-unused-filescoped.cpp @@ -66,7 +66,15 @@ namespace PR8841 { 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); +} |

