Index: lib/Parse/ParseExprCXX.cpp =================================================================== --- lib/Parse/ParseExprCXX.cpp +++ lib/Parse/ParseExprCXX.cpp @@ -3083,10 +3083,17 @@ // The current token should go after the cached tokens. Toks.push_back(Tok); + + // Make a copy of stored token to pass ownership to EnterTokenStream function. + // This copy is required because we may exit from this function when some + // tokens are not consumed yet. + Token *Buffer = new Token[Toks.size()]; + std::copy(Toks.begin(), Toks.end(), Buffer); + // Re-enter the stored parenthesized tokens into the token stream, so we may // parse them now. - PP.EnterTokenStream(Toks.data(), Toks.size(), - true/*DisableMacroExpansion*/, false/*OwnsTokens*/); + PP.EnterTokenStream(Buffer, Toks.size(), + true/*DisableMacroExpansion*/, true/*OwnsTokens*/); // Drop the current token and bring the first cached one. It's the same token // as when we entered this function. ConsumeAnyToken(); Index: test/Parser/cxx-ambig-paren-expr-asan.cpp =================================================================== --- /dev/null +++ test/Parser/cxx-ambig-paren-expr-asan.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s + +// This syntax error used to cause use-after free due to token local buffer +// in ParseCXXAmbiguousParenExpression. +int H((int()[)]); +// expected-error@-1 {{expected expression}} +// expected-error@-2 {{expected ']'}} +// expected-note@-3 {{to match this '['}}