r242420 - Disable #pragma redefine_extname for C++ code as it does not make sense in such a context.

Aaron Ballman aaron at aaronballman.com
Thu Jul 16 10:06:54 PDT 2015


Author: aaronballman
Date: Thu Jul 16 12:06:53 2015
New Revision: 242420

URL: http://llvm.org/viewvc/llvm-project?rev=242420&view=rev
Log:
Disable #pragma redefine_extname for C++ code as it does not make sense in such a context.

Patch by Andrey Bokhanko!

Added:
    cfe/trunk/test/SemaCXX/redefine_extname.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CodeGen/redefine_extname.c
    cfe/trunk/test/CodeGenCXX/redefine_extname.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=242420&r1=242419&r2=242420&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jul 16 12:06:53 2015
@@ -6343,6 +6343,10 @@ def warn_cast_qual : Warning<"cast from
   InGroup<CastQual>, DefaultIgnore;
 def warn_cast_qual2 : Warning<"cast from %0 to %1 must have all intermediate "
   "pointers const qualified to be safe">, InGroup<CastQual>, DefaultIgnore;
+def warn_redefine_extname_not_applied : Warning<
+  "#pragma redefine_extname is applicable to external C declarations only; "
+  "not applied to %select{function|variable}0 %1">,
+  InGroup<Pragmas>;
 } // End of general sema category.
 
 // inline asm.

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=242420&r1=242419&r2=242420&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jul 16 12:06:53 2015
@@ -5568,15 +5568,12 @@ bool Sema::adjustContextForLocalExternDe
   return true;
 }
 
-/// \brief Returns true if given declaration is TU-scoped and externally
-/// visible.
-static bool isDeclTUScopedExternallyVisible(const Decl *D) {
-  if (auto *FD = dyn_cast<FunctionDecl>(D))
-    return (FD->getDeclContext()->isTranslationUnit() || FD->isExternC()) &&
-           FD->hasExternalFormalLinkage();
-  else if (auto *VD = dyn_cast<VarDecl>(D))
-    return (VD->getDeclContext()->isTranslationUnit() || VD->isExternC()) &&
-           VD->hasExternalFormalLinkage();
+/// \brief Returns true if given declaration has external C language linkage.
+static bool isDeclExternC(const Decl *D) {
+  if (const auto *FD = dyn_cast<FunctionDecl>(D))
+    return FD->isExternC();
+  if (const auto *VD = dyn_cast<VarDecl>(D))
+    return VD->isExternC();
 
   llvm_unreachable("Unknown type of decl!");
 }
@@ -6005,13 +6002,16 @@ Sema::ActOnVariableDeclarator(Scope *S,
 
     NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
                                                 Context, Label, 0));
-  } else if (!ExtnameUndeclaredIdentifiers.empty() &&
-             isDeclTUScopedExternallyVisible(NewVD)) {
+  } else if (!ExtnameUndeclaredIdentifiers.empty()) {
     llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
       ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
     if (I != ExtnameUndeclaredIdentifiers.end()) {
-      NewVD->addAttr(I->second);
-      ExtnameUndeclaredIdentifiers.erase(I);
+      if (isDeclExternC(NewVD)) {
+        NewVD->addAttr(I->second);
+        ExtnameUndeclaredIdentifiers.erase(I);
+      } else
+        Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied)
+            << /*Variable*/1 << NewVD;
     }
   }
 
@@ -7533,13 +7533,16 @@ Sema::ActOnFunctionDeclarator(Scope *S,
     StringLiteral *SE = cast<StringLiteral>(E);
     NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
                                                 SE->getString(), 0));
-  } else if (!ExtnameUndeclaredIdentifiers.empty() &&
-             isDeclTUScopedExternallyVisible(NewFD)) {
+  } else if (!ExtnameUndeclaredIdentifiers.empty()) {
     llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
       ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier());
     if (I != ExtnameUndeclaredIdentifiers.end()) {
-      NewFD->addAttr(I->second);
-      ExtnameUndeclaredIdentifiers.erase(I);
+      if (isDeclExternC(NewFD)) {
+        NewFD->addAttr(I->second);
+        ExtnameUndeclaredIdentifiers.erase(I);
+      } else
+        Diag(NewFD->getLocation(), diag::warn_redefine_extname_not_applied)
+            << /*Variable*/0 << NewFD;
     }
   }
 
@@ -14388,12 +14391,14 @@ void Sema::ActOnPragmaRedefineExtname(Id
   // 1) declares a function or a variable
   // 2) has external linkage
   // already exists, add a label attribute to it.
-  if (PrevDecl &&
-      (isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl)) &&
-      PrevDecl->hasExternalFormalLinkage())
-    PrevDecl->addAttr(Attr);
+  if (PrevDecl && (isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl))) {
+    if (isDeclExternC(PrevDecl))
+      PrevDecl->addAttr(Attr);
+    else
+      Diag(PrevDecl->getLocation(), diag::warn_redefine_extname_not_applied)
+          << /*Variable*/(isa<FunctionDecl>(PrevDecl) ? 0 : 1) << PrevDecl;
   // Otherwise, add a label atttibute to ExtnameUndeclaredIdentifiers.
-  else
+  } else
     (void)ExtnameUndeclaredIdentifiers.insert(std::make_pair(Name, Attr));
 }
 

Modified: cfe/trunk/test/CodeGen/redefine_extname.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/redefine_extname.c?rev=242420&r1=242419&r2=242420&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/redefine_extname.c (original)
+++ cfe/trunk/test/CodeGen/redefine_extname.c Thu Jul 16 12:06:53 2015
@@ -24,3 +24,9 @@ int f() {
 extern int foo() { return 1; }
 // CHECK: define i32 @bar()
 
+// Check that pragma redefine_extname applies to external declarations only.
+#pragma redefine_extname foo_static bar_static
+static int foo_static() { return 1; }
+int baz() { return foo_static(); }
+// CHECK-NOT: call i32 @bar_static()
+

Modified: cfe/trunk/test/CodeGenCXX/redefine_extname.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/redefine_extname.cpp?rev=242420&r1=242419&r2=242420&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/redefine_extname.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/redefine_extname.cpp Thu Jul 16 12:06:53 2015
@@ -28,3 +28,9 @@ extern "C" {
 // CHECK: define i32 @bar()
 }
 
+// Check that pragma redefine_extname applies to C code only, and shouldn't be
+// applied to C++.
+#pragma redefine_extname foo_cpp bar_cpp
+extern int foo_cpp() { return 1; }
+// CHECK-NOT: define i32 @bar_cpp()
+

Added: cfe/trunk/test/SemaCXX/redefine_extname.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/redefine_extname.cpp?rev=242420&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/redefine_extname.cpp (added)
+++ cfe/trunk/test/SemaCXX/redefine_extname.cpp Thu Jul 16 12:06:53 2015
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux -Wpragmas -verify %s
+
+// Check that pragma redefine_extname applies to C code only, and shouldn't be
+// applied to C++.
+#pragma redefine_extname foo_cpp bar_cpp
+extern int foo_cpp() { return 1; } // expected-warning {{#pragma redefine_extname is applicable to external C declarations only; not applied to function 'foo_cpp'}}





More information about the cfe-commits mailing list