[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-stmt-attributes.cpp test/Parser/objcxx11-attributes.mm test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
Michael Han
Michael.Han at autodesk.com
Tue Oct 2 18:56:22 PDT 2012
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:
More information about the cfe-commits
mailing list