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