summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-11-10 21:10:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-11-10 21:10:32 +0000
commit99c464c3f377c31824318455789cdd422b3e3a82 (patch)
treeb18d762b7c84a8ea23978095a76b66c67640c1cc /clang/lib/Parse/ParseDecl.cpp
parent217e1eec0dc0287b5a1df4237532c79618a769fa (diff)
downloadbcm5719-llvm-99c464c3f377c31824318455789cdd422b3e3a82.tar.gz
bcm5719-llvm-99c464c3f377c31824318455789cdd422b3e3a82.zip
Improve diagnostics if _Noreturn is placed after a function declarator. (This sometimes happens when a macro is used that expands to either the GNU noreturn attribute or _Noreturn.)
llvm-svn: 221630
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index b2fa88db2b6..66b98c2c4da 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1601,9 +1601,30 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// appropriate function scope after the function Decl has been constructed.
// These will be parsed in ParseFunctionDefinition or ParseLexedAttrList.
LateParsedAttrList LateParsedAttrs(true);
- if (D.isFunctionDeclarator())
+ if (D.isFunctionDeclarator()) {
MaybeParseGNUAttributes(D, &LateParsedAttrs);
+ // The _Noreturn keyword can't appear here, unlike the GNU noreturn
+ // attribute. If we find the keyword here, tell the user to put it
+ // at the start instead.
+ if (Tok.is(tok::kw__Noreturn)) {
+ SourceLocation Loc = ConsumeToken();
+ const char *PrevSpec;
+ unsigned DiagID;
+
+ // We can offer a fixit if it's valid to mark this function as _Noreturn
+ // and we don't have any other declarators in this declaration.
+ bool Fixit = !DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID);
+ MaybeParseGNUAttributes(D, &LateParsedAttrs);
+ Fixit &= Tok.is(tok::semi) || Tok.is(tok::l_brace) || Tok.is(tok::kw_try);
+
+ Diag(Loc, diag::err_c11_noreturn_misplaced)
+ << (Fixit ? FixItHint::CreateRemoval(Loc) : FixItHint())
+ << (Fixit ? FixItHint::CreateInsertion(D.getLocStart(), "_Noreturn ")
+ : FixItHint());
+ }
+ }
+
// Check to see if we have a function *definition* which must have a body.
if (D.isFunctionDeclarator() &&
// Look at the next token to make sure that this isn't a function
OpenPOWER on IntegriCloud