From cab3cfd013cf92c441c3acbfcc1844b267ab8659 Mon Sep 17 00:00:00 2001 From: Adam Czachorowski Date: Mon, 11 Jul 2022 17:29:12 +0200 Subject: [PATCH] [clang] Do not crash on "requires" after a fatal error occurred. The code would assume that SubstExpr() cannot fail on concept specialization. This is incorret - we give up on some things after fatal error occurred, since there's no value in doing futher work that the user will not see anyway. In this case, this lead to crash. The fatal error is simulated in tests with -ferror-limit=1, but this could happen in other cases too. Fixes https://github.com/llvm/llvm-project/issues/55401 Differential Revision: https://reviews.llvm.org/D129499 --- clang/lib/Sema/SemaExprCXX.cpp | 16 ++++++++-------- clang/test/SemaCXX/concept-fatal-error.cpp | 10 ++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 clang/test/SemaCXX/concept-fatal-error.cpp diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 11f33c7c6363..5331193de863 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -9006,14 +9006,14 @@ Sema::BuildExprRequirement( cast(TPL->getParam(0))->getTypeConstraint() ->getImmediatelyDeclaredConstraint(); ExprResult Constraint = SubstExpr(IDC, MLTAL); - assert(!Constraint.isInvalid() && - "Substitution cannot fail as it is simply putting a type template " - "argument into a concept specialization expression's parameter."); - - SubstitutedConstraintExpr = - cast(Constraint.get()); - if (!SubstitutedConstraintExpr->isSatisfied()) - Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied; + if (Constraint.isInvalid()) { + Status = concepts::ExprRequirement::SS_ExprSubstitutionFailure; + } else { + SubstitutedConstraintExpr = + cast(Constraint.get()); + if (!SubstitutedConstraintExpr->isSatisfied()) + Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied; + } } return new (Context) concepts::ExprRequirement(E, IsSimple, NoexceptLoc, ReturnTypeRequirement, Status, diff --git a/clang/test/SemaCXX/concept-fatal-error.cpp b/clang/test/SemaCXX/concept-fatal-error.cpp new file mode 100644 index 000000000000..c299b39fdeb2 --- /dev/null +++ b/clang/test/SemaCXX/concept-fatal-error.cpp @@ -0,0 +1,10 @@ +// RUN: not %clang_cc1 -fsyntax-only -std=c++20 -ferror-limit 1 -verify %s + +template +concept f = requires { 42; }; +struct h { + // The missing semicolon will trigger an error and -ferror-limit=1 will make it fatal + // We test that we do not crash in such cases (#55401) + int i = requires { { i } f } // expected-error {{expected ';' at end of declaration list}} + // expected-error@* {{too many errros emitted}} +};