[clang][C++20] Fix clang/clangd assert/crash after compilation errors

After compilation errors, expression a transformation result may not be usable.
It triggers an assert in RemoveNestedImmediateInvocation and SIGSEGV in case of
builds without asserts. This issue significantly affects clangd because source
may not be valid during typing. Tests cases that I attached was reduce from huge
C++ translation unit.

Test Plan: check-clang

Differential Revision: https://reviews.llvm.org/D133948
This commit is contained in:
Dmitry Polukhin 2022-09-15 07:39:10 -07:00
parent 7914e53e31
commit 133b6d7db9
2 changed files with 18 additions and 3 deletions

View File

@ -17624,9 +17624,13 @@ static void RemoveNestedImmediateInvocation(
Transformer.AllowSkippingFirstCXXConstructExpr = false;
ExprResult Res = Transformer.TransformExpr(It->getPointer()->getSubExpr());
assert(Res.isUsable());
Res = SemaRef.MaybeCreateExprWithCleanups(Res);
It->getPointer()->setSubExpr(Res.get());
// The result may not be usable in case of previous compilation errors.
// In this case evaluation of the expression may result in crash so just
// don't do anything further with the result.
if (Res.isUsable()) {
Res = SemaRef.MaybeCreateExprWithCleanups(Res);
It->getPointer()->setSubExpr(Res.get());
}
}
static void

View File

@ -0,0 +1,11 @@
// RUN: not %clang_cc1 -fsyntax-only -verify -std=gnu++20 -ferror-limit 19 %s
// Creduced test case for the crash in RemoveNestedImmediateInvocation after compliation errros.
a, class b { template < typename c> consteval b(c
} template <typename...> using d = b;
auto e(d<>) -> int:;
}
f
}
g() {
auto h = "":(::i(e(h))