[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