From: Reid Kleckner Date: Thu, 20 Oct 2016 20:53:20 +0000 (+0000) Subject: Fix off-by-one error in PPCaching.cpp token annotation assertion X-Git-Tag: llvmorg-4.0.0-rc1~6644 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ae818501b7d891512de45c1f7362045c53440a46;p=platform%2Fupstream%2Fllvm.git Fix off-by-one error in PPCaching.cpp token annotation assertion This assert is intended to defend against backtracking into the middle of a sequence of tokens that is being replaced with an annotation, but it's OK if we backtrack to the exact position of the start of the annotation sequence. Use a <= comparison instead of <. Fixes PR25946 llvm-svn: 284777 --- diff --git a/clang/lib/Lex/PPCaching.cpp b/clang/lib/Lex/PPCaching.cpp index 4742aae..ae07ea9 100644 --- a/clang/lib/Lex/PPCaching.cpp +++ b/clang/lib/Lex/PPCaching.cpp @@ -105,7 +105,7 @@ void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) { for (CachedTokensTy::size_type i = CachedLexPos; i != 0; --i) { CachedTokensTy::iterator AnnotBegin = CachedTokens.begin() + i-1; if (AnnotBegin->getLocation() == Tok.getLocation()) { - assert((BacktrackPositions.empty() || BacktrackPositions.back() < i) && + assert((BacktrackPositions.empty() || BacktrackPositions.back() <= i) && "The backtrack pos points inside the annotated tokens!"); // Replace the cached tokens with the single annotation token. if (i < CachedLexPos) diff --git a/clang/test/Parser/backtrack-off-by-one.cpp b/clang/test/Parser/backtrack-off-by-one.cpp new file mode 100644 index 0000000..74b51cb --- /dev/null +++ b/clang/test/Parser/backtrack-off-by-one.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -verify %s + +// PR25946 +// We had an off-by-one error in an assertion when annotating A below. Our +// error recovery checks if A is a constructor declarator, and opens a +// TentativeParsingAction. Then we attempt to annotate the token at the exact +// position that we want to possibly backtrack to, and this used to crash. + +template class A {}; + +// expected-error@+1 {{expected '{' after base class list}} +template class B : T // not ',' or '{' +// expected-error@+3 {{C++ requires a type specifier for all declarations}} +// expected-error@+2 {{expected ';' after top level declarator}} +// expected-error@+1 {{expected ';' after class}} +A { +};