[cfe-commits] r172667 - in /cfe/trunk: lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclAttr.cpp test/Sema/attr-weak.c test/SemaCXX/attr-weak.cpp

Rafael Espindola rafael.espindola at gmail.com
Wed Jan 16 15:11:15 PST 2013


Author: rafael
Date: Wed Jan 16 17:11:15 2013
New Revision: 172667

URL: http://llvm.org/viewvc/llvm-project?rev=172667&view=rev
Log:
Check for internal weak decls after merging.

This fixes pr14946. The problem was that the linkage computation was done too
early, so things like "extern int a;" would be given external linkage, even if
a previous declaration was static.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Sema/attr-weak.c
    cfe/trunk/test/SemaCXX/attr-weak.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=172667&r1=172666&r2=172667&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jan 16 17:11:15 2013
@@ -4312,6 +4312,15 @@
   return false;
 }
 
+static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
+  // 'weak' only applies to declarations with external linkage.
+  WeakAttr *WA = ND.getAttr<WeakAttr>();
+  if (WA && ND.getLinkage() != ExternalLinkage) {
+    S.Diag(WA->getLocation(), diag::err_attribute_weak_static);
+    ND.dropAttr<WeakAttr>();
+  }
+}
+
 NamedDecl*
 Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
                               TypeSourceInfo *TInfo, LookupResult &Previous,
@@ -4590,6 +4599,8 @@
       NewVD->setInvalidDecl();
   }
 
+  checkAttributesAfterMerging(*this, *NewVD);
+
   // If this is a locally-scoped extern C variable, update the map of
   // such variables.
   if (CurContext->isFunctionOrMethod() && NewVD->isExternC() &&
@@ -6056,6 +6067,8 @@
     }
   }
 
+  checkAttributesAfterMerging(*this, *NewFD);
+
   AddKnownFunctionAttributes(NewFD);
 
   if (NewFD->hasAttr<OverloadableAttr>() && 

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=172667&r1=172666&r2=172667&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Jan 16 17:11:15 2013
@@ -2511,12 +2511,6 @@
 
   NamedDecl *nd = cast<NamedDecl>(D);
 
-  // 'weak' only applies to declarations with external linkage.
-  if (hasEffectivelyInternalLinkage(nd)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
-    return;
-  }
-
   nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
 }
 

Modified: cfe/trunk/test/Sema/attr-weak.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-weak.c?rev=172667&r1=172666&r2=172667&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-weak.c (original)
+++ cfe/trunk/test/Sema/attr-weak.c Wed Jan 16 17:11:15 2013
@@ -16,3 +16,9 @@
 // rdar://9538608
 int C; // expected-note {{previous definition is here}}
 extern int C __attribute__((weak_import)); // expected-warning {{an already-declared variable is made a weak_import declaration}}
+
+static int pr14946_x;
+extern int pr14946_x  __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
+
+static void pr14946_f();
+void pr14946_f() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}

Modified: cfe/trunk/test/SemaCXX/attr-weak.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-weak.cpp?rev=172667&r1=172666&r2=172667&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-weak.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-weak.cpp Wed Jan 16 17:11:15 2013
@@ -21,9 +21,16 @@
   };
 }
 
+// GCC rejects the instantiation with the internal type, but some existing
+// code expects it. It is also not that different from giving hidden visibility
+// to parts of a template that have explicit default visibility, so we accept
+// this.
 template <class T> struct Test7 {
   void test7() __attribute__((weak)) {}
+  static int var __attribute__((weak));
 };
+template <class T>
+int Test7<T>::var;
 namespace { class Internal; }
 template struct Test7<Internal>;
 template struct Test7<int>;





More information about the cfe-commits mailing list