[sema] enhance error handling for compound stmt body in StmtExpr (#113760)

Mark the whole StmtExpr invalid when the last statement in compound
statement is invalid.
Because the last statement need to do copy initialization, it causes
subsequent errors to simply ignore last invalid statement.

Fixed: #113468
This commit is contained in:
Congcong Cai 2024-10-30 14:34:19 +08:00 committed by GitHub
parent 44d0e9522a
commit cad09404cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 22 additions and 0 deletions

View File

@ -470,6 +470,7 @@ Bug Fixes in This Version
- The warning emitted for an unsupported register variable type now points to - The warning emitted for an unsupported register variable type now points to
the unsupported type instead of the ``register`` keyword (#GH109776). the unsupported type instead of the ``register`` keyword (#GH109776).
- Fixed a crash when emit ctor for global variant with flexible array init (#GH113187). - Fixed a crash when emit ctor for global variant with flexible array init (#GH113187).
- Fixed a crash when GNU statement expression contains invalid statement (#GH113468).
Bug Fixes to Compiler Builtins Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1243,6 +1243,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
ParsedStmtContext::Compound | ParsedStmtContext::Compound |
(isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext()); (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
bool LastIsError = false;
while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
Tok.isNot(tok::eof)) { Tok.isNot(tok::eof)) {
if (Tok.is(tok::annot_pragma_unused)) { if (Tok.is(tok::annot_pragma_unused)) {
@ -1299,7 +1300,15 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
if (R.isUsable()) if (R.isUsable())
Stmts.push_back(R.get()); Stmts.push_back(R.get());
LastIsError = R.isInvalid();
} }
// StmtExpr needs to do copy initialization for last statement.
// If last statement is invalid, the last statement in `Stmts` will be
// incorrect. Then the whole compound statement should also be marked as
// invalid to prevent subsequent errors.
if (isStmtExpr && LastIsError && !Stmts.empty())
return StmtError();
// Warn the user that using option `-ffp-eval-method=source` on a // Warn the user that using option `-ffp-eval-method=source` on a
// 32-bit target and feature `sse` disabled, or using // 32-bit target and feature `sse` disabled, or using
// `pragma clang fp eval_method=source` and feature `sse` disabled, is not // `pragma clang fp eval_method=source` and feature `sse` disabled, is not

View File

@ -0,0 +1,12 @@
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
constexpr int expr() {
if (({
int f;
f = 0;
if (f)
break; // expected-error {{'break' statement not in loop or switch statement}}
}))
return 2;
return 1;
}