[clang] 98ea471 - Properly Propagate RecoveryExpr through RequiresExpr
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 29 09:05:05 PDT 2023
Author: Erich Keane
Date: 2023-03-29T09:04:59-07:00
New Revision: 98ea4712828b0802c99b3e8a6808cdc908f5b5b9
URL: https://github.com/llvm/llvm-project/commit/98ea4712828b0802c99b3e8a6808cdc908f5b5b9
DIFF: https://github.com/llvm/llvm-project/commit/98ea4712828b0802c99b3e8a6808cdc908f5b5b9.diff
LOG: Properly Propagate RecoveryExpr through RequiresExpr
Commit 3d7946c58 implemented a DR that allowed us to error in a case
where an ill-formedness in a RequiresExpr is diagnosed as a satisfaction
failure. However, it failed to cover cases where the RequiresExpr had
Requirements that failed for similar reasons.
This patch propagates the RecoveryExpr "containsErrors" correctly
through RequiresExpr.
Fixes: #61776
Added:
Modified:
clang/lib/AST/ExprConcepts.cpp
clang/test/CXX/drs/dr25xx.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp
index fc8f1eb2abf14..a8a35d73815f9 100644
--- a/clang/lib/AST/ExprConcepts.cpp
+++ b/clang/lib/AST/ExprConcepts.cpp
@@ -112,6 +112,19 @@ concepts::ExprRequirement::ReturnTypeRequirement::getTypeConstraint() const {
->getTypeConstraint();
}
+// Search through the requirements, and see if any have a RecoveryExpr in it,
+// which means this RequiresExpr ALSO needs to be invalid.
+static bool RequirementContainsError(concepts::Requirement *R) {
+ if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R))
+ return ExprReq->getExpr() && ExprReq->getExpr()->containsErrors();
+
+ if (auto *NestedReq = dyn_cast<concepts::NestedRequirement>(R))
+ return !NestedReq->hasInvalidConstraint() &&
+ NestedReq->getConstraintExpr() &&
+ NestedReq->getConstraintExpr()->containsErrors();
+ return false;
+}
+
RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
RequiresExprBodyDecl *Body,
ArrayRef<ParmVarDecl *> LocalParameters,
@@ -138,6 +151,9 @@ RequiresExpr::RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
if (!RequiresExprBits.IsSatisfied)
break;
}
+
+ if (RequirementContainsError(R))
+ setDependence(getDependence() | ExprDependence::Error);
}
std::copy(LocalParameters.begin(), LocalParameters.end(),
getTrailingObjects<ParmVarDecl *>());
diff --git a/clang/test/CXX/drs/dr25xx.cpp b/clang/test/CXX/drs/dr25xx.cpp
index 0800adda63928..28ebda22a8017 100644
--- a/clang/test/CXX/drs/dr25xx.cpp
+++ b/clang/test/CXX/drs/dr25xx.cpp
@@ -75,4 +75,25 @@ namespace dr2565 { // dr2565: 16 open
// expected-error at -1{{constraints not satisfied for class template 'VariadicStruct'}}
// expected-note@#VSREQ{{because 'Variadic<void, int, char, double>' evaluated to false}}
// expected-note@#VC{{because 'b' would be invalid: argument may not have 'void' type}}
+
+ template<typename T>
+ // expected-error at +1 {{unknown type name 'ErrorRequires'}}
+ concept ErrorRequires = requires (ErrorRequires auto x) {
+ x;
+ };
+ static_assert(ErrorRequires<int>);
+ // expected-error at -1{{static assertion failed}}
+ // expected-note at -2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
+
+ template<typename T>
+ // expected-error at +2 {{unknown type name 'NestedErrorInRequires'}}
+ concept NestedErrorInRequires = requires (T x) {
+ requires requires (NestedErrorInRequires auto y) {
+ y;
+ };
+ };
+ static_assert(NestedErrorInRequires<int>);
+ // expected-error at -1{{static assertion failed}}
+ // expected-note at -2{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
+
}
More information about the cfe-commits
mailing list