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