[cfe-commits] r126453 - in /cfe/trunk: lib/AST/Decl.cpp test/SemaCXX/linkage.cpp

Chandler Carruth chandlerc at gmail.com
Thu Feb 24 16:05:02 PST 2011


Author: chandlerc
Date: Thu Feb 24 18:05:02 2011
New Revision: 126453

URL: http://llvm.org/viewvc/llvm-project?rev=126453&view=rev
Log:
Fix the rest of PR9316 along with some other bugs spotted by inspection.
I tried to add test cases for these, but I can't because variables
aren't warned on the way functions are and the codegen layer appears to
use different logic for determining that 'a' and 'g' in the test case
should receive C mangling. I've included the test so that if we ever
switch the codegen layer to use these functions, we won't regress due to
latent bugs.

Modified:
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/test/SemaCXX/linkage.cpp

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=126453&r1=126452&r2=126453&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu Feb 24 18:05:02 2011
@@ -708,7 +708,7 @@
   //   external linkage.
   if (D->getLexicalDeclContext()->isFunctionOrMethod()) {
     if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
-      if (Function->isInAnonymousNamespace())
+      if (Function->isInAnonymousNamespace() && !Function->isExternC())
         return LinkageInfo::uniqueExternal();
 
       LinkageInfo LV;
@@ -729,7 +729,7 @@
     if (const VarDecl *Var = dyn_cast<VarDecl>(D))
       if (Var->getStorageClass() == SC_Extern ||
           Var->getStorageClass() == SC_PrivateExtern) {
-        if (Var->isInAnonymousNamespace())
+        if (Var->isInAnonymousNamespace() && !Var->isExternC())
           return LinkageInfo::uniqueExternal();
 
         LinkageInfo LV;
@@ -1041,8 +1041,11 @@
             getStorageClass() != SC_Static) ||
       (getDeclContext()->isFunctionOrMethod() && hasExternalStorage());
 
-  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
-       DC = DC->getParent()) {
+  const DeclContext *DC = getDeclContext();
+  if (DC->isFunctionOrMethod())
+    return false;
+
+  for (; !DC->isTranslationUnit(); DC = DC->getParent()) {
     if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
       if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
         return getStorageClass() != SC_Static;
@@ -1050,8 +1053,6 @@
       break;
     }
 
-    if (DC->isFunctionOrMethod())
-      return false;
   }
 
   return false;
@@ -1367,8 +1368,11 @@
   if (!Context.getLangOptions().CPlusPlus)
     return getStorageClass() != SC_Static && !getAttr<OverloadableAttr>();
 
-  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
-       DC = DC->getParent()) {
+  const DeclContext *DC = getDeclContext();
+  if (DC->isRecord())
+    return false;
+
+  for (; !DC->isTranslationUnit(); DC = DC->getParent()) {
     if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
       if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
         return getStorageClass() != SC_Static &&
@@ -1376,9 +1380,6 @@
 
       break;
     }
-    
-    if (DC->isRecord())
-      break;
   }
 
   return isMain();

Modified: cfe/trunk/test/SemaCXX/linkage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage.cpp?rev=126453&r1=126452&r2=126453&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/linkage.cpp (original)
+++ cfe/trunk/test/SemaCXX/linkage.cpp Thu Feb 24 18:05:02 2011
@@ -3,7 +3,7 @@
 // compared against the earlier cached value.  If we had a way of
 // testing linkage directly in Sema, that would be better.
 
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -Werror -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
 
 // PR8926
 namespace test0 {
@@ -69,5 +69,28 @@
   extern "C" void test4(void) {}
 }
 
+// PR9316: Ensure that even non-namespace-scope function declarations in
+// a C declaration context respect that over the anonymous namespace.
+extern "C" {
+  namespace {
+    struct X {
+      int f() {
+        extern int g();
+        extern int a;
+
+        // Test both for mangling in the code generation and warnings from use
+        // of internal, undefined names via -Werror.
+        // CHECK: call i32 @g(
+        // CHECK: load i32* @a,
+        return g() + a;
+      }
+    };
+  }
+  // Force the above function to be emitted by codegen.
+  int test(X& x) {
+    return x.f();
+  }
+}
+
 // CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv(
 // CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv(





More information about the cfe-commits mailing list