1 //===-- SemaConcept.cpp - Semantic Analysis for Constraints and Concepts --===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements semantic analysis for C++ constraints and concepts. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/Sema/SemaConcept.h" 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTLambda.h" 16 #include "clang/AST/DeclCXX.h" 17 #include "clang/AST/ExprConcepts.h" 18 #include "clang/AST/RecursiveASTVisitor.h" 19 #include "clang/Basic/OperatorPrecedence.h" 20 #include "clang/Sema/EnterExpressionEvaluationContext.h" 21 #include "clang/Sema/Initialization.h" 22 #include "clang/Sema/Overload.h" 23 #include "clang/Sema/ScopeInfo.h" 24 #include "clang/Sema/Sema.h" 25 #include "clang/Sema/SemaDiagnostic.h" 26 #include "clang/Sema/SemaInternal.h" 27 #include "clang/Sema/Template.h" 28 #include "clang/Sema/TemplateDeduction.h" 29 #include "llvm/ADT/DenseMap.h" 30 #include "llvm/ADT/PointerUnion.h" 31 #include "llvm/ADT/StringExtras.h" 32 #include <optional> 33 34 using namespace clang; 35 using namespace sema; 36 37 namespace { 38 class LogicalBinOp { 39 SourceLocation Loc; 40 OverloadedOperatorKind Op = OO_None; 41 const Expr *LHS = nullptr; 42 const Expr *RHS = nullptr; 43 44 public: 45 LogicalBinOp(const Expr *E) { 46 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 47 Op = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 48 LHS = BO->getLHS(); 49 RHS = BO->getRHS(); 50 Loc = BO->getExprLoc(); 51 } else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) { 52 // If OO is not || or && it might not have exactly 2 arguments. 53 if (OO->getNumArgs() == 2) { 54 Op = OO->getOperator(); 55 LHS = OO->getArg(0); 56 RHS = OO->getArg(1); 57 Loc = OO->getOperatorLoc(); 58 } 59 } 60 } 61 62 bool isAnd() const { return Op == OO_AmpAmp; } 63 bool isOr() const { return Op == OO_PipePipe; } 64 explicit operator bool() const { return isAnd() || isOr(); } 65 66 const Expr *getLHS() const { return LHS; } 67 const Expr *getRHS() const { return RHS; } 68 69 ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS) const { 70 return recreateBinOp(SemaRef, LHS, const_cast<Expr *>(getRHS())); 71 } 72 73 ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS, 74 ExprResult RHS) const { 75 assert((isAnd() || isOr()) && "Not the right kind of op?"); 76 assert((!LHS.isInvalid() && !RHS.isInvalid()) && "not good expressions?"); 77 78 if (!LHS.isUsable() || !RHS.isUsable()) 79 return ExprEmpty(); 80 81 // We should just be able to 'normalize' these to the builtin Binary 82 // Operator, since that is how they are evaluated in constriant checks. 83 return BinaryOperator::Create(SemaRef.Context, LHS.get(), RHS.get(), 84 BinaryOperator::getOverloadedOpcode(Op), 85 SemaRef.Context.BoolTy, VK_PRValue, 86 OK_Ordinary, Loc, FPOptionsOverride{}); 87 } 88 }; 89 } 90 91 bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression, 92 Token NextToken, bool *PossibleNonPrimary, 93 bool IsTrailingRequiresClause) { 94 // C++2a [temp.constr.atomic]p1 95 // ..E shall be a constant expression of type bool. 96 97 ConstraintExpression = ConstraintExpression->IgnoreParenImpCasts(); 98 99 if (LogicalBinOp BO = ConstraintExpression) { 100 return CheckConstraintExpression(BO.getLHS(), NextToken, 101 PossibleNonPrimary) && 102 CheckConstraintExpression(BO.getRHS(), NextToken, 103 PossibleNonPrimary); 104 } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression)) 105 return CheckConstraintExpression(C->getSubExpr(), NextToken, 106 PossibleNonPrimary); 107 108 QualType Type = ConstraintExpression->getType(); 109 110 auto CheckForNonPrimary = [&] { 111 if (!PossibleNonPrimary) 112 return; 113 114 *PossibleNonPrimary = 115 // We have the following case: 116 // template<typename> requires func(0) struct S { }; 117 // The user probably isn't aware of the parentheses required around 118 // the function call, and we're only going to parse 'func' as the 119 // primary-expression, and complain that it is of non-bool type. 120 // 121 // However, if we're in a lambda, this might also be: 122 // []<typename> requires var () {}; 123 // Which also looks like a function call due to the lambda parentheses, 124 // but unlike the first case, isn't an error, so this check is skipped. 125 (NextToken.is(tok::l_paren) && 126 (IsTrailingRequiresClause || 127 (Type->isDependentType() && 128 isa<UnresolvedLookupExpr>(ConstraintExpression) && 129 !dyn_cast_if_present<LambdaScopeInfo>(getCurFunction())) || 130 Type->isFunctionType() || 131 Type->isSpecificBuiltinType(BuiltinType::Overload))) || 132 // We have the following case: 133 // template<typename T> requires size_<T> == 0 struct S { }; 134 // The user probably isn't aware of the parentheses required around 135 // the binary operator, and we're only going to parse 'func' as the 136 // first operand, and complain that it is of non-bool type. 137 getBinOpPrecedence(NextToken.getKind(), 138 /*GreaterThanIsOperator=*/true, 139 getLangOpts().CPlusPlus11) > prec::LogicalAnd; 140 }; 141 142 // An atomic constraint! 143 if (ConstraintExpression->isTypeDependent()) { 144 CheckForNonPrimary(); 145 return true; 146 } 147 148 if (!Context.hasSameUnqualifiedType(Type, Context.BoolTy)) { 149 Diag(ConstraintExpression->getExprLoc(), 150 diag::err_non_bool_atomic_constraint) << Type 151 << ConstraintExpression->getSourceRange(); 152 CheckForNonPrimary(); 153 return false; 154 } 155 156 if (PossibleNonPrimary) 157 *PossibleNonPrimary = false; 158 return true; 159 } 160 161 namespace { 162 struct SatisfactionStackRAII { 163 Sema &SemaRef; 164 bool Inserted = false; 165 SatisfactionStackRAII(Sema &SemaRef, const NamedDecl *ND, 166 const llvm::FoldingSetNodeID &FSNID) 167 : SemaRef(SemaRef) { 168 if (ND) { 169 SemaRef.PushSatisfactionStackEntry(ND, FSNID); 170 Inserted = true; 171 } 172 } 173 ~SatisfactionStackRAII() { 174 if (Inserted) 175 SemaRef.PopSatisfactionStackEntry(); 176 } 177 }; 178 } // namespace 179 180 template <typename AtomicEvaluator> 181 static ExprResult 182 calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr, 183 ConstraintSatisfaction &Satisfaction, 184 AtomicEvaluator &&Evaluator) { 185 ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts(); 186 187 if (LogicalBinOp BO = ConstraintExpr) { 188 size_t EffectiveDetailEndIndex = Satisfaction.Details.size(); 189 ExprResult LHSRes = calculateConstraintSatisfaction( 190 S, BO.getLHS(), Satisfaction, Evaluator); 191 192 if (LHSRes.isInvalid()) 193 return ExprError(); 194 195 bool IsLHSSatisfied = Satisfaction.IsSatisfied; 196 197 if (BO.isOr() && IsLHSSatisfied) 198 // [temp.constr.op] p3 199 // A disjunction is a constraint taking two operands. To determine if 200 // a disjunction is satisfied, the satisfaction of the first operand 201 // is checked. If that is satisfied, the disjunction is satisfied. 202 // Otherwise, the disjunction is satisfied if and only if the second 203 // operand is satisfied. 204 // LHS is instantiated while RHS is not. Skip creating invalid BinaryOp. 205 return LHSRes; 206 207 if (BO.isAnd() && !IsLHSSatisfied) 208 // [temp.constr.op] p2 209 // A conjunction is a constraint taking two operands. To determine if 210 // a conjunction is satisfied, the satisfaction of the first operand 211 // is checked. If that is not satisfied, the conjunction is not 212 // satisfied. Otherwise, the conjunction is satisfied if and only if 213 // the second operand is satisfied. 214 // LHS is instantiated while RHS is not. Skip creating invalid BinaryOp. 215 return LHSRes; 216 217 ExprResult RHSRes = calculateConstraintSatisfaction( 218 S, BO.getRHS(), Satisfaction, std::forward<AtomicEvaluator>(Evaluator)); 219 if (RHSRes.isInvalid()) 220 return ExprError(); 221 222 bool IsRHSSatisfied = Satisfaction.IsSatisfied; 223 // Current implementation adds diagnostic information about the falsity 224 // of each false atomic constraint expression when it evaluates them. 225 // When the evaluation results to `false || true`, the information 226 // generated during the evaluation of left-hand side is meaningless 227 // because the whole expression evaluates to true. 228 // The following code removes the irrelevant diagnostic information. 229 // FIXME: We should probably delay the addition of diagnostic information 230 // until we know the entire expression is false. 231 if (BO.isOr() && IsRHSSatisfied) { 232 auto EffectiveDetailEnd = Satisfaction.Details.begin(); 233 std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex); 234 Satisfaction.Details.erase(EffectiveDetailEnd, 235 Satisfaction.Details.end()); 236 } 237 238 return BO.recreateBinOp(S, LHSRes, RHSRes); 239 } 240 241 if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) { 242 // These aren't evaluated, so we don't care about cleanups, so we can just 243 // evaluate these as if the cleanups didn't exist. 244 return calculateConstraintSatisfaction( 245 S, C->getSubExpr(), Satisfaction, 246 std::forward<AtomicEvaluator>(Evaluator)); 247 } 248 249 // An atomic constraint expression 250 ExprResult SubstitutedAtomicExpr = Evaluator(ConstraintExpr); 251 252 if (SubstitutedAtomicExpr.isInvalid()) 253 return ExprError(); 254 255 if (!SubstitutedAtomicExpr.isUsable()) 256 // Evaluator has decided satisfaction without yielding an expression. 257 return ExprEmpty(); 258 259 // We don't have the ability to evaluate this, since it contains a 260 // RecoveryExpr, so we want to fail overload resolution. Otherwise, 261 // we'd potentially pick up a different overload, and cause confusing 262 // diagnostics. SO, add a failure detail that will cause us to make this 263 // overload set not viable. 264 if (SubstitutedAtomicExpr.get()->containsErrors()) { 265 Satisfaction.IsSatisfied = false; 266 Satisfaction.ContainsErrors = true; 267 268 PartialDiagnostic Msg = S.PDiag(diag::note_constraint_references_error); 269 SmallString<128> DiagString; 270 DiagString = ": "; 271 Msg.EmitToString(S.getDiagnostics(), DiagString); 272 unsigned MessageSize = DiagString.size(); 273 char *Mem = new (S.Context) char[MessageSize]; 274 memcpy(Mem, DiagString.c_str(), MessageSize); 275 Satisfaction.Details.emplace_back( 276 ConstraintExpr, 277 new (S.Context) ConstraintSatisfaction::SubstitutionDiagnostic{ 278 SubstitutedAtomicExpr.get()->getBeginLoc(), 279 StringRef(Mem, MessageSize)}); 280 return SubstitutedAtomicExpr; 281 } 282 283 EnterExpressionEvaluationContext ConstantEvaluated( 284 S, Sema::ExpressionEvaluationContext::ConstantEvaluated); 285 SmallVector<PartialDiagnosticAt, 2> EvaluationDiags; 286 Expr::EvalResult EvalResult; 287 EvalResult.Diag = &EvaluationDiags; 288 if (!SubstitutedAtomicExpr.get()->EvaluateAsConstantExpr(EvalResult, 289 S.Context) || 290 !EvaluationDiags.empty()) { 291 // C++2a [temp.constr.atomic]p1 292 // ...E shall be a constant expression of type bool. 293 S.Diag(SubstitutedAtomicExpr.get()->getBeginLoc(), 294 diag::err_non_constant_constraint_expression) 295 << SubstitutedAtomicExpr.get()->getSourceRange(); 296 for (const PartialDiagnosticAt &PDiag : EvaluationDiags) 297 S.Diag(PDiag.first, PDiag.second); 298 return ExprError(); 299 } 300 301 assert(EvalResult.Val.isInt() && 302 "evaluating bool expression didn't produce int"); 303 Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue(); 304 if (!Satisfaction.IsSatisfied) 305 Satisfaction.Details.emplace_back(ConstraintExpr, 306 SubstitutedAtomicExpr.get()); 307 308 return SubstitutedAtomicExpr; 309 } 310 311 static bool 312 DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, 313 const NamedDecl *Templ, const Expr *E, 314 const MultiLevelTemplateArgumentList &MLTAL) { 315 E->Profile(ID, S.Context, /*Canonical=*/true); 316 for (const auto &List : MLTAL) 317 for (const auto &TemplateArg : List.Args) 318 TemplateArg.Profile(ID, S.Context); 319 320 // Note that we have to do this with our own collection, because there are 321 // times where a constraint-expression check can cause us to need to evaluate 322 // other constriants that are unrelated, such as when evaluating a recovery 323 // expression, or when trying to determine the constexpr-ness of special 324 // members. Otherwise we could just use the 325 // Sema::InstantiatingTemplate::isAlreadyBeingInstantiated function. 326 if (S.SatisfactionStackContains(Templ, ID)) { 327 S.Diag(E->getExprLoc(), diag::err_constraint_depends_on_self) 328 << const_cast<Expr *>(E) << E->getSourceRange(); 329 return true; 330 } 331 332 return false; 333 } 334 335 static ExprResult calculateConstraintSatisfaction( 336 Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc, 337 const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr, 338 ConstraintSatisfaction &Satisfaction) { 339 return calculateConstraintSatisfaction( 340 S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) { 341 EnterExpressionEvaluationContext ConstantEvaluated( 342 S, Sema::ExpressionEvaluationContext::ConstantEvaluated, 343 Sema::ReuseLambdaContextDecl); 344 345 // Atomic constraint - substitute arguments and check satisfaction. 346 ExprResult SubstitutedExpression; 347 { 348 TemplateDeductionInfo Info(TemplateNameLoc); 349 Sema::InstantiatingTemplate Inst(S, AtomicExpr->getBeginLoc(), 350 Sema::InstantiatingTemplate::ConstraintSubstitution{}, 351 const_cast<NamedDecl *>(Template), Info, 352 AtomicExpr->getSourceRange()); 353 if (Inst.isInvalid()) 354 return ExprError(); 355 356 llvm::FoldingSetNodeID ID; 357 if (Template && 358 DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, MLTAL)) { 359 Satisfaction.IsSatisfied = false; 360 Satisfaction.ContainsErrors = true; 361 return ExprEmpty(); 362 } 363 364 SatisfactionStackRAII StackRAII(S, Template, ID); 365 366 // We do not want error diagnostics escaping here. 367 Sema::SFINAETrap Trap(S); 368 SubstitutedExpression = 369 S.SubstConstraintExpr(const_cast<Expr *>(AtomicExpr), MLTAL); 370 371 if (SubstitutedExpression.isInvalid() || Trap.hasErrorOccurred()) { 372 // C++2a [temp.constr.atomic]p1 373 // ...If substitution results in an invalid type or expression, the 374 // constraint is not satisfied. 375 if (!Trap.hasErrorOccurred()) 376 // A non-SFINAE error has occurred as a result of this 377 // substitution. 378 return ExprError(); 379 380 PartialDiagnosticAt SubstDiag{SourceLocation(), 381 PartialDiagnostic::NullDiagnostic()}; 382 Info.takeSFINAEDiagnostic(SubstDiag); 383 // FIXME: Concepts: This is an unfortunate consequence of there 384 // being no serialization code for PartialDiagnostics and the fact 385 // that serializing them would likely take a lot more storage than 386 // just storing them as strings. We would still like, in the 387 // future, to serialize the proper PartialDiagnostic as serializing 388 // it as a string defeats the purpose of the diagnostic mechanism. 389 SmallString<128> DiagString; 390 DiagString = ": "; 391 SubstDiag.second.EmitToString(S.getDiagnostics(), DiagString); 392 unsigned MessageSize = DiagString.size(); 393 char *Mem = new (S.Context) char[MessageSize]; 394 memcpy(Mem, DiagString.c_str(), MessageSize); 395 Satisfaction.Details.emplace_back( 396 AtomicExpr, 397 new (S.Context) ConstraintSatisfaction::SubstitutionDiagnostic{ 398 SubstDiag.first, StringRef(Mem, MessageSize)}); 399 Satisfaction.IsSatisfied = false; 400 return ExprEmpty(); 401 } 402 } 403 404 if (!S.CheckConstraintExpression(SubstitutedExpression.get())) 405 return ExprError(); 406 407 // [temp.constr.atomic]p3: To determine if an atomic constraint is 408 // satisfied, the parameter mapping and template arguments are first 409 // substituted into its expression. If substitution results in an 410 // invalid type or expression, the constraint is not satisfied. 411 // Otherwise, the lvalue-to-rvalue conversion is performed if necessary, 412 // and E shall be a constant expression of type bool. 413 // 414 // Perform the L to R Value conversion if necessary. We do so for all 415 // non-PRValue categories, else we fail to extend the lifetime of 416 // temporaries, and that fails the constant expression check. 417 if (!SubstitutedExpression.get()->isPRValue()) 418 SubstitutedExpression = ImplicitCastExpr::Create( 419 S.Context, SubstitutedExpression.get()->getType(), 420 CK_LValueToRValue, SubstitutedExpression.get(), 421 /*BasePath=*/nullptr, VK_PRValue, FPOptionsOverride()); 422 423 return SubstitutedExpression; 424 }); 425 } 426 427 static bool CheckConstraintSatisfaction( 428 Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, 429 llvm::SmallVectorImpl<Expr *> &Converted, 430 const MultiLevelTemplateArgumentList &TemplateArgsLists, 431 SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) { 432 if (ConstraintExprs.empty()) { 433 Satisfaction.IsSatisfied = true; 434 return false; 435 } 436 437 if (TemplateArgsLists.isAnyArgInstantiationDependent()) { 438 // No need to check satisfaction for dependent constraint expressions. 439 Satisfaction.IsSatisfied = true; 440 return false; 441 } 442 443 ArrayRef<TemplateArgument> TemplateArgs = 444 TemplateArgsLists.getNumSubstitutedLevels() > 0 445 ? TemplateArgsLists.getOutermost() 446 : ArrayRef<TemplateArgument> {}; 447 Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(), 448 Sema::InstantiatingTemplate::ConstraintsCheck{}, 449 const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange); 450 if (Inst.isInvalid()) 451 return true; 452 453 for (const Expr *ConstraintExpr : ConstraintExprs) { 454 ExprResult Res = calculateConstraintSatisfaction( 455 S, Template, TemplateIDRange.getBegin(), TemplateArgsLists, 456 ConstraintExpr, Satisfaction); 457 if (Res.isInvalid()) 458 return true; 459 460 Converted.push_back(Res.get()); 461 if (!Satisfaction.IsSatisfied) { 462 // Backfill the 'converted' list with nulls so we can keep the Converted 463 // and unconverted lists in sync. 464 Converted.append(ConstraintExprs.size() - Converted.size(), nullptr); 465 // [temp.constr.op] p2 466 // [...] To determine if a conjunction is satisfied, the satisfaction 467 // of the first operand is checked. If that is not satisfied, the 468 // conjunction is not satisfied. [...] 469 return false; 470 } 471 } 472 return false; 473 } 474 475 bool Sema::CheckConstraintSatisfaction( 476 const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, 477 llvm::SmallVectorImpl<Expr *> &ConvertedConstraints, 478 const MultiLevelTemplateArgumentList &TemplateArgsLists, 479 SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) { 480 if (ConstraintExprs.empty()) { 481 OutSatisfaction.IsSatisfied = true; 482 return false; 483 } 484 if (!Template) { 485 return ::CheckConstraintSatisfaction( 486 *this, nullptr, ConstraintExprs, ConvertedConstraints, 487 TemplateArgsLists, TemplateIDRange, OutSatisfaction); 488 } 489 490 // A list of the template argument list flattened in a predictible manner for 491 // the purposes of caching. The ConstraintSatisfaction type is in AST so it 492 // has no access to the MultiLevelTemplateArgumentList, so this has to happen 493 // here. 494 llvm::SmallVector<TemplateArgument, 4> FlattenedArgs; 495 for (auto List : TemplateArgsLists) 496 FlattenedArgs.insert(FlattenedArgs.end(), List.Args.begin(), 497 List.Args.end()); 498 499 llvm::FoldingSetNodeID ID; 500 ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs); 501 void *InsertPos; 502 if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) { 503 OutSatisfaction = *Cached; 504 return false; 505 } 506 507 auto Satisfaction = 508 std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs); 509 if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs, 510 ConvertedConstraints, TemplateArgsLists, 511 TemplateIDRange, *Satisfaction)) { 512 OutSatisfaction = *Satisfaction; 513 return true; 514 } 515 516 if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) { 517 // The evaluation of this constraint resulted in us trying to re-evaluate it 518 // recursively. This isn't really possible, except we try to form a 519 // RecoveryExpr as a part of the evaluation. If this is the case, just 520 // return the 'cached' version (which will have the same result), and save 521 // ourselves the extra-insert. If it ever becomes possible to legitimately 522 // recursively check a constraint, we should skip checking the 'inner' one 523 // above, and replace the cached version with this one, as it would be more 524 // specific. 525 OutSatisfaction = *Cached; 526 return false; 527 } 528 529 // Else we can simply add this satisfaction to the list. 530 OutSatisfaction = *Satisfaction; 531 // We cannot use InsertPos here because CheckConstraintSatisfaction might have 532 // invalidated it. 533 // Note that entries of SatisfactionCache are deleted in Sema's destructor. 534 SatisfactionCache.InsertNode(Satisfaction.release()); 535 return false; 536 } 537 538 bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr, 539 ConstraintSatisfaction &Satisfaction) { 540 return calculateConstraintSatisfaction( 541 *this, ConstraintExpr, Satisfaction, 542 [this](const Expr *AtomicExpr) -> ExprResult { 543 // We only do this to immitate lvalue-to-rvalue conversion. 544 return PerformContextuallyConvertToBool( 545 const_cast<Expr *>(AtomicExpr)); 546 }) 547 .isInvalid(); 548 } 549 550 bool Sema::addInstantiatedCapturesToScope( 551 FunctionDecl *Function, const FunctionDecl *PatternDecl, 552 LocalInstantiationScope &Scope, 553 const MultiLevelTemplateArgumentList &TemplateArgs) { 554 const auto *LambdaClass = cast<CXXMethodDecl>(Function)->getParent(); 555 const auto *LambdaPattern = cast<CXXMethodDecl>(PatternDecl)->getParent(); 556 557 unsigned Instantiated = 0; 558 559 auto AddSingleCapture = [&](const ValueDecl *CapturedPattern, 560 unsigned Index) { 561 ValueDecl *CapturedVar = LambdaClass->getCapture(Index)->getCapturedVar(); 562 if (CapturedVar->isInitCapture()) 563 Scope.InstantiatedLocal(CapturedPattern, CapturedVar); 564 }; 565 566 for (const LambdaCapture &CapturePattern : LambdaPattern->captures()) { 567 if (!CapturePattern.capturesVariable()) { 568 Instantiated++; 569 continue; 570 } 571 const ValueDecl *CapturedPattern = CapturePattern.getCapturedVar(); 572 if (!CapturedPattern->isParameterPack()) { 573 AddSingleCapture(CapturedPattern, Instantiated++); 574 } else { 575 Scope.MakeInstantiatedLocalArgPack(CapturedPattern); 576 std::optional<unsigned> NumArgumentsInExpansion = 577 getNumArgumentsInExpansion(CapturedPattern->getType(), TemplateArgs); 578 if (!NumArgumentsInExpansion) 579 continue; 580 for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) 581 AddSingleCapture(CapturedPattern, Instantiated++); 582 } 583 } 584 return false; 585 } 586 587 bool Sema::SetupConstraintScope( 588 FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs, 589 MultiLevelTemplateArgumentList MLTAL, LocalInstantiationScope &Scope) { 590 if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) { 591 FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate(); 592 InstantiatingTemplate Inst( 593 *this, FD->getPointOfInstantiation(), 594 Sema::InstantiatingTemplate::ConstraintsCheck{}, PrimaryTemplate, 595 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{}, 596 SourceRange()); 597 if (Inst.isInvalid()) 598 return true; 599 600 // addInstantiatedParametersToScope creates a map of 'uninstantiated' to 601 // 'instantiated' parameters and adds it to the context. For the case where 602 // this function is a template being instantiated NOW, we also need to add 603 // the list of current template arguments to the list so that they also can 604 // be picked out of the map. 605 if (auto *SpecArgs = FD->getTemplateSpecializationArgs()) { 606 MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(), 607 /*Final=*/false); 608 if (addInstantiatedParametersToScope( 609 FD, PrimaryTemplate->getTemplatedDecl(), Scope, JustTemplArgs)) 610 return true; 611 } 612 613 // If this is a member function, make sure we get the parameters that 614 // reference the original primary template. 615 // We walk up the instantiated template chain so that nested lambdas get 616 // handled properly. 617 for (FunctionTemplateDecl *FromMemTempl = 618 PrimaryTemplate->getInstantiatedFromMemberTemplate(); 619 FromMemTempl; 620 FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate()) { 621 if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(), 622 Scope, MLTAL)) 623 return true; 624 } 625 626 return false; 627 } 628 629 if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization || 630 FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) { 631 FunctionDecl *InstantiatedFrom = 632 FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization 633 ? FD->getInstantiatedFromMemberFunction() 634 : FD->getInstantiatedFromDecl(); 635 636 InstantiatingTemplate Inst( 637 *this, FD->getPointOfInstantiation(), 638 Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom, 639 TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{}, 640 SourceRange()); 641 if (Inst.isInvalid()) 642 return true; 643 644 // Case where this was not a template, but instantiated as a 645 // child-function. 646 if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL)) 647 return true; 648 } 649 650 return false; 651 } 652 653 // This function collects all of the template arguments for the purposes of 654 // constraint-instantiation and checking. 655 std::optional<MultiLevelTemplateArgumentList> 656 Sema::SetupConstraintCheckingTemplateArgumentsAndScope( 657 FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs, 658 LocalInstantiationScope &Scope) { 659 MultiLevelTemplateArgumentList MLTAL; 660 661 // Collect the list of template arguments relative to the 'primary' template. 662 // We need the entire list, since the constraint is completely uninstantiated 663 // at this point. 664 MLTAL = getTemplateInstantiationArgs(FD, FD->getLexicalDeclContext(), 665 /*Final=*/false, /*Innermost=*/nullptr, 666 /*RelativeToPrimary=*/true, 667 /*Pattern=*/nullptr, 668 /*ForConstraintInstantiation=*/true); 669 if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope)) 670 return std::nullopt; 671 672 return MLTAL; 673 } 674 675 bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, 676 ConstraintSatisfaction &Satisfaction, 677 SourceLocation UsageLoc, 678 bool ForOverloadResolution) { 679 // Don't check constraints if the function is dependent. Also don't check if 680 // this is a function template specialization, as the call to 681 // CheckinstantiatedFunctionTemplateConstraints after this will check it 682 // better. 683 if (FD->isDependentContext() || 684 FD->getTemplatedKind() == 685 FunctionDecl::TK_FunctionTemplateSpecialization) { 686 Satisfaction.IsSatisfied = true; 687 return false; 688 } 689 690 // A lambda conversion operator has the same constraints as the call operator 691 // and constraints checking relies on whether we are in a lambda call operator 692 // (and may refer to its parameters), so check the call operator instead. 693 if (const auto *MD = dyn_cast<CXXConversionDecl>(FD); 694 MD && isLambdaConversionOperator(const_cast<CXXConversionDecl *>(MD))) 695 return CheckFunctionConstraints(MD->getParent()->getLambdaCallOperator(), 696 Satisfaction, UsageLoc, 697 ForOverloadResolution); 698 699 DeclContext *CtxToSave = const_cast<FunctionDecl *>(FD); 700 701 while (isLambdaCallOperator(CtxToSave) || FD->isTransparentContext()) { 702 if (isLambdaCallOperator(CtxToSave)) 703 CtxToSave = CtxToSave->getParent()->getParent(); 704 else 705 CtxToSave = CtxToSave->getNonTransparentContext(); 706 } 707 708 ContextRAII SavedContext{*this, CtxToSave}; 709 LocalInstantiationScope Scope(*this, !ForOverloadResolution); 710 std::optional<MultiLevelTemplateArgumentList> MLTAL = 711 SetupConstraintCheckingTemplateArgumentsAndScope( 712 const_cast<FunctionDecl *>(FD), {}, Scope); 713 714 if (!MLTAL) 715 return true; 716 717 Qualifiers ThisQuals; 718 CXXRecordDecl *Record = nullptr; 719 if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) { 720 ThisQuals = Method->getMethodQualifiers(); 721 Record = const_cast<CXXRecordDecl *>(Method->getParent()); 722 } 723 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); 724 725 LambdaScopeForCallOperatorInstantiationRAII LambdaScope( 726 *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope, 727 ForOverloadResolution); 728 729 return CheckConstraintSatisfaction( 730 FD, {FD->getTrailingRequiresClause()}, *MLTAL, 731 SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()), 732 Satisfaction); 733 } 734 735 736 // Figure out the to-translation-unit depth for this function declaration for 737 // the purpose of seeing if they differ by constraints. This isn't the same as 738 // getTemplateDepth, because it includes already instantiated parents. 739 static unsigned 740 CalculateTemplateDepthForConstraints(Sema &S, const NamedDecl *ND, 741 bool SkipForSpecialization = false) { 742 MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs( 743 ND, ND->getLexicalDeclContext(), /*Final=*/false, /*Innermost=*/nullptr, 744 /*RelativeToPrimary=*/true, 745 /*Pattern=*/nullptr, 746 /*ForConstraintInstantiation=*/true, SkipForSpecialization); 747 return MLTAL.getNumLevels(); 748 } 749 750 namespace { 751 class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> { 752 unsigned TemplateDepth = 0; 753 public: 754 using inherited = TreeTransform<AdjustConstraintDepth>; 755 AdjustConstraintDepth(Sema &SemaRef, unsigned TemplateDepth) 756 : inherited(SemaRef), TemplateDepth(TemplateDepth) {} 757 758 using inherited::TransformTemplateTypeParmType; 759 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB, 760 TemplateTypeParmTypeLoc TL, bool) { 761 const TemplateTypeParmType *T = TL.getTypePtr(); 762 763 TemplateTypeParmDecl *NewTTPDecl = nullptr; 764 if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl()) 765 NewTTPDecl = cast_or_null<TemplateTypeParmDecl>( 766 TransformDecl(TL.getNameLoc(), OldTTPDecl)); 767 768 QualType Result = getSema().Context.getTemplateTypeParmType( 769 T->getDepth() + TemplateDepth, T->getIndex(), T->isParameterPack(), 770 NewTTPDecl); 771 TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result); 772 NewTL.setNameLoc(TL.getNameLoc()); 773 return Result; 774 } 775 }; 776 } // namespace 777 778 static const Expr *SubstituteConstraintExpressionWithoutSatisfaction( 779 Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo, 780 const Expr *ConstrExpr) { 781 MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs( 782 DeclInfo.getDecl(), DeclInfo.getLexicalDeclContext(), /*Final=*/false, 783 /*Innermost=*/nullptr, 784 /*RelativeToPrimary=*/true, 785 /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/true, 786 /*SkipForSpecialization*/ false); 787 788 if (MLTAL.getNumSubstitutedLevels() == 0) 789 return ConstrExpr; 790 791 Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/false); 792 793 Sema::InstantiatingTemplate Inst( 794 S, DeclInfo.getLocation(), 795 Sema::InstantiatingTemplate::ConstraintNormalization{}, 796 const_cast<NamedDecl *>(DeclInfo.getDecl()), SourceRange{}); 797 if (Inst.isInvalid()) 798 return nullptr; 799 800 std::optional<Sema::CXXThisScopeRAII> ThisScope; 801 if (auto *RD = dyn_cast<CXXRecordDecl>(DeclInfo.getDeclContext())) 802 ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers()); 803 ExprResult SubstConstr = S.SubstConstraintExprWithoutSatisfaction( 804 const_cast<clang::Expr *>(ConstrExpr), MLTAL); 805 if (SFINAE.hasErrorOccurred() || !SubstConstr.isUsable()) 806 return nullptr; 807 return SubstConstr.get(); 808 } 809 810 bool Sema::AreConstraintExpressionsEqual(const NamedDecl *Old, 811 const Expr *OldConstr, 812 const TemplateCompareNewDeclInfo &New, 813 const Expr *NewConstr) { 814 if (OldConstr == NewConstr) 815 return true; 816 // C++ [temp.constr.decl]p4 817 if (Old && !New.isInvalid() && !New.ContainsDecl(Old) && 818 Old->getLexicalDeclContext() != New.getLexicalDeclContext()) { 819 if (const Expr *SubstConstr = 820 SubstituteConstraintExpressionWithoutSatisfaction(*this, Old, 821 OldConstr)) 822 OldConstr = SubstConstr; 823 else 824 return false; 825 if (const Expr *SubstConstr = 826 SubstituteConstraintExpressionWithoutSatisfaction(*this, New, 827 NewConstr)) 828 NewConstr = SubstConstr; 829 else 830 return false; 831 } 832 833 llvm::FoldingSetNodeID ID1, ID2; 834 OldConstr->Profile(ID1, Context, /*Canonical=*/true); 835 NewConstr->Profile(ID2, Context, /*Canonical=*/true); 836 return ID1 == ID2; 837 } 838 839 bool Sema::FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD) { 840 assert(FD->getFriendObjectKind() && "Must be a friend!"); 841 842 // The logic for non-templates is handled in ASTContext::isSameEntity, so we 843 // don't have to bother checking 'DependsOnEnclosingTemplate' for a 844 // non-function-template. 845 assert(FD->getDescribedFunctionTemplate() && 846 "Non-function templates don't need to be checked"); 847 848 SmallVector<const Expr *, 3> ACs; 849 FD->getDescribedFunctionTemplate()->getAssociatedConstraints(ACs); 850 851 unsigned OldTemplateDepth = CalculateTemplateDepthForConstraints(*this, FD); 852 for (const Expr *Constraint : ACs) 853 if (ConstraintExpressionDependsOnEnclosingTemplate(FD, OldTemplateDepth, 854 Constraint)) 855 return true; 856 857 return false; 858 } 859 860 bool Sema::EnsureTemplateArgumentListConstraints( 861 TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists, 862 SourceRange TemplateIDRange) { 863 ConstraintSatisfaction Satisfaction; 864 llvm::SmallVector<const Expr *, 3> AssociatedConstraints; 865 TD->getAssociatedConstraints(AssociatedConstraints); 866 if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists, 867 TemplateIDRange, Satisfaction)) 868 return true; 869 870 if (!Satisfaction.IsSatisfied) { 871 SmallString<128> TemplateArgString; 872 TemplateArgString = " "; 873 TemplateArgString += getTemplateArgumentBindingsText( 874 TD->getTemplateParameters(), TemplateArgsLists.getInnermost().data(), 875 TemplateArgsLists.getInnermost().size()); 876 877 Diag(TemplateIDRange.getBegin(), 878 diag::err_template_arg_list_constraints_not_satisfied) 879 << (int)getTemplateNameKindForDiagnostics(TemplateName(TD)) << TD 880 << TemplateArgString << TemplateIDRange; 881 DiagnoseUnsatisfiedConstraint(Satisfaction); 882 return true; 883 } 884 return false; 885 } 886 887 bool Sema::CheckInstantiatedFunctionTemplateConstraints( 888 SourceLocation PointOfInstantiation, FunctionDecl *Decl, 889 ArrayRef<TemplateArgument> TemplateArgs, 890 ConstraintSatisfaction &Satisfaction) { 891 // In most cases we're not going to have constraints, so check for that first. 892 FunctionTemplateDecl *Template = Decl->getPrimaryTemplate(); 893 // Note - code synthesis context for the constraints check is created 894 // inside CheckConstraintsSatisfaction. 895 SmallVector<const Expr *, 3> TemplateAC; 896 Template->getAssociatedConstraints(TemplateAC); 897 if (TemplateAC.empty()) { 898 Satisfaction.IsSatisfied = true; 899 return false; 900 } 901 902 // Enter the scope of this instantiation. We don't use 903 // PushDeclContext because we don't have a scope. 904 Sema::ContextRAII savedContext(*this, Decl); 905 LocalInstantiationScope Scope(*this); 906 907 std::optional<MultiLevelTemplateArgumentList> MLTAL = 908 SetupConstraintCheckingTemplateArgumentsAndScope(Decl, TemplateArgs, 909 Scope); 910 911 if (!MLTAL) 912 return true; 913 914 Qualifiers ThisQuals; 915 CXXRecordDecl *Record = nullptr; 916 if (auto *Method = dyn_cast<CXXMethodDecl>(Decl)) { 917 ThisQuals = Method->getMethodQualifiers(); 918 Record = Method->getParent(); 919 } 920 921 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); 922 LambdaScopeForCallOperatorInstantiationRAII LambdaScope( 923 *this, const_cast<FunctionDecl *>(Decl), *MLTAL, Scope); 924 925 llvm::SmallVector<Expr *, 1> Converted; 926 return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL, 927 PointOfInstantiation, Satisfaction); 928 } 929 930 static void diagnoseUnsatisfiedRequirement(Sema &S, 931 concepts::ExprRequirement *Req, 932 bool First) { 933 assert(!Req->isSatisfied() 934 && "Diagnose() can only be used on an unsatisfied requirement"); 935 switch (Req->getSatisfactionStatus()) { 936 case concepts::ExprRequirement::SS_Dependent: 937 llvm_unreachable("Diagnosing a dependent requirement"); 938 break; 939 case concepts::ExprRequirement::SS_ExprSubstitutionFailure: { 940 auto *SubstDiag = Req->getExprSubstitutionDiagnostic(); 941 if (!SubstDiag->DiagMessage.empty()) 942 S.Diag(SubstDiag->DiagLoc, 943 diag::note_expr_requirement_expr_substitution_error) 944 << (int)First << SubstDiag->SubstitutedEntity 945 << SubstDiag->DiagMessage; 946 else 947 S.Diag(SubstDiag->DiagLoc, 948 diag::note_expr_requirement_expr_unknown_substitution_error) 949 << (int)First << SubstDiag->SubstitutedEntity; 950 break; 951 } 952 case concepts::ExprRequirement::SS_NoexceptNotMet: 953 S.Diag(Req->getNoexceptLoc(), 954 diag::note_expr_requirement_noexcept_not_met) 955 << (int)First << Req->getExpr(); 956 break; 957 case concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure: { 958 auto *SubstDiag = 959 Req->getReturnTypeRequirement().getSubstitutionDiagnostic(); 960 if (!SubstDiag->DiagMessage.empty()) 961 S.Diag(SubstDiag->DiagLoc, 962 diag::note_expr_requirement_type_requirement_substitution_error) 963 << (int)First << SubstDiag->SubstitutedEntity 964 << SubstDiag->DiagMessage; 965 else 966 S.Diag(SubstDiag->DiagLoc, 967 diag::note_expr_requirement_type_requirement_unknown_substitution_error) 968 << (int)First << SubstDiag->SubstitutedEntity; 969 break; 970 } 971 case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: { 972 ConceptSpecializationExpr *ConstraintExpr = 973 Req->getReturnTypeRequirementSubstitutedConstraintExpr(); 974 if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) { 975 // A simple case - expr type is the type being constrained and the concept 976 // was not provided arguments. 977 Expr *e = Req->getExpr(); 978 S.Diag(e->getBeginLoc(), 979 diag::note_expr_requirement_constraints_not_satisfied_simple) 980 << (int)First << S.Context.getReferenceQualifiedType(e) 981 << ConstraintExpr->getNamedConcept(); 982 } else { 983 S.Diag(ConstraintExpr->getBeginLoc(), 984 diag::note_expr_requirement_constraints_not_satisfied) 985 << (int)First << ConstraintExpr; 986 } 987 S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction()); 988 break; 989 } 990 case concepts::ExprRequirement::SS_Satisfied: 991 llvm_unreachable("We checked this above"); 992 } 993 } 994 995 static void diagnoseUnsatisfiedRequirement(Sema &S, 996 concepts::TypeRequirement *Req, 997 bool First) { 998 assert(!Req->isSatisfied() 999 && "Diagnose() can only be used on an unsatisfied requirement"); 1000 switch (Req->getSatisfactionStatus()) { 1001 case concepts::TypeRequirement::SS_Dependent: 1002 llvm_unreachable("Diagnosing a dependent requirement"); 1003 return; 1004 case concepts::TypeRequirement::SS_SubstitutionFailure: { 1005 auto *SubstDiag = Req->getSubstitutionDiagnostic(); 1006 if (!SubstDiag->DiagMessage.empty()) 1007 S.Diag(SubstDiag->DiagLoc, 1008 diag::note_type_requirement_substitution_error) << (int)First 1009 << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage; 1010 else 1011 S.Diag(SubstDiag->DiagLoc, 1012 diag::note_type_requirement_unknown_substitution_error) 1013 << (int)First << SubstDiag->SubstitutedEntity; 1014 return; 1015 } 1016 default: 1017 llvm_unreachable("Unknown satisfaction status"); 1018 return; 1019 } 1020 } 1021 static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, 1022 Expr *SubstExpr, 1023 bool First = true); 1024 1025 static void diagnoseUnsatisfiedRequirement(Sema &S, 1026 concepts::NestedRequirement *Req, 1027 bool First) { 1028 using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>; 1029 for (auto &Pair : Req->getConstraintSatisfaction()) { 1030 if (auto *SubstDiag = Pair.second.dyn_cast<SubstitutionDiagnostic *>()) 1031 S.Diag(SubstDiag->first, diag::note_nested_requirement_substitution_error) 1032 << (int)First << Req->getInvalidConstraintEntity() << SubstDiag->second; 1033 else 1034 diagnoseWellFormedUnsatisfiedConstraintExpr( 1035 S, Pair.second.dyn_cast<Expr *>(), First); 1036 First = false; 1037 } 1038 } 1039 1040 static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, 1041 Expr *SubstExpr, 1042 bool First) { 1043 SubstExpr = SubstExpr->IgnoreParenImpCasts(); 1044 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) { 1045 switch (BO->getOpcode()) { 1046 // These two cases will in practice only be reached when using fold 1047 // expressions with || and &&, since otherwise the || and && will have been 1048 // broken down into atomic constraints during satisfaction checking. 1049 case BO_LOr: 1050 // Or evaluated to false - meaning both RHS and LHS evaluated to false. 1051 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First); 1052 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), 1053 /*First=*/false); 1054 return; 1055 case BO_LAnd: { 1056 bool LHSSatisfied = 1057 BO->getLHS()->EvaluateKnownConstInt(S.Context).getBoolValue(); 1058 if (LHSSatisfied) { 1059 // LHS is true, so RHS must be false. 1060 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), First); 1061 return; 1062 } 1063 // LHS is false 1064 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First); 1065 1066 // RHS might also be false 1067 bool RHSSatisfied = 1068 BO->getRHS()->EvaluateKnownConstInt(S.Context).getBoolValue(); 1069 if (!RHSSatisfied) 1070 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), 1071 /*First=*/false); 1072 return; 1073 } 1074 case BO_GE: 1075 case BO_LE: 1076 case BO_GT: 1077 case BO_LT: 1078 case BO_EQ: 1079 case BO_NE: 1080 if (BO->getLHS()->getType()->isIntegerType() && 1081 BO->getRHS()->getType()->isIntegerType()) { 1082 Expr::EvalResult SimplifiedLHS; 1083 Expr::EvalResult SimplifiedRHS; 1084 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.Context, 1085 Expr::SE_NoSideEffects, 1086 /*InConstantContext=*/true); 1087 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context, 1088 Expr::SE_NoSideEffects, 1089 /*InConstantContext=*/true); 1090 if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) { 1091 S.Diag(SubstExpr->getBeginLoc(), 1092 diag::note_atomic_constraint_evaluated_to_false_elaborated) 1093 << (int)First << SubstExpr 1094 << toString(SimplifiedLHS.Val.getInt(), 10) 1095 << BinaryOperator::getOpcodeStr(BO->getOpcode()) 1096 << toString(SimplifiedRHS.Val.getInt(), 10); 1097 return; 1098 } 1099 } 1100 break; 1101 1102 default: 1103 break; 1104 } 1105 } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) { 1106 if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) { 1107 S.Diag( 1108 CSE->getSourceRange().getBegin(), 1109 diag:: 1110 note_single_arg_concept_specialization_constraint_evaluated_to_false) 1111 << (int)First 1112 << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument() 1113 << CSE->getNamedConcept(); 1114 } else { 1115 S.Diag(SubstExpr->getSourceRange().getBegin(), 1116 diag::note_concept_specialization_constraint_evaluated_to_false) 1117 << (int)First << CSE; 1118 } 1119 S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction()); 1120 return; 1121 } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) { 1122 // FIXME: RequiresExpr should store dependent diagnostics. 1123 for (concepts::Requirement *Req : RE->getRequirements()) 1124 if (!Req->isDependent() && !Req->isSatisfied()) { 1125 if (auto *E = dyn_cast<concepts::ExprRequirement>(Req)) 1126 diagnoseUnsatisfiedRequirement(S, E, First); 1127 else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req)) 1128 diagnoseUnsatisfiedRequirement(S, T, First); 1129 else 1130 diagnoseUnsatisfiedRequirement( 1131 S, cast<concepts::NestedRequirement>(Req), First); 1132 break; 1133 } 1134 return; 1135 } 1136 1137 S.Diag(SubstExpr->getSourceRange().getBegin(), 1138 diag::note_atomic_constraint_evaluated_to_false) 1139 << (int)First << SubstExpr; 1140 } 1141 1142 template<typename SubstitutionDiagnostic> 1143 static void diagnoseUnsatisfiedConstraintExpr( 1144 Sema &S, const Expr *E, 1145 const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record, 1146 bool First = true) { 1147 if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){ 1148 S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed) 1149 << Diag->second; 1150 return; 1151 } 1152 1153 diagnoseWellFormedUnsatisfiedConstraintExpr(S, 1154 Record.template get<Expr *>(), First); 1155 } 1156 1157 void 1158 Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction, 1159 bool First) { 1160 assert(!Satisfaction.IsSatisfied && 1161 "Attempted to diagnose a satisfied constraint"); 1162 for (auto &Pair : Satisfaction.Details) { 1163 diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First); 1164 First = false; 1165 } 1166 } 1167 1168 void Sema::DiagnoseUnsatisfiedConstraint( 1169 const ASTConstraintSatisfaction &Satisfaction, 1170 bool First) { 1171 assert(!Satisfaction.IsSatisfied && 1172 "Attempted to diagnose a satisfied constraint"); 1173 for (auto &Pair : Satisfaction) { 1174 diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First); 1175 First = false; 1176 } 1177 } 1178 1179 const NormalizedConstraint * 1180 Sema::getNormalizedAssociatedConstraints( 1181 NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) { 1182 // In case the ConstrainedDecl comes from modules, it is necessary to use 1183 // the canonical decl to avoid different atomic constraints with the 'same' 1184 // declarations. 1185 ConstrainedDecl = cast<NamedDecl>(ConstrainedDecl->getCanonicalDecl()); 1186 1187 auto CacheEntry = NormalizationCache.find(ConstrainedDecl); 1188 if (CacheEntry == NormalizationCache.end()) { 1189 auto Normalized = 1190 NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl, 1191 AssociatedConstraints); 1192 CacheEntry = 1193 NormalizationCache 1194 .try_emplace(ConstrainedDecl, 1195 Normalized 1196 ? new (Context) NormalizedConstraint( 1197 std::move(*Normalized)) 1198 : nullptr) 1199 .first; 1200 } 1201 return CacheEntry->second; 1202 } 1203 1204 static bool 1205 substituteParameterMappings(Sema &S, NormalizedConstraint &N, 1206 ConceptDecl *Concept, 1207 const MultiLevelTemplateArgumentList &MLTAL, 1208 const ASTTemplateArgumentListInfo *ArgsAsWritten) { 1209 if (!N.isAtomic()) { 1210 if (substituteParameterMappings(S, N.getLHS(), Concept, MLTAL, 1211 ArgsAsWritten)) 1212 return true; 1213 return substituteParameterMappings(S, N.getRHS(), Concept, MLTAL, 1214 ArgsAsWritten); 1215 } 1216 TemplateParameterList *TemplateParams = Concept->getTemplateParameters(); 1217 1218 AtomicConstraint &Atomic = *N.getAtomicConstraint(); 1219 TemplateArgumentListInfo SubstArgs; 1220 if (!Atomic.ParameterMapping) { 1221 llvm::SmallBitVector OccurringIndices(TemplateParams->size()); 1222 S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false, 1223 /*Depth=*/0, OccurringIndices); 1224 TemplateArgumentLoc *TempArgs = 1225 new (S.Context) TemplateArgumentLoc[OccurringIndices.count()]; 1226 for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I) 1227 if (OccurringIndices[I]) 1228 new (&(TempArgs)[J++]) 1229 TemplateArgumentLoc(S.getIdentityTemplateArgumentLoc( 1230 TemplateParams->begin()[I], 1231 // Here we assume we do not support things like 1232 // template<typename A, typename B> 1233 // concept C = ...; 1234 // 1235 // template<typename... Ts> requires C<Ts...> 1236 // struct S { }; 1237 // The above currently yields a diagnostic. 1238 // We still might have default arguments for concept parameters. 1239 ArgsAsWritten->NumTemplateArgs > I 1240 ? ArgsAsWritten->arguments()[I].getLocation() 1241 : SourceLocation())); 1242 Atomic.ParameterMapping.emplace(TempArgs, OccurringIndices.count()); 1243 } 1244 Sema::InstantiatingTemplate Inst( 1245 S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(), 1246 Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept, 1247 ArgsAsWritten->arguments().front().getSourceRange()); 1248 if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs)) 1249 return true; 1250 1251 TemplateArgumentLoc *TempArgs = 1252 new (S.Context) TemplateArgumentLoc[SubstArgs.size()]; 1253 std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(), 1254 TempArgs); 1255 Atomic.ParameterMapping.emplace(TempArgs, SubstArgs.size()); 1256 return false; 1257 } 1258 1259 static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, 1260 const ConceptSpecializationExpr *CSE) { 1261 TemplateArgumentList TAL{TemplateArgumentList::OnStack, 1262 CSE->getTemplateArguments()}; 1263 MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs( 1264 CSE->getNamedConcept(), CSE->getNamedConcept()->getLexicalDeclContext(), 1265 /*Final=*/false, &TAL, 1266 /*RelativeToPrimary=*/true, 1267 /*Pattern=*/nullptr, 1268 /*ForConstraintInstantiation=*/true); 1269 1270 return substituteParameterMappings(S, N, CSE->getNamedConcept(), MLTAL, 1271 CSE->getTemplateArgsAsWritten()); 1272 } 1273 1274 std::optional<NormalizedConstraint> 1275 NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D, 1276 ArrayRef<const Expr *> E) { 1277 assert(E.size() != 0); 1278 auto Conjunction = fromConstraintExpr(S, D, E[0]); 1279 if (!Conjunction) 1280 return std::nullopt; 1281 for (unsigned I = 1; I < E.size(); ++I) { 1282 auto Next = fromConstraintExpr(S, D, E[I]); 1283 if (!Next) 1284 return std::nullopt; 1285 *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction), 1286 std::move(*Next), CCK_Conjunction); 1287 } 1288 return Conjunction; 1289 } 1290 1291 std::optional<NormalizedConstraint> 1292 NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) { 1293 assert(E != nullptr); 1294 1295 // C++ [temp.constr.normal]p1.1 1296 // [...] 1297 // - The normal form of an expression (E) is the normal form of E. 1298 // [...] 1299 E = E->IgnoreParenImpCasts(); 1300 1301 // C++2a [temp.param]p4: 1302 // [...] If T is not a pack, then E is E', otherwise E is (E' && ...). 1303 // Fold expression is considered atomic constraints per current wording. 1304 // See http://cplusplus.github.io/concepts-ts/ts-active.html#28 1305 1306 if (LogicalBinOp BO = E) { 1307 auto LHS = fromConstraintExpr(S, D, BO.getLHS()); 1308 if (!LHS) 1309 return std::nullopt; 1310 auto RHS = fromConstraintExpr(S, D, BO.getRHS()); 1311 if (!RHS) 1312 return std::nullopt; 1313 1314 return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS), 1315 BO.isAnd() ? CCK_Conjunction : CCK_Disjunction); 1316 } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) { 1317 const NormalizedConstraint *SubNF; 1318 { 1319 Sema::InstantiatingTemplate Inst( 1320 S, CSE->getExprLoc(), 1321 Sema::InstantiatingTemplate::ConstraintNormalization{}, D, 1322 CSE->getSourceRange()); 1323 // C++ [temp.constr.normal]p1.1 1324 // [...] 1325 // The normal form of an id-expression of the form C<A1, A2, ..., AN>, 1326 // where C names a concept, is the normal form of the 1327 // constraint-expression of C, after substituting A1, A2, ..., AN for C’s 1328 // respective template parameters in the parameter mappings in each atomic 1329 // constraint. If any such substitution results in an invalid type or 1330 // expression, the program is ill-formed; no diagnostic is required. 1331 // [...] 1332 ConceptDecl *CD = CSE->getNamedConcept(); 1333 SubNF = S.getNormalizedAssociatedConstraints(CD, 1334 {CD->getConstraintExpr()}); 1335 if (!SubNF) 1336 return std::nullopt; 1337 } 1338 1339 std::optional<NormalizedConstraint> New; 1340 New.emplace(S.Context, *SubNF); 1341 1342 if (substituteParameterMappings(S, *New, CSE)) 1343 return std::nullopt; 1344 1345 return New; 1346 } 1347 return NormalizedConstraint{new (S.Context) AtomicConstraint(S, E)}; 1348 } 1349 1350 using NormalForm = 1351 llvm::SmallVector<llvm::SmallVector<AtomicConstraint *, 2>, 4>; 1352 1353 static NormalForm makeCNF(const NormalizedConstraint &Normalized) { 1354 if (Normalized.isAtomic()) 1355 return {{Normalized.getAtomicConstraint()}}; 1356 1357 NormalForm LCNF = makeCNF(Normalized.getLHS()); 1358 NormalForm RCNF = makeCNF(Normalized.getRHS()); 1359 if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Conjunction) { 1360 LCNF.reserve(LCNF.size() + RCNF.size()); 1361 while (!RCNF.empty()) 1362 LCNF.push_back(RCNF.pop_back_val()); 1363 return LCNF; 1364 } 1365 1366 // Disjunction 1367 NormalForm Res; 1368 Res.reserve(LCNF.size() * RCNF.size()); 1369 for (auto &LDisjunction : LCNF) 1370 for (auto &RDisjunction : RCNF) { 1371 NormalForm::value_type Combined; 1372 Combined.reserve(LDisjunction.size() + RDisjunction.size()); 1373 std::copy(LDisjunction.begin(), LDisjunction.end(), 1374 std::back_inserter(Combined)); 1375 std::copy(RDisjunction.begin(), RDisjunction.end(), 1376 std::back_inserter(Combined)); 1377 Res.emplace_back(Combined); 1378 } 1379 return Res; 1380 } 1381 1382 static NormalForm makeDNF(const NormalizedConstraint &Normalized) { 1383 if (Normalized.isAtomic()) 1384 return {{Normalized.getAtomicConstraint()}}; 1385 1386 NormalForm LDNF = makeDNF(Normalized.getLHS()); 1387 NormalForm RDNF = makeDNF(Normalized.getRHS()); 1388 if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Disjunction) { 1389 LDNF.reserve(LDNF.size() + RDNF.size()); 1390 while (!RDNF.empty()) 1391 LDNF.push_back(RDNF.pop_back_val()); 1392 return LDNF; 1393 } 1394 1395 // Conjunction 1396 NormalForm Res; 1397 Res.reserve(LDNF.size() * RDNF.size()); 1398 for (auto &LConjunction : LDNF) { 1399 for (auto &RConjunction : RDNF) { 1400 NormalForm::value_type Combined; 1401 Combined.reserve(LConjunction.size() + RConjunction.size()); 1402 std::copy(LConjunction.begin(), LConjunction.end(), 1403 std::back_inserter(Combined)); 1404 std::copy(RConjunction.begin(), RConjunction.end(), 1405 std::back_inserter(Combined)); 1406 Res.emplace_back(Combined); 1407 } 1408 } 1409 return Res; 1410 } 1411 1412 template<typename AtomicSubsumptionEvaluator> 1413 static bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF, 1414 AtomicSubsumptionEvaluator E) { 1415 // C++ [temp.constr.order] p2 1416 // Then, P subsumes Q if and only if, for every disjunctive clause Pi in the 1417 // disjunctive normal form of P, Pi subsumes every conjunctive clause Qj in 1418 // the conjuctive normal form of Q, where [...] 1419 for (const auto &Pi : PDNF) { 1420 for (const auto &Qj : QCNF) { 1421 // C++ [temp.constr.order] p2 1422 // - [...] a disjunctive clause Pi subsumes a conjunctive clause Qj if 1423 // and only if there exists an atomic constraint Pia in Pi for which 1424 // there exists an atomic constraint, Qjb, in Qj such that Pia 1425 // subsumes Qjb. 1426 bool Found = false; 1427 for (const AtomicConstraint *Pia : Pi) { 1428 for (const AtomicConstraint *Qjb : Qj) { 1429 if (E(*Pia, *Qjb)) { 1430 Found = true; 1431 break; 1432 } 1433 } 1434 if (Found) 1435 break; 1436 } 1437 if (!Found) 1438 return false; 1439 } 1440 } 1441 return true; 1442 } 1443 1444 template<typename AtomicSubsumptionEvaluator> 1445 static bool subsumes(Sema &S, NamedDecl *DP, ArrayRef<const Expr *> P, 1446 NamedDecl *DQ, ArrayRef<const Expr *> Q, bool &Subsumes, 1447 AtomicSubsumptionEvaluator E) { 1448 // C++ [temp.constr.order] p2 1449 // In order to determine if a constraint P subsumes a constraint Q, P is 1450 // transformed into disjunctive normal form, and Q is transformed into 1451 // conjunctive normal form. [...] 1452 auto *PNormalized = S.getNormalizedAssociatedConstraints(DP, P); 1453 if (!PNormalized) 1454 return true; 1455 const NormalForm PDNF = makeDNF(*PNormalized); 1456 1457 auto *QNormalized = S.getNormalizedAssociatedConstraints(DQ, Q); 1458 if (!QNormalized) 1459 return true; 1460 const NormalForm QCNF = makeCNF(*QNormalized); 1461 1462 Subsumes = subsumes(PDNF, QCNF, E); 1463 return false; 1464 } 1465 1466 bool Sema::IsAtLeastAsConstrained(NamedDecl *D1, 1467 MutableArrayRef<const Expr *> AC1, 1468 NamedDecl *D2, 1469 MutableArrayRef<const Expr *> AC2, 1470 bool &Result) { 1471 if (const auto *FD1 = dyn_cast<FunctionDecl>(D1)) { 1472 auto IsExpectedEntity = [](const FunctionDecl *FD) { 1473 FunctionDecl::TemplatedKind Kind = FD->getTemplatedKind(); 1474 return Kind == FunctionDecl::TK_NonTemplate || 1475 Kind == FunctionDecl::TK_FunctionTemplate; 1476 }; 1477 const auto *FD2 = dyn_cast<FunctionDecl>(D2); 1478 (void)IsExpectedEntity; 1479 (void)FD1; 1480 (void)FD2; 1481 assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) && 1482 "use non-instantiated function declaration for constraints partial " 1483 "ordering"); 1484 } 1485 1486 if (AC1.empty()) { 1487 Result = AC2.empty(); 1488 return false; 1489 } 1490 if (AC2.empty()) { 1491 // TD1 has associated constraints and TD2 does not. 1492 Result = true; 1493 return false; 1494 } 1495 1496 std::pair<NamedDecl *, NamedDecl *> Key{D1, D2}; 1497 auto CacheEntry = SubsumptionCache.find(Key); 1498 if (CacheEntry != SubsumptionCache.end()) { 1499 Result = CacheEntry->second; 1500 return false; 1501 } 1502 1503 unsigned Depth1 = CalculateTemplateDepthForConstraints(*this, D1, true); 1504 unsigned Depth2 = CalculateTemplateDepthForConstraints(*this, D2, true); 1505 1506 for (size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) { 1507 if (Depth2 > Depth1) { 1508 AC1[I] = AdjustConstraintDepth(*this, Depth2 - Depth1) 1509 .TransformExpr(const_cast<Expr *>(AC1[I])) 1510 .get(); 1511 } else if (Depth1 > Depth2) { 1512 AC2[I] = AdjustConstraintDepth(*this, Depth1 - Depth2) 1513 .TransformExpr(const_cast<Expr *>(AC2[I])) 1514 .get(); 1515 } 1516 } 1517 1518 if (subsumes(*this, D1, AC1, D2, AC2, Result, 1519 [this] (const AtomicConstraint &A, const AtomicConstraint &B) { 1520 return A.subsumes(Context, B); 1521 })) 1522 return true; 1523 SubsumptionCache.try_emplace(Key, Result); 1524 return false; 1525 } 1526 1527 bool Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1, 1528 ArrayRef<const Expr *> AC1, NamedDecl *D2, ArrayRef<const Expr *> AC2) { 1529 if (isSFINAEContext()) 1530 // No need to work here because our notes would be discarded. 1531 return false; 1532 1533 if (AC1.empty() || AC2.empty()) 1534 return false; 1535 1536 auto NormalExprEvaluator = 1537 [this] (const AtomicConstraint &A, const AtomicConstraint &B) { 1538 return A.subsumes(Context, B); 1539 }; 1540 1541 const Expr *AmbiguousAtomic1 = nullptr, *AmbiguousAtomic2 = nullptr; 1542 auto IdenticalExprEvaluator = 1543 [&] (const AtomicConstraint &A, const AtomicConstraint &B) { 1544 if (!A.hasMatchingParameterMapping(Context, B)) 1545 return false; 1546 const Expr *EA = A.ConstraintExpr, *EB = B.ConstraintExpr; 1547 if (EA == EB) 1548 return true; 1549 1550 // Not the same source level expression - are the expressions 1551 // identical? 1552 llvm::FoldingSetNodeID IDA, IDB; 1553 EA->Profile(IDA, Context, /*Canonical=*/true); 1554 EB->Profile(IDB, Context, /*Canonical=*/true); 1555 if (IDA != IDB) 1556 return false; 1557 1558 AmbiguousAtomic1 = EA; 1559 AmbiguousAtomic2 = EB; 1560 return true; 1561 }; 1562 1563 { 1564 // The subsumption checks might cause diagnostics 1565 SFINAETrap Trap(*this); 1566 auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1); 1567 if (!Normalized1) 1568 return false; 1569 const NormalForm DNF1 = makeDNF(*Normalized1); 1570 const NormalForm CNF1 = makeCNF(*Normalized1); 1571 1572 auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2); 1573 if (!Normalized2) 1574 return false; 1575 const NormalForm DNF2 = makeDNF(*Normalized2); 1576 const NormalForm CNF2 = makeCNF(*Normalized2); 1577 1578 bool Is1AtLeastAs2Normally = subsumes(DNF1, CNF2, NormalExprEvaluator); 1579 bool Is2AtLeastAs1Normally = subsumes(DNF2, CNF1, NormalExprEvaluator); 1580 bool Is1AtLeastAs2 = subsumes(DNF1, CNF2, IdenticalExprEvaluator); 1581 bool Is2AtLeastAs1 = subsumes(DNF2, CNF1, IdenticalExprEvaluator); 1582 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally && 1583 Is2AtLeastAs1 == Is2AtLeastAs1Normally) 1584 // Same result - no ambiguity was caused by identical atomic expressions. 1585 return false; 1586 } 1587 1588 // A different result! Some ambiguous atomic constraint(s) caused a difference 1589 assert(AmbiguousAtomic1 && AmbiguousAtomic2); 1590 1591 Diag(AmbiguousAtomic1->getBeginLoc(), diag::note_ambiguous_atomic_constraints) 1592 << AmbiguousAtomic1->getSourceRange(); 1593 Diag(AmbiguousAtomic2->getBeginLoc(), 1594 diag::note_ambiguous_atomic_constraints_similar_expression) 1595 << AmbiguousAtomic2->getSourceRange(); 1596 return true; 1597 } 1598 1599 concepts::ExprRequirement::ExprRequirement( 1600 Expr *E, bool IsSimple, SourceLocation NoexceptLoc, 1601 ReturnTypeRequirement Req, SatisfactionStatus Status, 1602 ConceptSpecializationExpr *SubstitutedConstraintExpr) : 1603 Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent, 1604 Status == SS_Dependent && 1605 (E->containsUnexpandedParameterPack() || 1606 Req.containsUnexpandedParameterPack()), 1607 Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc), 1608 TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr), 1609 Status(Status) { 1610 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) && 1611 "Simple requirement must not have a return type requirement or a " 1612 "noexcept specification"); 1613 assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) == 1614 (SubstitutedConstraintExpr != nullptr)); 1615 } 1616 1617 concepts::ExprRequirement::ExprRequirement( 1618 SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple, 1619 SourceLocation NoexceptLoc, ReturnTypeRequirement Req) : 1620 Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(), 1621 Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false), 1622 Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req), 1623 Status(SS_ExprSubstitutionFailure) { 1624 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) && 1625 "Simple requirement must not have a return type requirement or a " 1626 "noexcept specification"); 1627 } 1628 1629 concepts::ExprRequirement::ReturnTypeRequirement:: 1630 ReturnTypeRequirement(TemplateParameterList *TPL) : 1631 TypeConstraintInfo(TPL, false) { 1632 assert(TPL->size() == 1); 1633 const TypeConstraint *TC = 1634 cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint(); 1635 assert(TC && 1636 "TPL must have a template type parameter with a type constraint"); 1637 auto *Constraint = 1638 cast<ConceptSpecializationExpr>(TC->getImmediatelyDeclaredConstraint()); 1639 bool Dependent = 1640 Constraint->getTemplateArgsAsWritten() && 1641 TemplateSpecializationType::anyInstantiationDependentTemplateArguments( 1642 Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1)); 1643 TypeConstraintInfo.setInt(Dependent ? true : false); 1644 } 1645 1646 concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T) : 1647 Requirement(RK_Type, T->getType()->isInstantiationDependentType(), 1648 T->getType()->containsUnexpandedParameterPack(), 1649 // We reach this ctor with either dependent types (in which 1650 // IsSatisfied doesn't matter) or with non-dependent type in 1651 // which the existence of the type indicates satisfaction. 1652 /*IsSatisfied=*/true), 1653 Value(T), 1654 Status(T->getType()->isInstantiationDependentType() ? SS_Dependent 1655 : SS_Satisfied) {} 1656