Author: kremenek Date: Fri Apr 15 00:49:29 2011 New Revision: 129560 URL: http://llvm.org/viewvc/llvm-project?rev=129560&view=rev Log: Improve diagnostics on GNU attributes by warning about attributes that should have no arguments or parameters. Patch by Michael Han!
Added: cfe/trunk/test/Sema/attr-args.c Modified: cfe/trunk/include/clang/Sema/AttributeList.h cfe/trunk/lib/Sema/SemaDeclAttr.cpp Modified: cfe/trunk/include/clang/Sema/AttributeList.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=129560&r1=129559&r2=129560&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/AttributeList.h (original) +++ cfe/trunk/include/clang/Sema/AttributeList.h Fri Apr 15 00:49:29 2011 @@ -264,6 +264,10 @@ /// 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!"); Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=129560&r1=129559&r2=129560&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Apr 15 00:49:29 2011 @@ -752,7 +752,7 @@ 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 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 @@ } 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 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 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 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 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 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 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 @@ 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; Added: cfe/trunk/test/Sema/attr-args.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-args.c?rev=129560&view=auto ============================================================================== --- cfe/trunk/test/Sema/attr-args.c (added) +++ cfe/trunk/test/Sema/attr-args.c Fri Apr 15 00:49:29 2011 @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -DATTR=noreturn -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=always_inline -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=cdecl -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=const -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=fastcall -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=malloc -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=nothrow -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=stdcall -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=used -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=unused -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=weak -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s + +#define ATTR_DECL(a) __attribute__((ATTR(a))) + +int a; + +inline ATTR_DECL(a) void* foo(); // expected-error{{attribute takes no arguments}} + + + +// RUN: %clang_cc1 -DATTR=noreturn -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=always_inline -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=cdecl -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=const -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=fastcall -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=malloc -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=nothrow -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=stdcall -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=used -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=unused -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s +// RUN: %clang_cc1 -DATTR=weak -verify -Wunused -Wused-but-marked-unused -Wunused-parameter -Wunused -fsyntax-only %s + +#define ATTR_DECL(a) __attribute__((ATTR(a))) + +int a; + +inline ATTR_DECL(a) void* foo(); // expected-error{{attribute takes no arguments}} + + + _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits