From: David Majnemer Date: Thu, 19 Mar 2015 00:10:23 +0000 (+0000) Subject: Parse: Don't assume tokens have a length X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f92da5f2f07c188b4b8070a1f74da2a1ea07cb55;p=clang Parse: Don't assume tokens have a length Don't crash if the last token in a bad inline method body is an annotation token. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@232694 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h index 8617c67b32..e087809340 100644 --- a/include/clang/Lex/Token.h +++ b/include/clang/Lex/Token.h @@ -130,7 +130,7 @@ public: SourceLocation getAnnotationEndLoc() const { assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); - return SourceLocation::getFromRawEncoding(UintData); + return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc); } void setAnnotationEndLoc(SourceLocation L) { assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); @@ -141,6 +141,11 @@ public: return isAnnotation() ? getAnnotationEndLoc() : getLocation(); } + SourceLocation getEndLoc() const { + return isAnnotation() ? getAnnotationEndLoc() + : getLocation().getLocWithOffset(getLength()); + } + /// \brief SourceRange of the group of tokens that this annotation token /// represents. SourceRange getAnnotationRange() const { diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp index a53079b260..86ac471ddb 100644 --- a/lib/Parse/ParseCXXInlineMethods.cpp +++ b/lib/Parse/ParseCXXInlineMethods.cpp @@ -317,8 +317,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { Token DefArgEnd; DefArgEnd.startToken(); DefArgEnd.setKind(tok::eof); - DefArgEnd.setLocation(LastDefaultArgToken.getLocation().getLocWithOffset( - LastDefaultArgToken.getLength())); + DefArgEnd.setLocation(LastDefaultArgToken.getEndLoc()); DefArgEnd.setEofData(Param); Toks->push_back(DefArgEnd); @@ -392,9 +391,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { Token ExceptionSpecEnd; ExceptionSpecEnd.startToken(); ExceptionSpecEnd.setKind(tok::eof); - ExceptionSpecEnd.setLocation( - LastExceptionSpecToken.getLocation().getLocWithOffset( - LastExceptionSpecToken.getLength())); + ExceptionSpecEnd.setLocation(LastExceptionSpecToken.getEndLoc()); ExceptionSpecEnd.setEofData(LM.Method); Toks->push_back(ExceptionSpecEnd); @@ -499,8 +496,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { Token BodyEnd; BodyEnd.startToken(); BodyEnd.setKind(tok::eof); - BodyEnd.setLocation( - LastBodyToken.getLocation().getLocWithOffset(LastBodyToken.getLength())); + BodyEnd.setLocation(LastBodyToken.getEndLoc()); BodyEnd.setEofData(LM.D); LM.Toks.push_back(BodyEnd); // Append the current token at the end of the new token stream so that it diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 5f89f01598..0ae4679806 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -906,6 +906,7 @@ void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, << "visibility"; return; } + SourceLocation EndLoc = Tok.getLocation(); PP.LexUnexpandedToken(Tok); if (Tok.isNot(tok::eod)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) @@ -917,6 +918,7 @@ void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, Toks[0].startToken(); Toks[0].setKind(tok::annot_pragma_vis); Toks[0].setLocation(VisLoc); + Toks[0].setAnnotationEndLoc(EndLoc); Toks[0].setAnnotationValue( const_cast(static_cast(VisType))); PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, @@ -1036,6 +1038,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Toks[0].startToken(); Toks[0].setKind(tok::annot_pragma_pack); Toks[0].setLocation(PackLoc); + Toks[0].setAnnotationEndLoc(RParenLoc); Toks[0].setAnnotationValue(static_cast(Info)); PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); @@ -1054,6 +1057,7 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); return; } + SourceLocation EndLoc = Tok.getLocation(); const IdentifierInfo *II = Tok.getIdentifierInfo(); if (II->isStr("on")) { Kind = Sema::PMSST_ON; @@ -1079,6 +1083,7 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, Toks[0].startToken(); Toks[0].setKind(tok::annot_pragma_msstruct); Toks[0].setLocation(MSStructTok.getLocation()); + Toks[0].setAnnotationEndLoc(EndLoc); Toks[0].setAnnotationValue(reinterpret_cast( static_cast(Kind))); PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, @@ -1134,6 +1139,7 @@ static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, return; } + SourceLocation EndLoc = Tok.getLocation(); PP.Lex(Tok); if (Tok.isNot(tok::eod)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) @@ -1148,6 +1154,7 @@ static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, Toks[0].startToken(); Toks[0].setKind(tok::annot_pragma_align); Toks[0].setLocation(FirstTok.getLocation()); + Toks[0].setAnnotationEndLoc(EndLoc); Toks[0].setAnnotationValue(reinterpret_cast( static_cast(Kind))); PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, @@ -1291,6 +1298,7 @@ void PragmaWeakHandler::HandlePragma(Preprocessor &PP, pragmaUnusedTok.startToken(); pragmaUnusedTok.setKind(tok::annot_pragma_weakalias); pragmaUnusedTok.setLocation(WeakLoc); + pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation()); Toks[1] = WeakName; Toks[2] = AliasName; PP.EnterTokenStream(Toks, 3, @@ -1303,6 +1311,7 @@ void PragmaWeakHandler::HandlePragma(Preprocessor &PP, pragmaUnusedTok.startToken(); pragmaUnusedTok.setKind(tok::annot_pragma_weak); pragmaUnusedTok.setLocation(WeakLoc); + pragmaUnusedTok.setAnnotationEndLoc(WeakLoc); Toks[1] = WeakName; PP.EnterTokenStream(Toks, 2, /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); @@ -1348,6 +1357,7 @@ void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP, pragmaRedefTok.startToken(); pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname); pragmaRedefTok.setLocation(RedefLoc); + pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation()); Toks[1] = RedefName; Toks[2] = AliasName; PP.EnterTokenStream(Toks, 3, @@ -1370,6 +1380,7 @@ PragmaFPContractHandler::HandlePragma(Preprocessor &PP, Toks[0].startToken(); Toks[0].setKind(tok::annot_pragma_fp_contract); Toks[0].setLocation(Tok.getLocation()); + Toks[0].setAnnotationEndLoc(Tok.getLocation()); Toks[0].setAnnotationValue(reinterpret_cast( static_cast(OOS))); PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, @@ -1429,6 +1440,7 @@ PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP, Toks[0].setKind(tok::annot_pragma_opencl_extension); Toks[0].setLocation(NameLoc); Toks[0].setAnnotationValue(data.getOpaqueValue()); + Toks[0].setAnnotationEndLoc(StateLoc); PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true, /*OwnsTokens=*/false); @@ -1560,6 +1572,7 @@ void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP, return; } + SourceLocation EndLoc = Tok.getLocation(); PP.Lex(Tok); if (Tok.isNot(tok::eod)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) @@ -1571,6 +1584,7 @@ void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP, AnnotTok.startToken(); AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members); AnnotTok.setLocation(PointersToMembersLoc); + AnnotTok.setAnnotationEndLoc(EndLoc); AnnotTok.setAnnotationValue( reinterpret_cast(static_cast(RepresentationMethod))); PP.EnterToken(AnnotTok); @@ -1650,6 +1664,7 @@ void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP, PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp"; return; } + SourceLocation EndLoc = Tok.getLocation(); PP.Lex(Tok); if (Tok.isNot(tok::eod)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) @@ -1662,6 +1677,7 @@ void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP, AnnotTok.startToken(); AnnotTok.setKind(tok::annot_pragma_ms_vtordisp); AnnotTok.setLocation(VtorDispLoc); + AnnotTok.setAnnotationEndLoc(EndLoc); AnnotTok.setAnnotationValue(reinterpret_cast( static_cast((Kind << 16) | (Value & 0xFFFF)))); PP.EnterToken(AnnotTok); @@ -1678,10 +1694,13 @@ void PragmaMSPragma::HandlePragma(Preprocessor &PP, AnnotTok.startToken(); AnnotTok.setKind(tok::annot_pragma_ms_pragma); AnnotTok.setLocation(Tok.getLocation()); + AnnotTok.setAnnotationEndLoc(Tok.getLocation()); SmallVector TokenVector; // Suck up all of the tokens before the eod. - for (; Tok.isNot(tok::eod); PP.Lex(Tok)) + for (; Tok.isNot(tok::eod); PP.Lex(Tok)) { TokenVector.push_back(Tok); + AnnotTok.setAnnotationEndLoc(Tok.getLocation()); + } // Add a sentinal EoF token to the end of the list. TokenVector.push_back(EoF); // We must allocate this array with new because EnterTokenStream is going to @@ -2000,6 +2019,7 @@ void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP, LoopHintTok.startToken(); LoopHintTok.setKind(tok::annot_pragma_loop_hint); LoopHintTok.setLocation(PragmaName.getLocation()); + LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation()); LoopHintTok.setAnnotationValue(static_cast(Info)); TokenList.push_back(LoopHintTok); } @@ -2082,6 +2102,7 @@ void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP, TokenArray[0].startToken(); TokenArray[0].setKind(tok::annot_pragma_loop_hint); TokenArray[0].setLocation(PragmaName.getLocation()); + TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation()); TokenArray[0].setAnnotationValue(static_cast(Info)); PP.EnterTokenStream(TokenArray, 1, /*DisableMacroExpansion=*/false, /*OwnsTokens=*/true); diff --git a/test/Parser/annotation-token-in-lexed-body.cpp b/test/Parser/annotation-token-in-lexed-body.cpp new file mode 100644 index 0000000000..bcc9de111a --- /dev/null +++ b/test/Parser/annotation-token-in-lexed-body.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct S { // expected-note{{to match this}} + void f() { // expected-note{{to match this}} + // expected-error@+1{{expected '}'}} expected-error@+1{{expected '}'}} expected-error@+1{{expected ';'}} +#pragma pack()