Author: Adam Czachorowski
Date: 2022-07-14T15:45:32+02:00
New Revision: cab3cfd013cf92c441c3acbfcc1844b267ab8659

URL: 
https://github.com/llvm/llvm-project/commit/cab3cfd013cf92c441c3acbfcc1844b267ab8659
DIFF: 
https://github.com/llvm/llvm-project/commit/cab3cfd013cf92c441c3acbfcc1844b267ab8659.diff

LOG: [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

Added: 
    clang/test/SemaCXX/concept-fatal-error.cpp

Modified: 
    clang/lib/Sema/SemaExprCXX.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 11f33c7c63633..5331193de863d 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -9006,14 +9006,14 @@ Sema::BuildExprRequirement(
         cast<TemplateTypeParmDecl>(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<ConceptSpecializationExpr>(Constraint.get());
-    if (!SubstitutedConstraintExpr->isSatisfied())
-      Status = concepts::ExprRequirement::SS_ConstraintsNotSatisfied;
+    if (Constraint.isInvalid()) {
+      Status = concepts::ExprRequirement::SS_ExprSubstitutionFailure;
+    } else {
+      SubstitutedConstraintExpr =
+          cast<ConceptSpecializationExpr>(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 0000000000000..c299b39fdeb23
--- /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 <class>
+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}}
+};


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to