[cfe-commits] r165082 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaStmtAttr.cpp test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp test/Parser/cxx0x-attributes.cpp test/Parser/cxx11-
Richard Smith
richard at metafoo.co.uk
Wed Oct 3 14:41:34 PDT 2012
On Wed, Oct 3, 2012 at 12:10 PM, Matthieu Monrocq <
matthieu.monrocq at gmail.com> wrote:
> On Wed, Oct 3, 2012 at 3:56 AM, Michael Han <Michael.Han at autodesk.com>
> wrote:
> > Author: hanm
> > Date: Tue Oct 2 20:56:22 2012
> > New Revision: 165082
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=165082&view=rev
> > Log:
> > Improve C++11 attribute parsing.
> >
> > - General C++11 attributes were previously parsed and ignored. Now they
> are parsed and stored in AST.
> > - Add support to parse arguments of attributes that in 'gnu' namespace.
> > - Differentiate unknown attributes and known attributes that can't be
> applied to statements when emitting diagnostic.
> >
> >
> > Modified:
> > cfe/trunk/include/clang/Parse/Parser.h
> > cfe/trunk/lib/Parse/ParseDecl.cpp
> > cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> > cfe/trunk/lib/Sema/SemaStmtAttr.cpp
> > cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp
> > cfe/trunk/test/Parser/cxx0x-attributes.cpp
> > cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp
> > cfe/trunk/test/Parser/objcxx11-attributes.mm
> > cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
> >
> > Modified: cfe/trunk/include/clang/Parse/Parser.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=165082&r1=165081&r2=165082&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/Parse/Parser.h (original)
> > +++ cfe/trunk/include/clang/Parse/Parser.h Tue Oct 2 20:56:22 2012
> > @@ -1848,7 +1848,10 @@
> > void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
> > SourceLocation AttrNameLoc,
> > ParsedAttributes &Attrs,
> > - SourceLocation *EndLoc);
> > + SourceLocation *EndLoc,
> > + IdentifierInfo *ScopeName,
> > + SourceLocation ScopeLoc,
> > + AttributeList::Syntax Syntax);
> >
> > void MaybeParseCXX0XAttributes(Declarator &D) {
> > if (getLangOpts().CPlusPlus0x && isCXX11AttributeSpecifier()) {
> > @@ -1878,6 +1881,7 @@
> > SourceLocation *EndLoc = 0);
> > void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
> > SourceLocation *EndLoc = 0);
> > +
> > IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc);
> >
> > void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
> >
> > Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=165082&r1=165081&r2=165082&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> > +++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Oct 2 20:56:22 2012
> > @@ -154,7 +154,8 @@
> > Eof.setLocation(Tok.getLocation());
> > LA->Toks.push_back(Eof);
> > } else {
> > - ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc);
> > + ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc,
> > + 0, AttrNameLoc, AttributeList::AS_GNU);
> > }
> > } else {
> > attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc,
> > @@ -173,11 +174,15 @@
> > }
> >
> >
> > -/// Parse the arguments to a parameterized GNU attribute
> > +/// Parse the arguments to a parameterized GNU attribute or
> > +/// a C++11 attribute in "gnu" namespace.
> > void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
> > SourceLocation AttrNameLoc,
> > ParsedAttributes &Attrs,
> > - SourceLocation *EndLoc) {
> > + SourceLocation *EndLoc,
> > + IdentifierInfo *ScopeName,
> > + SourceLocation ScopeLoc,
> > + AttributeList::Syntax Syntax) {
> >
> > assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with
> '('");
> >
> > @@ -278,9 +283,9 @@
> > SourceLocation RParen = Tok.getLocation();
> > if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
> > AttributeList *attr =
> > - Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), 0,
> AttrNameLoc,
> > - ParmName, ParmLoc, ArgExprs.data(), ArgExprs.size(),
> > - AttributeList::AS_GNU);
> > + Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen),
> > + ScopeName, ScopeLoc, ParmName, ParmLoc,
> > + ArgExprs.data(), ArgExprs.size(), Syntax);
> > if (BuiltinType && attr->getKind() ==
> AttributeList::AT_IBOutletCollection)
> > Diag(Tok, diag::err_iboutletcollection_builtintype);
> > }
> > @@ -923,7 +928,8 @@
> > if (HasFunScope)
> > Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
> >
> > - ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
> &endLoc);
> > + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
> &endLoc,
> > + 0, LA.AttrNameLoc, AttributeList::AS_GNU);
> >
> > if (HasFunScope) {
> > Actions.ActOnExitFunctionContext();
> > @@ -935,7 +941,8 @@
> > } else {
> > // If there are multiple decls, then the decl cannot be within the
> > // function scope.
> > - ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
> &endLoc);
> > + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
> &endLoc,
> > + 0, LA.AttrNameLoc, AttributeList::AS_GNU);
> > }
> > } else {
> > Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
> >
> > Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=165082&r1=165081&r2=165082&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
> > +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Oct 2 20:56:22 2012
> > @@ -2879,6 +2879,21 @@
> > }
> > }
> >
> > +static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
> > + IdentifierInfo
> *ScopeName) {
> > + switch (AttributeList::getKind(AttrName, ScopeName,
> > + AttributeList::AS_CXX11)) {
> > + case AttributeList::AT_CarriesDependency:
> > + case AttributeList::AT_FallThrough:
> > + case AttributeList::AT_NoReturn: {
> > + return true;
> > + }
> > +
> > + default:
> > + return false;
> > + }
> > +}
> > +
> > /// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier.
> Currently
> > /// only parses standard attributes.
> > ///
> > @@ -2963,46 +2978,38 @@
> > }
> > }
> >
> > + bool StandardAttr =
> IsBuiltInOrStandardCXX11Attribute(AttrName,ScopeName);
> > bool AttrParsed = false;
> > - switch (AttributeList::getKind(AttrName, ScopeName,
> > - AttributeList::AS_CXX11)) {
> > - // No arguments
> > - case AttributeList::AT_CarriesDependency:
> > - // FIXME: implement generic support of attributes with C++11 syntax
> > - // see Parse/ParseDecl.cpp: ParseGNUAttributes
> > - case AttributeList::AT_FallThrough:
> > - case AttributeList::AT_NoReturn: {
> > - if (Tok.is(tok::l_paren)) {
> > - Diag(Tok.getLocation(),
> diag::err_cxx11_attribute_forbids_arguments)
> > - << AttrName->getName();
> > - break;
> > +
> > + // Parse attribute arguments
> > + if (Tok.is(tok::l_paren)) {
> > + if (ScopeName && ScopeName->getName() == "gnu") {
> > + ParseGNUAttributeArgs(AttrName, AttrLoc, attrs, endLoc,
> > + ScopeName, ScopeLoc,
> AttributeList::AS_CXX11);
> > + AttrParsed = true;
> > + } else {
> > + if (StandardAttr)
> > + Diag(Tok.getLocation(),
> diag::err_cxx11_attribute_forbids_arguments)
> > + << AttrName->getName();
> > +
> > + // FIXME: handle other formats of c++11 attribute arguments
> > + ConsumeParen();
> > + SkipUntil(tok::r_paren, false);
> > }
> > + }
> >
> > + if (!AttrParsed)
> > attrs.addNew(AttrName,
> > SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc,
> > AttrLoc),
> > ScopeName, ScopeLoc, 0,
> > SourceLocation(), 0, 0, AttributeList::AS_CXX11);
> > - AttrParsed = true;
> > - break;
> > - }
> > -
> > - // Silence warnings
> > - default: break;
> > - }
> > -
> > - // Skip the entire parameter clause, if any
> > - if (!AttrParsed && Tok.is(tok::l_paren)) {
> > - ConsumeParen();
> > - // SkipUntil maintains the balancedness of tokens.
> > - SkipUntil(tok::r_paren, false);
> > - }
> >
> > if (Tok.is(tok::ellipsis)) {
> > - if (AttrParsed)
> > - Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
> > - << AttrName->getName();
> > ConsumeToken();
> > +
> > + Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
> > + << AttrName->getName();
> > }
> > }
> >
> >
> > Modified: cfe/trunk/lib/Sema/SemaStmtAttr.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=165082&r1=165081&r2=165082&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaStmtAttr.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp Tue Oct 2 20:56:22 2012
> > @@ -48,11 +48,16 @@
> > static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const
> AttributeList &A,
> > SourceRange Range) {
> > switch (A.getKind()) {
> > + case AttributeList::UnknownAttribute:
> > + S.Diag(A.getLoc(), A.isDeclspecAttribute() ?
> > + diag::warn_unhandled_ms_attribute_ignored :
> > + diag::warn_unknown_attribute_ignored) << A.getName();
> > + return 0;
> > case AttributeList::AT_FallThrough:
> > return handleFallThroughAttr(S, St, A, Range);
> > default:
> > - // if we're here, then we parsed an attribute, but didn't recognize
> it as a
> > - // statement attribute => it is declaration attribute
> > + // if we're here, then we parsed a known attribute, but didn't
> recognize
> > + // it as a statement attribute => it is declaration attribute
> > S.Diag(A.getRange().getBegin(),
> diag::warn_attribute_invalid_on_stmt)
> > << A.getName()->getName() << St->getLocStart();
> > return 0;
> >
> > Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp?rev=165082&r1=165081&r2=165082&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp
> (original)
> > +++ cfe/trunk/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p6.cpp Tue Oct
> 2 20:56:22 2012
> > @@ -6,7 +6,8 @@
> > void f() {
> > int x = 42, y[5];
> > // FIXME: Produce a better diagnostic for this case.
> > - int(p[[x] { return x; }()]); // expected-error {{expected ']'}}
> > + int(p[[x] { return x; }()]); // expected-error {{expected ']'}} \
> > + // expected-warning {{unknown attribute 'x' ignored}}
> > y[[] { return 2; }()] = 2; // expected-error {{consecutive left
> square brackets}}
> > }
> >
> >
> > Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=165082&r1=165081&r2=165082&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
> > +++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Tue Oct 2 20:56:22 2012
> > @@ -44,10 +44,15 @@
> > int && [[]] rref_attr = 0;
> > int array_attr [1] [[]];
> > alignas(8) int aligned_attr;
> > -[[test::valid(for 42 [very] **** '+' symbols went on a trip and had a
> "good"_time; the end.)]]
> > - int garbage_attr;
> > -[[,,,static, class, namespace,, inline, constexpr, mutable,, bi\
> > -tand, bitor::compl(!.*_ Cx.!U^*R),,,]] int more_garbage_attr;
> > +[[test::valid(for 42 [very] **** '+' symbols went on a trip and had a
> "good"_time; the end.)]] int garbage_attr; // expected-warning {{unknown
> attribute 'valid' ignored}}
> > +[[,,,static, class, namespace,, inline, constexpr, mutable,, bitand,
> bitor::compl(!.*_ Cx.!U^*R),,,]] int more_garbage_attr; // expected-warning
> {{unknown attribute 'static' ignored}} \
> > + // expected-warning {{unknown attribute 'class' ignored}} \
> > + // expected-warning {{unknown attribute 'namespace' ignored}} \
> > + // expected-warning {{unknown attribute 'inline' ignored}} \
> > + // expected-warning {{unknown attribute 'constexpr' ignored}} \
> > + // expected-warning {{unknown attribute 'mutable' ignored}} \
> > + // expected-warning {{unknown attribute 'bitand' ignored}} \
> > + // expected-warning {{unknown attribute 'compl' ignored}}
> > [[u8"invalid!"]] int invalid_string_attr; // expected-error {{expected
> ']'}}
> > void fn_attr () [[]];
> > void noexcept_fn_attr () noexcept [[]];
> > @@ -212,3 +217,9 @@
> > one, /* rest are deprecated */ two, three
> > };
> > enum class [[]] EvenMoreSecrets {};
> > +
> > +namespace arguments {
> > + // FIXME: remove the sema warnings after migrating existing gnu
> attributes to c++11 syntax.
> > + void f(const char*, ...) [[gnu::format(printf, 1, 2)]]; //
> expected-warning {{unknown attribute 'format' ignored}}
> > + void g() [[unknown::foo(currently arguments of attributes from
> unknown namespace other than 'gnu' namespace are ignored... blah...)]]; //
> expected-warning {{unknown attribute 'foo' ignored}}
> > +}
> >
> > Modified: cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp?rev=165082&r1=165081&r2=165082&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp (original)
> > +++ cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp Tue Oct 2 20:56:22
> 2012
> > @@ -2,53 +2,78 @@
> >
> > void foo(int i) {
> >
> > - [[unknown_attribute]] ;
> > - [[unknown_attribute]] { }
> > - [[unknown_attribute]] if (0) { }
> > - [[unknown_attribute]] for (;;);
> > - [[unknown_attribute]] do {
> > - [[unknown_attribute]] continue;
> > + [[unknown_attribute]] ; // expected-warning {{unknown attribute
> 'unknown_attribute' ignored}}
> > + [[unknown_attribute]] { } // expected-warning {{unknown attribute
> 'unknown_attribute' ignored}}
> > + [[unknown_attribute]] if (0) { } // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> > + [[unknown_attribute]] for (;;); // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> > + [[unknown_attribute]] do { // expected-warning {{unknown attribute
> 'unknown_attribute' ignored}}
> > + [[unknown_attribute]] continue; // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> > } while (0);
> > - [[unknown_attribute]] while (0);
> > + [[unknown_attribute]] while (0); // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> >
> > - [[unknown_attribute]] switch (i) {
> > - [[unknown_attribute]] case 0:
> > - [[unknown_attribute]] default:
> > - [[unknown_attribute]] break;
> > + [[unknown_attribute]] switch (i) { // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> > + [[unknown_attribute]] case 0: // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> > + [[unknown_attribute]] default: // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> > + [[unknown_attribute]] break; // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> > }
> >
> > - [[unknown_attribute]] goto here;
> > - [[unknown_attribute]] here:
> > + [[unknown_attribute]] goto here; // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> > + [[unknown_attribute]] here: // expected-warning {{unknown attribute
> 'unknown_attribute' ignored}}
> >
> > - [[unknown_attribute]] try {
> > + [[unknown_attribute]] try { // expected-warning {{unknown attribute
> 'unknown_attribute' ignored}}
> > } catch (...) {
> > }
> >
> > - [[unknown_attribute]] return;
> > -
> > + [[unknown_attribute]] return; // expected-warning {{unknown attribute
> 'unknown_attribute' ignored}}
> > +
> >
> > alignas(8) ; // expected-warning {{attribute aligned cannot be
> specified on a statement}}
> > [[noreturn]] { } // expected-warning {{attribute noreturn cannot be
> specified on a statement}}
> > [[noreturn]] if (0) { } // expected-warning {{attribute noreturn
> cannot be specified on a statement}}
> > [[noreturn]] for (;;); // expected-warning {{attribute noreturn
> cannot be specified on a statement}}
> > [[noreturn]] do { // expected-warning {{attribute noreturn cannot be
> specified on a statement}}
> > - [[unavailable]] continue; // TODO: only noreturn, alignas and
> carries_dependency are parsed in C++ 11 syntax at the moment, hence no
> warning here
> > + [[unavailable]] continue; // expected-warning {{unknown attribute
> 'unavailable' ignored}}
> > + } while (0);
> > + [[unknown_attributqqq]] while (0); // expected-warning {{unknown
> attribute 'unknown_attributqqq' ignored}}
> > + // TODO: remove 'qqq' part and enjoy 'empty loop body' warning
> here (DiagnoseEmptyLoopBody)
> > +
> > + [[unknown_attribute]] while (0); // expected-warning {{unknown
> attribute 'unknown_attribute' ignored}}
> > +
> > + [[unused]] switch (i) { // expected-warning {{unknown attribute
> 'unused' ignored}}
> > + [[uuid]] case 0: // expected-warning {{unknown attribute 'uuid'
> ignored}}
> > + [[visibility]] default: // expected-warning {{unknown attribute
> 'visibility' ignored}}
> > + [[carries_dependency]] break; // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > + }
> > +
> > + [[fastcall]] goto there; // expected-warning {{unknown attribute
> 'fastcall' ignored}}
> > + [[noinline]] there: // expected-warning {{unknown attribute
> 'noinline' ignored}}
> > +
> > + [[lock_returned]] try { // expected-warning {{unknown attribute
> 'lock_returned' ignored}}
> > + } catch (...) {
> > + }
> > +
> > + [[weakref]] return; // expected-warning {{unknown attribute 'weakref'
> ignored}}
> > +
> > + [[carries_dependency]] ; // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > + [[carries_dependency]] { } // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > + [[carries_dependency]] if (0) { } // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > + [[carries_dependency]] for (;;); // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > + [[carries_dependency]] do { // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > + [[carries_dependency]] continue; // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}} ignored}}
> > } while (0);
> > - [[unknown_attributqqq]] while (0); // TODO: remove 'qqq' part and
> enjoy 'empty loop body' warning here (DiagnoseEmptyLoopBody)
> > - [[unknown_attribute]] while (0); // no warning here yet, just an
> unknown attribute
> > + [[carries_dependency]] while (0); // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> >
> > - [[unused]] switch (i) { // TODO: only noreturn, alignas and
> carries_dependency are parsed in C++ 11 syntax at the moment, hence no
> warning here
> > - [[uuid]] case 0: // TODO: only noreturn, alignas and
> carries_dependency are parsed in C++ 11 syntax at the moment, hence no
> warning here
> > - [[visibility]] default: // TODO: only noreturn, alignas and
> carries_dependency are parsed in C++ 11 syntax at the moment, hence no
> warning here
> > + [[carries_dependency]] switch (i) { // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}} ignored}}
> > + [[carries_dependency]] case 0: // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > + [[carries_dependency]] default: // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > [[carries_dependency]] break; // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > }
> >
> > - [[fastcall]] goto there; // TODO: only noreturn, alignas and
> carries_dependency are parsed in C++ 11 syntax at the moment, hence no
> warning here
> > - [[noinline]] there: // TODO: only noreturn, alignas and
> carries_dependency are parsed in C++ 11 syntax at the moment, hence no
> warning here
> > + [[carries_dependency]] goto here; // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> >
> > - [[lock_returned]] try { // TODO: only noreturn, alignas and
> carries_dependency are parsed in C++ 11 syntax at the moment, hence no
> warning here
> > + [[carries_dependency]] try { // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > } catch (...) {
> > }
> >
> > - [[weakref]] return; // TODO: only noreturn, alignas and
> carries_dependency are parsed in C++ 11 syntax at the moment, hence no
> warning here
> > + [[carries_dependency]] return; // expected-warning {{attribute
> carries_dependency cannot be specified on a statement}}
> > }
> >
> > Modified: cfe/trunk/test/Parser/objcxx11-attributes.mm
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx11-attributes.mm?rev=165082&r1=165081&r2=165082&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/Parser/objcxx11-attributes.mm (original)
> > +++ cfe/trunk/test/Parser/objcxx11-attributes.mm Tue Oct 2 20:56:22
> 2012
> > @@ -31,9 +31,13 @@
> >
> > // An attribute is OK.
> > [[]];
> > - [[int(), noreturn]]; // expected-warning {{attribute noreturn cannot
> be specified on a statement}}
> > - [[class, test(foo 'x' bar),,,]];
> > - [[bitand, noreturn]]; // expected-warning {{attribute noreturn cannot
> be specified on a statement}}
> > + [[int(), noreturn]]; // expected-warning {{unknown attribute 'int'
> ignored}} \
> > + // expected-warning {{attribute noreturn cannot be specified on a
> statement}}
> > + [[class, test(foo 'x' bar),,,]]; // expected-warning {{unknown
> attribute 'test' ignored}}\
> > + // expected-warning {{unknown attribute 'class' ignored}}
> > +
> > + [[bitand, noreturn]]; // expected-warning {{attribute noreturn cannot
> be specified on a statement}} \
> > + expected-warning {{unknown attribute 'bitand' ignored}}
> >
> > // FIXME: Suppress vexing parse warning
> > [[noreturn]]int(e)(); // expected-warning {{function declaration}}
> expected-note {{replace parentheses with an initializer}}
> > @@ -52,7 +56,11 @@
> > }
> >
> > template<typename...Ts> void f(Ts ...x) {
> > - [[test::foo(bar, baz)...]];
> > - [[used(x)...]];
> > + [[test::foo(bar, baz)...]]; // expected-error {{attribute 'foo'
> cannot be used as an attribute pack}} \
> > + // expected-warning {{unknown attribute 'foo' ignored}}
> > +
> > + [[used(x)...]]; // expected-error {{attribute 'used' cannot be used
> as an attribute pack}} \
> > + // expected-warning {{unknown attribute 'used' ignored}}
> > +
> > [[x...] { return [ X alloc ]; }() init];
> > }
> >
> > Modified:
> cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp?rev=165082&r1=165081&r2=165082&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
> (original)
> > +++ cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
> Tue Oct 2 20:56:22 2012
> > @@ -42,7 +42,7 @@
> > switch (n % 2) {
> > case 0:
> > // FIXME: This should be typo-corrected, probably.
> > - [[fallthrough]];
> > + [[fallthrough]]; // expected-warning{{unknown attribute
> 'fallthrough' ignored}}
> > case 2: // expected-warning{{unannotated fall-through}}
> expected-note{{clang::fallthrough}} expected-note{{break;}}
> > [[clang::fallthrough]];
> > case 1:
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
> Thanks Michael!
>
> I have one nit: the warning is on by default. Is this intentional ? I
> expect it will produce quite a lot of noise on codebases annotated for
> another compiler (gcc for example) if clang ever miss one or two gcc
> attributes. Since the Standard explicitly asks compilers to ignore
> unknown attributes it also seems strange to warn aggressively on
> unknown ones.
>
> What do you think ?
The current behavior matches our existing behavior for
__attribute__((unknown)). The standard doesn't say to ignore unknown
attributes, it just says the behavior of non-standard attributes is
implementation-defined, so we're well within our rights to issue a warning.
I don't think we should silently ignore typo'd attributes!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121003/713444fc/attachment.html>
More information about the cfe-commits
mailing list