]> granicus.if.org Git - clang/commitdiff
Improve diagnostics on GNU attributes by warning about attributes that should have...
authorTed Kremenek <kremenek@apple.com>
Fri, 15 Apr 2011 05:49:29 +0000 (05:49 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 15 Apr 2011 05:49:29 +0000 (05:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129560 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/AttributeList.h
lib/Sema/SemaDeclAttr.cpp
test/Sema/attr-args.c [new file with mode: 0644]

index ed2295554e35217c2f91b3f188454c4e945ef4d9..e976865217a72ed37918bcd8694d59887d934db1 100644 (file)
@@ -264,6 +264,10 @@ public:
   /// getNumArgs - Return the number of actual arguments to this attribute.
   unsigned getNumArgs() const { return NumArgs; }
 
+  /// hasParameterOrArguments - Return true if this attribute has a parameter,
+  /// or has a non empty argument expression list.
+  bool hasParameterOrArguments() const { return ParmName || NumArgs; }
+
   /// getArg - Return the specified argument.
   Expr *getArg(unsigned Arg) const {
     assert(Arg < NumArgs && "Arg access out of range!");
index 4c72c8390c5ad19f8761f25eae7559d41f129e57..5b3c486fd07edde2a028fa44446184de1851f047 100644 (file)
@@ -752,7 +752,7 @@ static void HandleNakedAttr(Decl *d, const AttributeList &Attr,
 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
                                    Sema &S) {
   // Check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
+  if (Attr.hasParameterOrArguments()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
@@ -768,7 +768,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
 
 static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // Check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
+  if (Attr.hasParameterOrArguments()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
@@ -827,7 +827,7 @@ static void HandleNoReturnAttr(Decl *d, const AttributeList &attr, Sema &S) {
 }
 
 bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
-  if (attr.getNumArgs() != 0) {
+  if (attr.hasParameterOrArguments()) {
     Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     attr.setInvalid();
     return true;
@@ -935,7 +935,7 @@ static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
 
 static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
+  if (Attr.hasParameterOrArguments()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
@@ -952,7 +952,7 @@ static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
 
 static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
+  if (Attr.hasParameterOrArguments()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
@@ -1402,7 +1402,7 @@ static void HandleWarnUnusedResult(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) {
+  if (attr.hasParameterOrArguments()) {
     S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
@@ -1514,7 +1514,7 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
 
 static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
+  if (Attr.hasParameterOrArguments()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
@@ -1524,7 +1524,7 @@ static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
 
 static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
+  if (Attr.hasParameterOrArguments()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     return;
   }
@@ -2262,7 +2262,7 @@ static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
 static void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   if (S.LangOpts.CUDA) {
     // check the attribute arguments.
-    if (Attr.getNumArgs() != 0) {
+    if (Attr.hasParameterOrArguments()) {
       S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
       return;
     }
@@ -2466,8 +2466,9 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
   if (attr.isInvalid())
     return true;
 
-  if (attr.getNumArgs() != 0 &&
-      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) {
+  if ((attr.getNumArgs() != 0 &&
+      !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
+      attr.getParameterName()) {
     Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
     attr.setInvalid();
     return true;
diff --git a/test/Sema/attr-args.c b/test/Sema/attr-args.c
new file mode 100644 (file)
index 0000000..fa6f3ad
--- /dev/null
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -DATTR=noreturn -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=always_inline -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=cdecl -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=const -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=fastcall -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=malloc -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=nothrow -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=stdcall -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=used -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=unused -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=weak -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+\r
+#define ATTR_DECL(a) __attribute__((ATTR(a)))\r
+\r
+int a;\r
+\r
+inline ATTR_DECL(a) void* foo(); // expected-error{{attribute takes no arguments}}\r
+\r
+\r
+\r
+// RUN: %clang_cc1 -DATTR=noreturn -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=always_inline -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=cdecl -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=const -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=fastcall -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=malloc -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=nothrow -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=stdcall -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=used -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=unused -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+// RUN: %clang_cc1 -DATTR=weak -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s\r
+\r
+#define ATTR_DECL(a) __attribute__((ATTR(a)))\r
+\r
+int a;\r
+\r
+inline ATTR_DECL(a) void* foo(); // expected-error{{attribute takes no arguments}}\r
+\r
+\r
+\r