diff options
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 23 |
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 |