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-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7fea8003b3c904095b03f1ce1bac241c58a8fbb9;p=clang 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284777 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp index 4742aae5c1..ae07ea9bcf 100644 --- a/lib/Lex/PPCaching.cpp +++ b/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/test/Parser/backtrack-off-by-one.cpp b/test/Parser/backtrack-off-by-one.cpp new file mode 100644 index 0000000000..74b51cbb67 --- /dev/null +++ b/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 { +};