[cfe-commits] r125126 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclAttr.cpp test/Sema/attr-weak.c test/SemaCXX/attr-weak.cpp test/SemaCXX/attr-weakref.cpp

John McCall rjmccall at apple.com
Tue Feb 8 14:35:49 PST 2011


Author: rjmccall
Date: Tue Feb  8 16:35:49 2011
New Revision: 125126

URL: http://llvm.org/viewvc/llvm-project?rev=125126&view=rev
Log:
When checking the 'weak' and 'weakref' attributes, look for non-external
linkage rather than the presence of the 'static' storage class specifier.
Fixes rdar://problem/8814626.


Added:
    cfe/trunk/test/SemaCXX/attr-weak.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Sema/attr-weak.c
    cfe/trunk/test/SemaCXX/attr-weakref.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=125126&r1=125125&r2=125126&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb  8 16:35:49 2011
@@ -1051,11 +1051,11 @@
 def warn_weak_identifier_undeclared : Warning<
   "weak identifier %0 never declared">;
 def err_attribute_weak_static : Error<
-  "weak declaration of '%0' must be public">;
+  "weak declaration cannot have internal linkage">;
 def warn_attribute_weak_import_invalid_on_definition : Warning<
   "'weak_import' attribute cannot be specified on a definition">;
 def err_attribute_weakref_not_static : Error<
-  "weakref declaration of '%0' must be static">;
+  "weakref declaration must have internal linkage">;
 def err_attribute_weakref_not_global_context : Error<
   "weakref declaration of '%0' must be in a global context">;
 def err_attribute_weakref_without_alias : Error<

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=125126&r1=125125&r2=125126&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Feb  8 16:35:49 2011
@@ -586,11 +586,23 @@
                                              start, size));
 }
 
-static bool isStaticVarOrStaticFunction(Decl *D) {
-  if (VarDecl *VD = dyn_cast<VarDecl>(D))
-    return VD->getStorageClass() == SC_Static;
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-    return FD->getStorageClass() == SC_Static;
+/// Whether this declaration has internal linkage for the purposes of
+/// things that want to complain about things not have internal linkage.
+static bool hasEffectivelyInternalLinkage(NamedDecl *D) {
+  switch (D->getLinkage()) {
+  case NoLinkage:
+  case InternalLinkage:
+    return true;
+
+  // Template instantiations that go from external to unique-external
+  // shouldn't get diagnosed.
+  case UniqueExternalLinkage:
+    return true;
+
+  case ExternalLinkage:
+    return false;
+  }
+  llvm_unreachable("unknown linkage kind!");
   return false;
 }
 
@@ -601,6 +613,14 @@
     return;
   }
 
+  if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << 2 /*variables and functions*/;
+    return;
+  }
+
+  NamedDecl *nd = cast<NamedDecl>(d);
+
   // gcc rejects
   // class c {
   //   static int a __attribute__((weakref ("v2")));
@@ -614,7 +634,7 @@
   const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
   if (!Ctx->isFileContext()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
-        dyn_cast<NamedDecl>(d)->getNameAsString();
+        nd->getNameAsString();
     return;
   }
 
@@ -636,9 +656,8 @@
   // This looks like a bug in gcc. We reject that for now. We should revisit
   // it if this behaviour is actually used.
 
-  if (!isStaticVarOrStaticFunction(d)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) <<
-      dyn_cast<NamedDecl>(d)->getNameAsString();
+  if (!hasEffectivelyInternalLinkage(nd)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
     return;
   }
 
@@ -1274,28 +1293,28 @@
   D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
 }
 
-static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
+static void HandleWeakAttr(Decl *d, const AttributeList &attr, Sema &S) {
   // check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+  if (attr.getNumArgs() != 0) {
+    S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
 
-  /* weak only applies to non-static declarations */
-  if (isStaticVarOrStaticFunction(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) <<
-      dyn_cast<NamedDecl>(D)->getNameAsString();
+  if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
+    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << attr.getName() << 2 /*variables and functions*/;
     return;
   }
 
-  // TODO: could also be applied to methods?
-  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << 2 /*variable and function*/;
+  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;
   }
 
-  D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
+  nd->addAttr(::new (S.Context) WeakAttr(attr.getLoc(), S.Context));
 }
 
 static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {

Modified: cfe/trunk/test/Sema/attr-weak.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-weak.c?rev=125126&r1=125125&r2=125126&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-weak.c (original)
+++ cfe/trunk/test/Sema/attr-weak.c Tue Feb  8 16:35:49 2011
@@ -11,5 +11,4 @@
 struct __attribute__((weak)) s0 {}; // expected-warning {{'weak' attribute only applies to variables and functions}}
 struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' attribute only applies to variables and functions}}
 
-static int x __attribute__((weak)); // expected-error {{weak declaration of 'x' must be public}}
-
+static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}

Added: cfe/trunk/test/SemaCXX/attr-weak.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-weak.cpp?rev=125126&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-weak.cpp (added)
+++ cfe/trunk/test/SemaCXX/attr-weak.cpp Tue Feb  8 16:35:49 2011
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+
+static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
+static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
+
+namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables and functions}}
+}
+
+namespace {
+  int test3 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
+  void test4() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
+}
+
+struct Test5 {
+  static void test5() __attribute__((weak)); // no error
+};
+
+namespace {
+  struct Test6 {
+    static void test6() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
+  };
+}
+
+template <class T> struct Test7 {
+  void test7() __attribute__((weak)) {}
+};
+namespace { class Internal; }
+template struct Test7<Internal>;
+template struct Test7<int>;

Modified: cfe/trunk/test/SemaCXX/attr-weakref.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-weakref.cpp?rev=125126&r1=125125&r2=125126&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-weakref.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-weakref.cpp Tue Feb  8 16:35:49 2011
@@ -24,8 +24,8 @@
   static int a __attribute__((weakref ("v2"))); // expected-error {{declaration of 'a' must be in a global context}}
   static int b() __attribute__((weakref ("f3"))); // expected-error {{declaration of 'b' must be in a global context}}
 };
-int a7() __attribute__((weakref ("f1"))); // expected-error {{declaration of 'a7' must be static}}
-int a8 __attribute__((weakref ("v1"))); // expected-error {{declaration of 'a8' must be static}}
+int a7() __attribute__((weakref ("f1"))); // expected-error {{weakref declaration must have internal linkage}}
+int a8 __attribute__((weakref ("v1"))); // expected-error {{weakref declaration must have internal linkage}}
 
 // gcc accepts this
-int a9 __attribute__((weakref)); // expected-error {{declaration of 'a9' must be static}}
+int a9 __attribute__((weakref)); // expected-error {{weakref declaration must have internal linkage}}





More information about the cfe-commits mailing list