[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