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 "clang/Sema/Sema.h" 15 #include "clang/Sema/SemaInternal.h" 16 #include "clang/Sema/SemaDiagnostic.h" 17 #include "clang/Sema/TemplateDeduction.h" 18 #include "clang/Sema/Template.h" 19 #include "clang/Sema/Overload.h" 20 #include "clang/Sema/Initialization.h" 21 #include "clang/AST/ExprConcepts.h" 22 #include "clang/AST/RecursiveASTVisitor.h" 23 #include "clang/Basic/OperatorPrecedence.h" 24 #include "llvm/ADT/DenseMap.h" 25 #include "llvm/ADT/PointerUnion.h" 26 #include "llvm/ADT/StringExtras.h" 27 28 using namespace clang; 29 using namespace sema; 30 31 namespace { 32 class LogicalBinOp { 33 OverloadedOperatorKind Op = OO_None; 34 const Expr *LHS = nullptr; 35 const Expr *RHS = nullptr; 36 37 public: 38 LogicalBinOp(const Expr *E) { 39 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 40 Op = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 41 LHS = BO->getLHS(); 42 RHS = BO->getRHS(); 43 } else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) { 44 // If OO is not || or && it might not have exactly 2 arguments. 45 if (OO->getNumArgs() == 2) { 46 Op = OO->getOperator(); 47 LHS = OO->getArg(0); 48 RHS = OO->getArg(1); 49 } 50 } 51 } 52 53 bool isAnd() const { return Op == OO_AmpAmp; } 54 bool isOr() const { return Op == OO_PipePipe; } 55 explicit operator bool() const { return isAnd() || isOr(); } 56 57 const Expr *getLHS() const { return LHS; } 58 const Expr *getRHS() const { return RHS; } 59 }; 60 } 61 62 bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression, 63 Token NextToken, bool *PossibleNonPrimary, 64 bool IsTrailingRequiresClause) { 65 // C++2a [temp.constr.atomic]p1 66 // ..E shall be a constant expression of type bool. 67 68 ConstraintExpression = ConstraintExpression->IgnoreParenImpCasts(); 69 70 if (LogicalBinOp BO = ConstraintExpression) { 71 return CheckConstraintExpression(BO.getLHS(), NextToken, 72 PossibleNonPrimary) && 73 CheckConstraintExpression(BO.getRHS(), NextToken, 74 PossibleNonPrimary); 75 } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression)) 76 return CheckConstraintExpression(C->getSubExpr(), NextToken, 77 PossibleNonPrimary); 78 79 QualType Type = ConstraintExpression->getType(); 80 81 auto CheckForNonPrimary = [&] { 82 if (PossibleNonPrimary) 83 *PossibleNonPrimary = 84 // We have the following case: 85 // template<typename> requires func(0) struct S { }; 86 // The user probably isn't aware of the parentheses required around 87 // the function call, and we're only going to parse 'func' as the 88 // primary-expression, and complain that it is of non-bool type. 89 (NextToken.is(tok::l_paren) && 90 (IsTrailingRequiresClause || 91 (Type->isDependentType() && 92 isa<UnresolvedLookupExpr>(ConstraintExpression)) || 93 Type->isFunctionType() || 94 Type->isSpecificBuiltinType(BuiltinType::Overload))) || 95 // We have the following case: 96 // template<typename T> requires size_<T> == 0 struct S { }; 97 // The user probably isn't aware of the parentheses required around 98 // the binary operator, and we're only going to parse 'func' as the 99 // first operand, and complain that it is of non-bool type. 100 getBinOpPrecedence(NextToken.getKind(), 101 /*GreaterThanIsOperator=*/true, 102 getLangOpts().CPlusPlus11) > prec::LogicalAnd; 103 }; 104 105 // An atomic constraint! 106 if (ConstraintExpression->isTypeDependent()) { 107 CheckForNonPrimary(); 108 return true; 109 } 110 111 if (!Context.hasSameUnqualifiedType(Type, Context.BoolTy)) { 112 Diag(ConstraintExpression->getExprLoc(), 113 diag::err_non_bool_atomic_constraint) << Type 114 << ConstraintExpression->getSourceRange(); 115 CheckForNonPrimary(); 116 return false; 117 } 118 119 if (PossibleNonPrimary) 120 *PossibleNonPrimary = false; 121 return true; 122 } 123 124 template <typename AtomicEvaluator> 125 static bool 126 calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr, 127 ConstraintSatisfaction &Satisfaction, 128 AtomicEvaluator &&Evaluator) { 129 ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts(); 130 131 if (LogicalBinOp BO = ConstraintExpr) { 132 if (calculateConstraintSatisfaction(S, BO.getLHS(), Satisfaction, 133 Evaluator)) 134 return true; 135 136 bool IsLHSSatisfied = Satisfaction.IsSatisfied; 137 138 if (BO.isOr() && IsLHSSatisfied) 139 // [temp.constr.op] p3 140 // A disjunction is a constraint taking two operands. To determine if 141 // a disjunction is satisfied, the satisfaction of the first operand 142 // is checked. If that is satisfied, the disjunction is satisfied. 143 // Otherwise, the disjunction is satisfied if and only if the second 144 // operand is satisfied. 145 return false; 146 147 if (BO.isAnd() && !IsLHSSatisfied) 148 // [temp.constr.op] p2 149 // A conjunction is a constraint taking two operands. To determine if 150 // a conjunction is satisfied, the satisfaction of the first operand 151 // is checked. If that is not satisfied, the conjunction is not 152 // satisfied. Otherwise, the conjunction is satisfied if and only if 153 // the second operand is satisfied. 154 return false; 155 156 return calculateConstraintSatisfaction( 157 S, BO.getRHS(), Satisfaction, std::forward<AtomicEvaluator>(Evaluator)); 158 } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) { 159 return calculateConstraintSatisfaction(S, C->getSubExpr(), Satisfaction, 160 std::forward<AtomicEvaluator>(Evaluator)); 161 } 162 163 // An atomic constraint expression 164 ExprResult SubstitutedAtomicExpr = Evaluator(ConstraintExpr); 165 166 if (SubstitutedAtomicExpr.isInvalid()) 167 return true; 168 169 if (!SubstitutedAtomicExpr.isUsable()) 170 // Evaluator has decided satisfaction without yielding an expression. 171 return false; 172 173 EnterExpressionEvaluationContext ConstantEvaluated( 174 S, Sema::ExpressionEvaluationContext::ConstantEvaluated); 175 SmallVector<PartialDiagnosticAt, 2> EvaluationDiags; 176 Expr::EvalResult EvalResult; 177 EvalResult.Diag = &EvaluationDiags; 178 if (!SubstitutedAtomicExpr.get()->EvaluateAsConstantExpr(EvalResult, 179 S.Context) || 180 !EvaluationDiags.empty()) { 181 // C++2a [temp.constr.atomic]p1 182 // ...E shall be a constant expression of type bool. 183 S.Diag(SubstitutedAtomicExpr.get()->getBeginLoc(), 184 diag::err_non_constant_constraint_expression) 185 << SubstitutedAtomicExpr.get()->getSourceRange(); 186 for (const PartialDiagnosticAt &PDiag : EvaluationDiags) 187 S.Diag(PDiag.first, PDiag.second); 188 return true; 189 } 190 191 assert(EvalResult.Val.isInt() && 192 "evaluating bool expression didn't produce int"); 193 Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue(); 194 if (!Satisfaction.IsSatisfied) 195 Satisfaction.Details.emplace_back(ConstraintExpr, 196 SubstitutedAtomicExpr.get()); 197 198 return false; 199 } 200 201 static bool calculateConstraintSatisfaction( 202 Sema &S, const NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs, 203 SourceLocation TemplateNameLoc, MultiLevelTemplateArgumentList &MLTAL, 204 const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction) { 205 return calculateConstraintSatisfaction( 206 S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) { 207 EnterExpressionEvaluationContext ConstantEvaluated( 208 S, Sema::ExpressionEvaluationContext::ConstantEvaluated); 209 210 // Atomic constraint - substitute arguments and check satisfaction. 211 ExprResult SubstitutedExpression; 212 { 213 TemplateDeductionInfo Info(TemplateNameLoc); 214 Sema::InstantiatingTemplate Inst(S, AtomicExpr->getBeginLoc(), 215 Sema::InstantiatingTemplate::ConstraintSubstitution{}, 216 const_cast<NamedDecl *>(Template), Info, 217 AtomicExpr->getSourceRange()); 218 if (Inst.isInvalid()) 219 return ExprError(); 220 // We do not want error diagnostics escaping here. 221 Sema::SFINAETrap Trap(S); 222 SubstitutedExpression = S.SubstExpr(const_cast<Expr *>(AtomicExpr), 223 MLTAL); 224 // Substitution might have stripped off a contextual conversion to 225 // bool if this is the operand of an '&&' or '||'. For example, we 226 // might lose an lvalue-to-rvalue conversion here. If so, put it back 227 // before we try to evaluate. 228 if (!SubstitutedExpression.isInvalid()) 229 SubstitutedExpression = 230 S.PerformContextuallyConvertToBool(SubstitutedExpression.get()); 231 if (SubstitutedExpression.isInvalid() || Trap.hasErrorOccurred()) { 232 // C++2a [temp.constr.atomic]p1 233 // ...If substitution results in an invalid type or expression, the 234 // constraint is not satisfied. 235 if (!Trap.hasErrorOccurred()) 236 // A non-SFINAE error has occurred as a result of this 237 // substitution. 238 return ExprError(); 239 240 PartialDiagnosticAt SubstDiag{SourceLocation(), 241 PartialDiagnostic::NullDiagnostic()}; 242 Info.takeSFINAEDiagnostic(SubstDiag); 243 // FIXME: Concepts: This is an unfortunate consequence of there 244 // being no serialization code for PartialDiagnostics and the fact 245 // that serializing them would likely take a lot more storage than 246 // just storing them as strings. We would still like, in the 247 // future, to serialize the proper PartialDiagnostic as serializing 248 // it as a string defeats the purpose of the diagnostic mechanism. 249 SmallString<128> DiagString; 250 DiagString = ": "; 251 SubstDiag.second.EmitToString(S.getDiagnostics(), DiagString); 252 unsigned MessageSize = DiagString.size(); 253 char *Mem = new (S.Context) char[MessageSize]; 254 memcpy(Mem, DiagString.c_str(), MessageSize); 255 Satisfaction.Details.emplace_back( 256 AtomicExpr, 257 new (S.Context) ConstraintSatisfaction::SubstitutionDiagnostic{ 258 SubstDiag.first, StringRef(Mem, MessageSize)}); 259 Satisfaction.IsSatisfied = false; 260 return ExprEmpty(); 261 } 262 } 263 264 if (!S.CheckConstraintExpression(SubstitutedExpression.get())) 265 return ExprError(); 266 267 return SubstitutedExpression; 268 }); 269 } 270 271 static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template, 272 ArrayRef<const Expr *> ConstraintExprs, 273 ArrayRef<TemplateArgument> TemplateArgs, 274 SourceRange TemplateIDRange, 275 ConstraintSatisfaction &Satisfaction) { 276 if (ConstraintExprs.empty()) { 277 Satisfaction.IsSatisfied = true; 278 return false; 279 } 280 281 for (auto& Arg : TemplateArgs) 282 if (Arg.isInstantiationDependent()) { 283 // No need to check satisfaction for dependent constraint expressions. 284 Satisfaction.IsSatisfied = true; 285 return false; 286 } 287 288 Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(), 289 Sema::InstantiatingTemplate::ConstraintsCheck{}, 290 const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange); 291 if (Inst.isInvalid()) 292 return true; 293 294 MultiLevelTemplateArgumentList MLTAL; 295 MLTAL.addOuterTemplateArguments(TemplateArgs); 296 297 for (const Expr *ConstraintExpr : ConstraintExprs) { 298 if (calculateConstraintSatisfaction(S, Template, TemplateArgs, 299 TemplateIDRange.getBegin(), MLTAL, 300 ConstraintExpr, Satisfaction)) 301 return true; 302 if (!Satisfaction.IsSatisfied) 303 // [temp.constr.op] p2 304 // [...] To determine if a conjunction is satisfied, the satisfaction 305 // of the first operand is checked. If that is not satisfied, the 306 // conjunction is not satisfied. [...] 307 return false; 308 } 309 return false; 310 } 311 312 bool Sema::CheckConstraintSatisfaction( 313 const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, 314 ArrayRef<TemplateArgument> TemplateArgs, SourceRange TemplateIDRange, 315 ConstraintSatisfaction &OutSatisfaction) { 316 if (ConstraintExprs.empty()) { 317 OutSatisfaction.IsSatisfied = true; 318 return false; 319 } 320 if (!Template) { 321 return ::CheckConstraintSatisfaction(*this, nullptr, ConstraintExprs, 322 TemplateArgs, TemplateIDRange, 323 OutSatisfaction); 324 } 325 llvm::FoldingSetNodeID ID; 326 ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs); 327 void *InsertPos; 328 if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) { 329 OutSatisfaction = *Cached; 330 return false; 331 } 332 auto Satisfaction = 333 std::make_unique<ConstraintSatisfaction>(Template, TemplateArgs); 334 if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs, 335 TemplateArgs, TemplateIDRange, 336 *Satisfaction)) { 337 return true; 338 } 339 OutSatisfaction = *Satisfaction; 340 // We cannot use InsertPos here because CheckConstraintSatisfaction might have 341 // invalidated it. 342 // Note that entries of SatisfactionCache are deleted in Sema's destructor. 343 SatisfactionCache.InsertNode(Satisfaction.release()); 344 return false; 345 } 346 347 bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr, 348 ConstraintSatisfaction &Satisfaction) { 349 return calculateConstraintSatisfaction( 350 *this, ConstraintExpr, Satisfaction, 351 [this](const Expr *AtomicExpr) -> ExprResult { 352 // We only do this to immitate lvalue-to-rvalue conversion. 353 return PerformContextuallyConvertToBool(const_cast<Expr *>(AtomicExpr)); 354 }); 355 } 356 357 bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, 358 ConstraintSatisfaction &Satisfaction, 359 SourceLocation UsageLoc) { 360 const Expr *RC = FD->getTrailingRequiresClause(); 361 if (RC->isInstantiationDependent()) { 362 Satisfaction.IsSatisfied = true; 363 return false; 364 } 365 Qualifiers ThisQuals; 366 CXXRecordDecl *Record = nullptr; 367 if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) { 368 ThisQuals = Method->getMethodQualifiers(); 369 Record = const_cast<CXXRecordDecl *>(Method->getParent()); 370 } 371 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); 372 // We substitute with empty arguments in order to rebuild the atomic 373 // constraint in a constant-evaluated context. 374 // FIXME: Should this be a dedicated TreeTransform? 375 return CheckConstraintSatisfaction( 376 FD, {RC}, /*TemplateArgs=*/{}, 377 SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()), 378 Satisfaction); 379 } 380 381 bool Sema::EnsureTemplateArgumentListConstraints( 382 TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs, 383 SourceRange TemplateIDRange) { 384 ConstraintSatisfaction Satisfaction; 385 llvm::SmallVector<const Expr *, 3> AssociatedConstraints; 386 TD->getAssociatedConstraints(AssociatedConstraints); 387 if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgs, 388 TemplateIDRange, Satisfaction)) 389 return true; 390 391 if (!Satisfaction.IsSatisfied) { 392 SmallString<128> TemplateArgString; 393 TemplateArgString = " "; 394 TemplateArgString += getTemplateArgumentBindingsText( 395 TD->getTemplateParameters(), TemplateArgs.data(), TemplateArgs.size()); 396 397 Diag(TemplateIDRange.getBegin(), 398 diag::err_template_arg_list_constraints_not_satisfied) 399 << (int)getTemplateNameKindForDiagnostics(TemplateName(TD)) << TD 400 << TemplateArgString << TemplateIDRange; 401 DiagnoseUnsatisfiedConstraint(Satisfaction); 402 return true; 403 } 404 return false; 405 } 406 407 bool Sema::CheckInstantiatedFunctionTemplateConstraints( 408 SourceLocation PointOfInstantiation, FunctionDecl *Decl, 409 ArrayRef<TemplateArgument> TemplateArgs, 410 ConstraintSatisfaction &Satisfaction) { 411 // In most cases we're not going to have constraints, so check for that first. 412 FunctionTemplateDecl *Template = Decl->getPrimaryTemplate(); 413 // Note - code synthesis context for the constraints check is created 414 // inside CheckConstraintsSatisfaction. 415 SmallVector<const Expr *, 3> TemplateAC; 416 Template->getAssociatedConstraints(TemplateAC); 417 if (TemplateAC.empty()) { 418 Satisfaction.IsSatisfied = true; 419 return false; 420 } 421 422 // Enter the scope of this instantiation. We don't use 423 // PushDeclContext because we don't have a scope. 424 Sema::ContextRAII savedContext(*this, Decl); 425 LocalInstantiationScope Scope(*this); 426 427 // If this is not an explicit specialization - we need to get the instantiated 428 // version of the template arguments and add them to scope for the 429 // substitution. 430 if (Decl->isTemplateInstantiation()) { 431 InstantiatingTemplate Inst(*this, Decl->getPointOfInstantiation(), 432 InstantiatingTemplate::ConstraintsCheck{}, Decl->getPrimaryTemplate(), 433 TemplateArgs, SourceRange()); 434 if (Inst.isInvalid()) 435 return true; 436 MultiLevelTemplateArgumentList MLTAL( 437 *Decl->getTemplateSpecializationArgs()); 438 if (addInstantiatedParametersToScope( 439 Decl, Decl->getPrimaryTemplate()->getTemplatedDecl(), Scope, MLTAL)) 440 return true; 441 } 442 Qualifiers ThisQuals; 443 CXXRecordDecl *Record = nullptr; 444 if (auto *Method = dyn_cast<CXXMethodDecl>(Decl)) { 445 ThisQuals = Method->getMethodQualifiers(); 446 Record = Method->getParent(); 447 } 448 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); 449 return CheckConstraintSatisfaction(Template, TemplateAC, TemplateArgs, 450 PointOfInstantiation, Satisfaction); 451 } 452 453 static void diagnoseUnsatisfiedRequirement(Sema &S, 454 concepts::ExprRequirement *Req, 455 bool First) { 456 assert(!Req->isSatisfied() 457 && "Diagnose() can only be used on an unsatisfied requirement"); 458 switch (Req->getSatisfactionStatus()) { 459 case concepts::ExprRequirement::SS_Dependent: 460 llvm_unreachable("Diagnosing a dependent requirement"); 461 break; 462 case concepts::ExprRequirement::SS_ExprSubstitutionFailure: { 463 auto *SubstDiag = Req->getExprSubstitutionDiagnostic(); 464 if (!SubstDiag->DiagMessage.empty()) 465 S.Diag(SubstDiag->DiagLoc, 466 diag::note_expr_requirement_expr_substitution_error) 467 << (int)First << SubstDiag->SubstitutedEntity 468 << SubstDiag->DiagMessage; 469 else 470 S.Diag(SubstDiag->DiagLoc, 471 diag::note_expr_requirement_expr_unknown_substitution_error) 472 << (int)First << SubstDiag->SubstitutedEntity; 473 break; 474 } 475 case concepts::ExprRequirement::SS_NoexceptNotMet: 476 S.Diag(Req->getNoexceptLoc(), 477 diag::note_expr_requirement_noexcept_not_met) 478 << (int)First << Req->getExpr(); 479 break; 480 case concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure: { 481 auto *SubstDiag = 482 Req->getReturnTypeRequirement().getSubstitutionDiagnostic(); 483 if (!SubstDiag->DiagMessage.empty()) 484 S.Diag(SubstDiag->DiagLoc, 485 diag::note_expr_requirement_type_requirement_substitution_error) 486 << (int)First << SubstDiag->SubstitutedEntity 487 << SubstDiag->DiagMessage; 488 else 489 S.Diag(SubstDiag->DiagLoc, 490 diag::note_expr_requirement_type_requirement_unknown_substitution_error) 491 << (int)First << SubstDiag->SubstitutedEntity; 492 break; 493 } 494 case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: { 495 ConceptSpecializationExpr *ConstraintExpr = 496 Req->getReturnTypeRequirementSubstitutedConstraintExpr(); 497 if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) { 498 // A simple case - expr type is the type being constrained and the concept 499 // was not provided arguments. 500 Expr *e = Req->getExpr(); 501 S.Diag(e->getBeginLoc(), 502 diag::note_expr_requirement_constraints_not_satisfied_simple) 503 << (int)First << S.Context.getReferenceQualifiedType(e) 504 << ConstraintExpr->getNamedConcept(); 505 } else { 506 S.Diag(ConstraintExpr->getBeginLoc(), 507 diag::note_expr_requirement_constraints_not_satisfied) 508 << (int)First << ConstraintExpr; 509 } 510 S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction()); 511 break; 512 } 513 case concepts::ExprRequirement::SS_Satisfied: 514 llvm_unreachable("We checked this above"); 515 } 516 } 517 518 static void diagnoseUnsatisfiedRequirement(Sema &S, 519 concepts::TypeRequirement *Req, 520 bool First) { 521 assert(!Req->isSatisfied() 522 && "Diagnose() can only be used on an unsatisfied requirement"); 523 switch (Req->getSatisfactionStatus()) { 524 case concepts::TypeRequirement::SS_Dependent: 525 llvm_unreachable("Diagnosing a dependent requirement"); 526 return; 527 case concepts::TypeRequirement::SS_SubstitutionFailure: { 528 auto *SubstDiag = Req->getSubstitutionDiagnostic(); 529 if (!SubstDiag->DiagMessage.empty()) 530 S.Diag(SubstDiag->DiagLoc, 531 diag::note_type_requirement_substitution_error) << (int)First 532 << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage; 533 else 534 S.Diag(SubstDiag->DiagLoc, 535 diag::note_type_requirement_unknown_substitution_error) 536 << (int)First << SubstDiag->SubstitutedEntity; 537 return; 538 } 539 default: 540 llvm_unreachable("Unknown satisfaction status"); 541 return; 542 } 543 } 544 545 static void diagnoseUnsatisfiedRequirement(Sema &S, 546 concepts::NestedRequirement *Req, 547 bool First) { 548 if (Req->isSubstitutionFailure()) { 549 concepts::Requirement::SubstitutionDiagnostic *SubstDiag = 550 Req->getSubstitutionDiagnostic(); 551 if (!SubstDiag->DiagMessage.empty()) 552 S.Diag(SubstDiag->DiagLoc, 553 diag::note_nested_requirement_substitution_error) 554 << (int)First << SubstDiag->SubstitutedEntity 555 << SubstDiag->DiagMessage; 556 else 557 S.Diag(SubstDiag->DiagLoc, 558 diag::note_nested_requirement_unknown_substitution_error) 559 << (int)First << SubstDiag->SubstitutedEntity; 560 return; 561 } 562 S.DiagnoseUnsatisfiedConstraint(Req->getConstraintSatisfaction(), First); 563 } 564 565 566 static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, 567 Expr *SubstExpr, 568 bool First = true) { 569 SubstExpr = SubstExpr->IgnoreParenImpCasts(); 570 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) { 571 switch (BO->getOpcode()) { 572 // These two cases will in practice only be reached when using fold 573 // expressions with || and &&, since otherwise the || and && will have been 574 // broken down into atomic constraints during satisfaction checking. 575 case BO_LOr: 576 // Or evaluated to false - meaning both RHS and LHS evaluated to false. 577 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First); 578 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), 579 /*First=*/false); 580 return; 581 case BO_LAnd: { 582 bool LHSSatisfied = 583 BO->getLHS()->EvaluateKnownConstInt(S.Context).getBoolValue(); 584 if (LHSSatisfied) { 585 // LHS is true, so RHS must be false. 586 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), First); 587 return; 588 } 589 // LHS is false 590 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First); 591 592 // RHS might also be false 593 bool RHSSatisfied = 594 BO->getRHS()->EvaluateKnownConstInt(S.Context).getBoolValue(); 595 if (!RHSSatisfied) 596 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), 597 /*First=*/false); 598 return; 599 } 600 case BO_GE: 601 case BO_LE: 602 case BO_GT: 603 case BO_LT: 604 case BO_EQ: 605 case BO_NE: 606 if (BO->getLHS()->getType()->isIntegerType() && 607 BO->getRHS()->getType()->isIntegerType()) { 608 Expr::EvalResult SimplifiedLHS; 609 Expr::EvalResult SimplifiedRHS; 610 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.Context, 611 Expr::SE_NoSideEffects, 612 /*InConstantContext=*/true); 613 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context, 614 Expr::SE_NoSideEffects, 615 /*InConstantContext=*/true); 616 if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) { 617 S.Diag(SubstExpr->getBeginLoc(), 618 diag::note_atomic_constraint_evaluated_to_false_elaborated) 619 << (int)First << SubstExpr 620 << toString(SimplifiedLHS.Val.getInt(), 10) 621 << BinaryOperator::getOpcodeStr(BO->getOpcode()) 622 << toString(SimplifiedRHS.Val.getInt(), 10); 623 return; 624 } 625 } 626 break; 627 628 default: 629 break; 630 } 631 } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) { 632 if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) { 633 S.Diag( 634 CSE->getSourceRange().getBegin(), 635 diag:: 636 note_single_arg_concept_specialization_constraint_evaluated_to_false) 637 << (int)First 638 << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument() 639 << CSE->getNamedConcept(); 640 } else { 641 S.Diag(SubstExpr->getSourceRange().getBegin(), 642 diag::note_concept_specialization_constraint_evaluated_to_false) 643 << (int)First << CSE; 644 } 645 S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction()); 646 return; 647 } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) { 648 for (concepts::Requirement *Req : RE->getRequirements()) 649 if (!Req->isDependent() && !Req->isSatisfied()) { 650 if (auto *E = dyn_cast<concepts::ExprRequirement>(Req)) 651 diagnoseUnsatisfiedRequirement(S, E, First); 652 else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req)) 653 diagnoseUnsatisfiedRequirement(S, T, First); 654 else 655 diagnoseUnsatisfiedRequirement( 656 S, cast<concepts::NestedRequirement>(Req), First); 657 break; 658 } 659 return; 660 } 661 662 S.Diag(SubstExpr->getSourceRange().getBegin(), 663 diag::note_atomic_constraint_evaluated_to_false) 664 << (int)First << SubstExpr; 665 } 666 667 template<typename SubstitutionDiagnostic> 668 static void diagnoseUnsatisfiedConstraintExpr( 669 Sema &S, const Expr *E, 670 const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record, 671 bool First = true) { 672 if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){ 673 S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed) 674 << Diag->second; 675 return; 676 } 677 678 diagnoseWellFormedUnsatisfiedConstraintExpr(S, 679 Record.template get<Expr *>(), First); 680 } 681 682 void 683 Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction, 684 bool First) { 685 assert(!Satisfaction.IsSatisfied && 686 "Attempted to diagnose a satisfied constraint"); 687 for (auto &Pair : Satisfaction.Details) { 688 diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First); 689 First = false; 690 } 691 } 692 693 void Sema::DiagnoseUnsatisfiedConstraint( 694 const ASTConstraintSatisfaction &Satisfaction, 695 bool First) { 696 assert(!Satisfaction.IsSatisfied && 697 "Attempted to diagnose a satisfied constraint"); 698 for (auto &Pair : Satisfaction) { 699 diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First); 700 First = false; 701 } 702 } 703 704 const NormalizedConstraint * 705 Sema::getNormalizedAssociatedConstraints( 706 NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) { 707 auto CacheEntry = NormalizationCache.find(ConstrainedDecl); 708 if (CacheEntry == NormalizationCache.end()) { 709 auto Normalized = 710 NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl, 711 AssociatedConstraints); 712 CacheEntry = 713 NormalizationCache 714 .try_emplace(ConstrainedDecl, 715 Normalized 716 ? new (Context) NormalizedConstraint( 717 std::move(*Normalized)) 718 : nullptr) 719 .first; 720 } 721 return CacheEntry->second; 722 } 723 724 static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, 725 ConceptDecl *Concept, ArrayRef<TemplateArgument> TemplateArgs, 726 const ASTTemplateArgumentListInfo *ArgsAsWritten) { 727 if (!N.isAtomic()) { 728 if (substituteParameterMappings(S, N.getLHS(), Concept, TemplateArgs, 729 ArgsAsWritten)) 730 return true; 731 return substituteParameterMappings(S, N.getRHS(), Concept, TemplateArgs, 732 ArgsAsWritten); 733 } 734 TemplateParameterList *TemplateParams = Concept->getTemplateParameters(); 735 736 AtomicConstraint &Atomic = *N.getAtomicConstraint(); 737 TemplateArgumentListInfo SubstArgs; 738 MultiLevelTemplateArgumentList MLTAL; 739 MLTAL.addOuterTemplateArguments(TemplateArgs); 740 if (!Atomic.ParameterMapping) { 741 llvm::SmallBitVector OccurringIndices(TemplateParams->size()); 742 S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false, 743 /*Depth=*/0, OccurringIndices); 744 Atomic.ParameterMapping.emplace( 745 MutableArrayRef<TemplateArgumentLoc>( 746 new (S.Context) TemplateArgumentLoc[OccurringIndices.count()], 747 OccurringIndices.count())); 748 for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I) 749 if (OccurringIndices[I]) 750 new (&(*Atomic.ParameterMapping)[J++]) TemplateArgumentLoc( 751 S.getIdentityTemplateArgumentLoc(TemplateParams->begin()[I], 752 // Here we assume we do not support things like 753 // template<typename A, typename B> 754 // concept C = ...; 755 // 756 // template<typename... Ts> requires C<Ts...> 757 // struct S { }; 758 // The above currently yields a diagnostic. 759 // We still might have default arguments for concept parameters. 760 ArgsAsWritten->NumTemplateArgs > I ? 761 ArgsAsWritten->arguments()[I].getLocation() : 762 SourceLocation())); 763 } 764 Sema::InstantiatingTemplate Inst( 765 S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(), 766 Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept, 767 SourceRange(ArgsAsWritten->arguments()[0].getSourceRange().getBegin(), 768 ArgsAsWritten->arguments().back().getSourceRange().getEnd())); 769 if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs)) 770 return true; 771 Atomic.ParameterMapping.emplace( 772 MutableArrayRef<TemplateArgumentLoc>( 773 new (S.Context) TemplateArgumentLoc[SubstArgs.size()], 774 SubstArgs.size())); 775 std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(), 776 N.getAtomicConstraint()->ParameterMapping->begin()); 777 return false; 778 } 779 780 Optional<NormalizedConstraint> 781 NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D, 782 ArrayRef<const Expr *> E) { 783 assert(E.size() != 0); 784 auto Conjunction = fromConstraintExpr(S, D, E[0]); 785 if (!Conjunction) 786 return None; 787 for (unsigned I = 1; I < E.size(); ++I) { 788 auto Next = fromConstraintExpr(S, D, E[I]); 789 if (!Next) 790 return None; 791 *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction), 792 std::move(*Next), CCK_Conjunction); 793 } 794 return Conjunction; 795 } 796 797 llvm::Optional<NormalizedConstraint> 798 NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) { 799 assert(E != nullptr); 800 801 // C++ [temp.constr.normal]p1.1 802 // [...] 803 // - The normal form of an expression (E) is the normal form of E. 804 // [...] 805 E = E->IgnoreParenImpCasts(); 806 if (LogicalBinOp BO = E) { 807 auto LHS = fromConstraintExpr(S, D, BO.getLHS()); 808 if (!LHS) 809 return None; 810 auto RHS = fromConstraintExpr(S, D, BO.getRHS()); 811 if (!RHS) 812 return None; 813 814 return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS), 815 BO.isAnd() ? CCK_Conjunction : CCK_Disjunction); 816 } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) { 817 const NormalizedConstraint *SubNF; 818 { 819 Sema::InstantiatingTemplate Inst( 820 S, CSE->getExprLoc(), 821 Sema::InstantiatingTemplate::ConstraintNormalization{}, D, 822 CSE->getSourceRange()); 823 // C++ [temp.constr.normal]p1.1 824 // [...] 825 // The normal form of an id-expression of the form C<A1, A2, ..., AN>, 826 // where C names a concept, is the normal form of the 827 // constraint-expression of C, after substituting A1, A2, ..., AN for C’s 828 // respective template parameters in the parameter mappings in each atomic 829 // constraint. If any such substitution results in an invalid type or 830 // expression, the program is ill-formed; no diagnostic is required. 831 // [...] 832 ConceptDecl *CD = CSE->getNamedConcept(); 833 SubNF = S.getNormalizedAssociatedConstraints(CD, 834 {CD->getConstraintExpr()}); 835 if (!SubNF) 836 return None; 837 } 838 839 Optional<NormalizedConstraint> New; 840 New.emplace(S.Context, *SubNF); 841 842 if (substituteParameterMappings( 843 S, *New, CSE->getNamedConcept(), 844 CSE->getTemplateArguments(), CSE->getTemplateArgsAsWritten())) 845 return None; 846 847 return New; 848 } 849 return NormalizedConstraint{new (S.Context) AtomicConstraint(S, E)}; 850 } 851 852 using NormalForm = 853 llvm::SmallVector<llvm::SmallVector<AtomicConstraint *, 2>, 4>; 854 855 static NormalForm makeCNF(const NormalizedConstraint &Normalized) { 856 if (Normalized.isAtomic()) 857 return {{Normalized.getAtomicConstraint()}}; 858 859 NormalForm LCNF = makeCNF(Normalized.getLHS()); 860 NormalForm RCNF = makeCNF(Normalized.getRHS()); 861 if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Conjunction) { 862 LCNF.reserve(LCNF.size() + RCNF.size()); 863 while (!RCNF.empty()) 864 LCNF.push_back(RCNF.pop_back_val()); 865 return LCNF; 866 } 867 868 // Disjunction 869 NormalForm Res; 870 Res.reserve(LCNF.size() * RCNF.size()); 871 for (auto &LDisjunction : LCNF) 872 for (auto &RDisjunction : RCNF) { 873 NormalForm::value_type Combined; 874 Combined.reserve(LDisjunction.size() + RDisjunction.size()); 875 std::copy(LDisjunction.begin(), LDisjunction.end(), 876 std::back_inserter(Combined)); 877 std::copy(RDisjunction.begin(), RDisjunction.end(), 878 std::back_inserter(Combined)); 879 Res.emplace_back(Combined); 880 } 881 return Res; 882 } 883 884 static NormalForm makeDNF(const NormalizedConstraint &Normalized) { 885 if (Normalized.isAtomic()) 886 return {{Normalized.getAtomicConstraint()}}; 887 888 NormalForm LDNF = makeDNF(Normalized.getLHS()); 889 NormalForm RDNF = makeDNF(Normalized.getRHS()); 890 if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Disjunction) { 891 LDNF.reserve(LDNF.size() + RDNF.size()); 892 while (!RDNF.empty()) 893 LDNF.push_back(RDNF.pop_back_val()); 894 return LDNF; 895 } 896 897 // Conjunction 898 NormalForm Res; 899 Res.reserve(LDNF.size() * RDNF.size()); 900 for (auto &LConjunction : LDNF) { 901 for (auto &RConjunction : RDNF) { 902 NormalForm::value_type Combined; 903 Combined.reserve(LConjunction.size() + RConjunction.size()); 904 std::copy(LConjunction.begin(), LConjunction.end(), 905 std::back_inserter(Combined)); 906 std::copy(RConjunction.begin(), RConjunction.end(), 907 std::back_inserter(Combined)); 908 Res.emplace_back(Combined); 909 } 910 } 911 return Res; 912 } 913 914 template<typename AtomicSubsumptionEvaluator> 915 static bool subsumes(NormalForm PDNF, NormalForm QCNF, 916 AtomicSubsumptionEvaluator E) { 917 // C++ [temp.constr.order] p2 918 // Then, P subsumes Q if and only if, for every disjunctive clause Pi in the 919 // disjunctive normal form of P, Pi subsumes every conjunctive clause Qj in 920 // the conjuctive normal form of Q, where [...] 921 for (const auto &Pi : PDNF) { 922 for (const auto &Qj : QCNF) { 923 // C++ [temp.constr.order] p2 924 // - [...] a disjunctive clause Pi subsumes a conjunctive clause Qj if 925 // and only if there exists an atomic constraint Pia in Pi for which 926 // there exists an atomic constraint, Qjb, in Qj such that Pia 927 // subsumes Qjb. 928 bool Found = false; 929 for (const AtomicConstraint *Pia : Pi) { 930 for (const AtomicConstraint *Qjb : Qj) { 931 if (E(*Pia, *Qjb)) { 932 Found = true; 933 break; 934 } 935 } 936 if (Found) 937 break; 938 } 939 if (!Found) 940 return false; 941 } 942 } 943 return true; 944 } 945 946 template<typename AtomicSubsumptionEvaluator> 947 static bool subsumes(Sema &S, NamedDecl *DP, ArrayRef<const Expr *> P, 948 NamedDecl *DQ, ArrayRef<const Expr *> Q, bool &Subsumes, 949 AtomicSubsumptionEvaluator E) { 950 // C++ [temp.constr.order] p2 951 // In order to determine if a constraint P subsumes a constraint Q, P is 952 // transformed into disjunctive normal form, and Q is transformed into 953 // conjunctive normal form. [...] 954 auto *PNormalized = S.getNormalizedAssociatedConstraints(DP, P); 955 if (!PNormalized) 956 return true; 957 const NormalForm PDNF = makeDNF(*PNormalized); 958 959 auto *QNormalized = S.getNormalizedAssociatedConstraints(DQ, Q); 960 if (!QNormalized) 961 return true; 962 const NormalForm QCNF = makeCNF(*QNormalized); 963 964 Subsumes = subsumes(PDNF, QCNF, E); 965 return false; 966 } 967 968 bool Sema::IsAtLeastAsConstrained(NamedDecl *D1, ArrayRef<const Expr *> AC1, 969 NamedDecl *D2, ArrayRef<const Expr *> AC2, 970 bool &Result) { 971 if (AC1.empty()) { 972 Result = AC2.empty(); 973 return false; 974 } 975 if (AC2.empty()) { 976 // TD1 has associated constraints and TD2 does not. 977 Result = true; 978 return false; 979 } 980 981 std::pair<NamedDecl *, NamedDecl *> Key{D1, D2}; 982 auto CacheEntry = SubsumptionCache.find(Key); 983 if (CacheEntry != SubsumptionCache.end()) { 984 Result = CacheEntry->second; 985 return false; 986 } 987 988 if (subsumes(*this, D1, AC1, D2, AC2, Result, 989 [this] (const AtomicConstraint &A, const AtomicConstraint &B) { 990 return A.subsumes(Context, B); 991 })) 992 return true; 993 SubsumptionCache.try_emplace(Key, Result); 994 return false; 995 } 996 997 bool Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1, 998 ArrayRef<const Expr *> AC1, NamedDecl *D2, ArrayRef<const Expr *> AC2) { 999 if (isSFINAEContext()) 1000 // No need to work here because our notes would be discarded. 1001 return false; 1002 1003 if (AC1.empty() || AC2.empty()) 1004 return false; 1005 1006 auto NormalExprEvaluator = 1007 [this] (const AtomicConstraint &A, const AtomicConstraint &B) { 1008 return A.subsumes(Context, B); 1009 }; 1010 1011 const Expr *AmbiguousAtomic1 = nullptr, *AmbiguousAtomic2 = nullptr; 1012 auto IdenticalExprEvaluator = 1013 [&] (const AtomicConstraint &A, const AtomicConstraint &B) { 1014 if (!A.hasMatchingParameterMapping(Context, B)) 1015 return false; 1016 const Expr *EA = A.ConstraintExpr, *EB = B.ConstraintExpr; 1017 if (EA == EB) 1018 return true; 1019 1020 // Not the same source level expression - are the expressions 1021 // identical? 1022 llvm::FoldingSetNodeID IDA, IDB; 1023 EA->Profile(IDA, Context, /*Canonical=*/true); 1024 EB->Profile(IDB, Context, /*Canonical=*/true); 1025 if (IDA != IDB) 1026 return false; 1027 1028 AmbiguousAtomic1 = EA; 1029 AmbiguousAtomic2 = EB; 1030 return true; 1031 }; 1032 1033 { 1034 // The subsumption checks might cause diagnostics 1035 SFINAETrap Trap(*this); 1036 auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1); 1037 if (!Normalized1) 1038 return false; 1039 const NormalForm DNF1 = makeDNF(*Normalized1); 1040 const NormalForm CNF1 = makeCNF(*Normalized1); 1041 1042 auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2); 1043 if (!Normalized2) 1044 return false; 1045 const NormalForm DNF2 = makeDNF(*Normalized2); 1046 const NormalForm CNF2 = makeCNF(*Normalized2); 1047 1048 bool Is1AtLeastAs2Normally = subsumes(DNF1, CNF2, NormalExprEvaluator); 1049 bool Is2AtLeastAs1Normally = subsumes(DNF2, CNF1, NormalExprEvaluator); 1050 bool Is1AtLeastAs2 = subsumes(DNF1, CNF2, IdenticalExprEvaluator); 1051 bool Is2AtLeastAs1 = subsumes(DNF2, CNF1, IdenticalExprEvaluator); 1052 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally && 1053 Is2AtLeastAs1 == Is2AtLeastAs1Normally) 1054 // Same result - no ambiguity was caused by identical atomic expressions. 1055 return false; 1056 } 1057 1058 // A different result! Some ambiguous atomic constraint(s) caused a difference 1059 assert(AmbiguousAtomic1 && AmbiguousAtomic2); 1060 1061 Diag(AmbiguousAtomic1->getBeginLoc(), diag::note_ambiguous_atomic_constraints) 1062 << AmbiguousAtomic1->getSourceRange(); 1063 Diag(AmbiguousAtomic2->getBeginLoc(), 1064 diag::note_ambiguous_atomic_constraints_similar_expression) 1065 << AmbiguousAtomic2->getSourceRange(); 1066 return true; 1067 } 1068 1069 concepts::ExprRequirement::ExprRequirement( 1070 Expr *E, bool IsSimple, SourceLocation NoexceptLoc, 1071 ReturnTypeRequirement Req, SatisfactionStatus Status, 1072 ConceptSpecializationExpr *SubstitutedConstraintExpr) : 1073 Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent, 1074 Status == SS_Dependent && 1075 (E->containsUnexpandedParameterPack() || 1076 Req.containsUnexpandedParameterPack()), 1077 Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc), 1078 TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr), 1079 Status(Status) { 1080 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) && 1081 "Simple requirement must not have a return type requirement or a " 1082 "noexcept specification"); 1083 assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) == 1084 (SubstitutedConstraintExpr != nullptr)); 1085 } 1086 1087 concepts::ExprRequirement::ExprRequirement( 1088 SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple, 1089 SourceLocation NoexceptLoc, ReturnTypeRequirement Req) : 1090 Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(), 1091 Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false), 1092 Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req), 1093 Status(SS_ExprSubstitutionFailure) { 1094 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) && 1095 "Simple requirement must not have a return type requirement or a " 1096 "noexcept specification"); 1097 } 1098 1099 concepts::ExprRequirement::ReturnTypeRequirement:: 1100 ReturnTypeRequirement(TemplateParameterList *TPL) : 1101 TypeConstraintInfo(TPL, false) { 1102 assert(TPL->size() == 1); 1103 const TypeConstraint *TC = 1104 cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint(); 1105 assert(TC && 1106 "TPL must have a template type parameter with a type constraint"); 1107 auto *Constraint = 1108 cast<ConceptSpecializationExpr>(TC->getImmediatelyDeclaredConstraint()); 1109 bool Dependent = 1110 Constraint->getTemplateArgsAsWritten() && 1111 TemplateSpecializationType::anyInstantiationDependentTemplateArguments( 1112 Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1)); 1113 TypeConstraintInfo.setInt(Dependent ? true : false); 1114 } 1115 1116 concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T) : 1117 Requirement(RK_Type, T->getType()->isInstantiationDependentType(), 1118 T->getType()->containsUnexpandedParameterPack(), 1119 // We reach this ctor with either dependent types (in which 1120 // IsSatisfied doesn't matter) or with non-dependent type in 1121 // which the existence of the type indicates satisfaction. 1122 /*IsSatisfied=*/true), 1123 Value(T), 1124 Status(T->getType()->isInstantiationDependentType() ? SS_Dependent 1125 : SS_Satisfied) {} 1126