[cfe-commits] [PATCH] Check for internal weak decls after merging.

Rafael Ávila de Espíndola rafael.espindola at gmail.com
Tue Jan 15 21:16:34 PST 2013


This fixes pr14946 and changes our behaviour when instantiating weak decls in
templates with internal type arguments. We now match gcc. In the testcase in
attr-weak.cpp gcc says:

test.cpp: In instantiation of ‘struct Test7<{anonymous}::Internal>’:
test.cpp:8:17:   required from here
test.cpp:5:6: error: weak declaration of ‘void Test7<T>::test7() [with T = {anonymous}::Internal]’ must be public
 void Test7<T>::test7() {
      ^
---
 lib/Sema/SemaDecl.cpp      | 21 +++++++++++++++++----
 lib/Sema/SemaDeclAttr.cpp  |  6 ------
 test/Sema/attr-weak.c      |  6 ++++++
 test/SemaCXX/attr-weak.cpp |  4 ++--
 4 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 5d655e2..3357cbd 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4707,6 +4707,15 @@ static bool mayConflictWithNonVisibleExternC(const T *ND) {
   return ND->getDeclContext()->isTranslationUnit();
 }
 
+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>();
+  }
+}
+
 /// \brief Perform semantic checking on a newly-created variable
 /// declaration.
 ///
@@ -4847,11 +4856,13 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
     return false;
   }
 
-  if (!Previous.empty()) {
+  bool IsRedeclaration = !Previous.empty();
+  if (IsRedeclaration)
     MergeVarDecl(NewVD, Previous);
-    return true;
-  }
-  return false;
+
+  checkAttributesAfterMerging(*this, *NewVD);
+
+  return IsRedeclaration;
 }
 
 /// \brief Data used with FindOverriddenMethod
@@ -6284,6 +6295,8 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
     }
   }
 
+  checkAttributesAfterMerging(*this, *NewFD);
+
   // Semantic checking for this function declaration (in isolation).
   if (getLangOpts().CPlusPlus) {
     // C++-specific checks.
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 85f48ec..efeafa6 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -2511,12 +2511,6 @@ static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
 
   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));
 }
 
diff --git a/test/Sema/attr-weak.c b/test/Sema/attr-weak.c
index adedf12..df74554 100644
--- a/test/Sema/attr-weak.c
+++ b/test/Sema/attr-weak.c
@@ -16,3 +16,9 @@ static int x __attribute__((weak)); // expected-error {{weak declaration cannot
 // 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}}
diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp
index b6a9e0a..cabe8bb 100644
--- a/test/SemaCXX/attr-weak.cpp
+++ b/test/SemaCXX/attr-weak.cpp
@@ -22,8 +22,8 @@ namespace {
 }
 
 template <class T> struct Test7 {
-  void test7() __attribute__((weak)) {}
+  void test7() __attribute__((weak)) {} // expected-error {{weak declaration cannot have internal linkage}}
 };
 namespace { class Internal; }
-template struct Test7<Internal>;
+template struct Test7<Internal>; // expected-note {{in instantiation of template class 'Test7<<anonymous>::Internal>' requested here}}
 template struct Test7<int>;
-- 
1.7.11.7




More information about the cfe-commits mailing list