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 321 llvm::FoldingSetNodeID ID; 322 void *InsertPos; 323 ConstraintSatisfaction *Satisfaction = nullptr; 324 bool ShouldCache = LangOpts.ConceptSatisfactionCaching && Template; 325 if (ShouldCache) { 326 ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs); 327 Satisfaction = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos); 328 if (Satisfaction) { 329 OutSatisfaction = *Satisfaction; 330 return false; 331 } 332 Satisfaction = new ConstraintSatisfaction(Template, TemplateArgs); 333 } else { 334 Satisfaction = &OutSatisfaction; 335 } 336 if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs, 337 TemplateArgs, TemplateIDRange, 338 *Satisfaction)) { 339 if (ShouldCache) 340 delete Satisfaction; 341 return true; 342 } 343 344 if (ShouldCache) { 345 // We cannot use InsertNode here because CheckConstraintSatisfaction might 346 // have invalidated it. 347 SatisfactionCache.InsertNode(Satisfaction); 348 OutSatisfaction = *Satisfaction; 349 } 350 return false; 351 } 352 353 bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr, 354 ConstraintSatisfaction &Satisfaction) { 355 return calculateConstraintSatisfaction( 356 *this, ConstraintExpr, Satisfaction, 357 [](const Expr *AtomicExpr) -> ExprResult { 358 return ExprResult(const_cast<Expr *>(AtomicExpr)); 359 }); 360 } 361 362 bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, 363 ConstraintSatisfaction &Satisfaction, 364 SourceLocation UsageLoc) { 365 const Expr *RC = FD->getTrailingRequiresClause(); 366 if (RC->isInstantiationDependent()) { 367 Satisfaction.IsSatisfied = true; 368 return false; 369 } 370 Qualifiers ThisQuals; 371 CXXRecordDecl *Record = nullptr; 372 if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) { 373 ThisQuals = Method->getMethodQualifiers(); 374 Record = const_cast<CXXRecordDecl *>(Method->getParent()); 375 } 376 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); 377 // We substitute with empty arguments in order to rebuild the atomic 378 // constraint in a constant-evaluated context. 379 // FIXME: Should this be a dedicated TreeTransform? 380 return CheckConstraintSatisfaction( 381 FD, {RC}, /*TemplateArgs=*/{}, 382 SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()), 383 Satisfaction); 384 } 385 386 bool Sema::EnsureTemplateArgumentListConstraints( 387 TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs, 388 SourceRange TemplateIDRange) { 389 ConstraintSatisfaction Satisfaction; 390 llvm::SmallVector<const Expr *, 3> AssociatedConstraints; 391 TD->getAssociatedConstraints(AssociatedConstraints); 392 if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgs, 393 TemplateIDRange, Satisfaction)) 394 return true; 395 396 if (!Satisfaction.IsSatisfied) { 397 SmallString<128> TemplateArgString; 398 TemplateArgString = " "; 399 TemplateArgString += getTemplateArgumentBindingsText( 400 TD->getTemplateParameters(), TemplateArgs.data(), TemplateArgs.size()); 401 402 Diag(TemplateIDRange.getBegin(), 403 diag::err_template_arg_list_constraints_not_satisfied) 404 << (int)getTemplateNameKindForDiagnostics(TemplateName(TD)) << TD 405 << TemplateArgString << TemplateIDRange; 406 DiagnoseUnsatisfiedConstraint(Satisfaction); 407 return true; 408 } 409 return false; 410 } 411 412 bool Sema::CheckInstantiatedFunctionTemplateConstraints( 413 SourceLocation PointOfInstantiation, FunctionDecl *Decl, 414 ArrayRef<TemplateArgument> TemplateArgs, 415 ConstraintSatisfaction &Satisfaction) { 416 // In most cases we're not going to have constraints, so check for that first. 417 FunctionTemplateDecl *Template = Decl->getPrimaryTemplate(); 418 // Note - code synthesis context for the constraints check is created 419 // inside CheckConstraintsSatisfaction. 420 SmallVector<const Expr *, 3> TemplateAC; 421 Template->getAssociatedConstraints(TemplateAC); 422 if (TemplateAC.empty()) { 423 Satisfaction.IsSatisfied = true; 424 return false; 425 } 426 427 // Enter the scope of this instantiation. We don't use 428 // PushDeclContext because we don't have a scope. 429 Sema::ContextRAII savedContext(*this, Decl); 430 LocalInstantiationScope Scope(*this); 431 432 // If this is not an explicit specialization - we need to get the instantiated 433 // version of the template arguments and add them to scope for the 434 // substitution. 435 if (Decl->isTemplateInstantiation()) { 436 InstantiatingTemplate Inst(*this, Decl->getPointOfInstantiation(), 437 InstantiatingTemplate::ConstraintsCheck{}, Decl->getPrimaryTemplate(), 438 TemplateArgs, SourceRange()); 439 if (Inst.isInvalid()) 440 return true; 441 MultiLevelTemplateArgumentList MLTAL( 442 *Decl->getTemplateSpecializationArgs()); 443 if (addInstantiatedParametersToScope( 444 Decl, Decl->getPrimaryTemplate()->getTemplatedDecl(), Scope, MLTAL)) 445 return true; 446 } 447 Qualifiers ThisQuals; 448 CXXRecordDecl *Record = nullptr; 449 if (auto *Method = dyn_cast<CXXMethodDecl>(Decl)) { 450 ThisQuals = Method->getMethodQualifiers(); 451 Record = Method->getParent(); 452 } 453 CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); 454 return CheckConstraintSatisfaction(Template, TemplateAC, TemplateArgs, 455 PointOfInstantiation, Satisfaction); 456 } 457 458 static void diagnoseUnsatisfiedRequirement(Sema &S, 459 concepts::ExprRequirement *Req, 460 bool First) { 461 assert(!Req->isSatisfied() 462 && "Diagnose() can only be used on an unsatisfied requirement"); 463 switch (Req->getSatisfactionStatus()) { 464 case concepts::ExprRequirement::SS_Dependent: 465 llvm_unreachable("Diagnosing a dependent requirement"); 466 break; 467 case concepts::ExprRequirement::SS_ExprSubstitutionFailure: { 468 auto *SubstDiag = Req->getExprSubstitutionDiagnostic(); 469 if (!SubstDiag->DiagMessage.empty()) 470 S.Diag(SubstDiag->DiagLoc, 471 diag::note_expr_requirement_expr_substitution_error) 472 << (int)First << SubstDiag->SubstitutedEntity 473 << SubstDiag->DiagMessage; 474 else 475 S.Diag(SubstDiag->DiagLoc, 476 diag::note_expr_requirement_expr_unknown_substitution_error) 477 << (int)First << SubstDiag->SubstitutedEntity; 478 break; 479 } 480 case concepts::ExprRequirement::SS_NoexceptNotMet: 481 S.Diag(Req->getNoexceptLoc(), 482 diag::note_expr_requirement_noexcept_not_met) 483 << (int)First << Req->getExpr(); 484 break; 485 case concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure: { 486 auto *SubstDiag = 487 Req->getReturnTypeRequirement().getSubstitutionDiagnostic(); 488 if (!SubstDiag->DiagMessage.empty()) 489 S.Diag(SubstDiag->DiagLoc, 490 diag::note_expr_requirement_type_requirement_substitution_error) 491 << (int)First << SubstDiag->SubstitutedEntity 492 << SubstDiag->DiagMessage; 493 else 494 S.Diag(SubstDiag->DiagLoc, 495 diag::note_expr_requirement_type_requirement_unknown_substitution_error) 496 << (int)First << SubstDiag->SubstitutedEntity; 497 break; 498 } 499 case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: { 500 ConceptSpecializationExpr *ConstraintExpr = 501 Req->getReturnTypeRequirementSubstitutedConstraintExpr(); 502 if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) { 503 // A simple case - expr type is the type being constrained and the concept 504 // was not provided arguments. 505 Expr *e = Req->getExpr(); 506 S.Diag(e->getBeginLoc(), 507 diag::note_expr_requirement_constraints_not_satisfied_simple) 508 << (int)First << S.Context.getReferenceQualifiedType(e) 509 << ConstraintExpr->getNamedConcept(); 510 } else { 511 S.Diag(ConstraintExpr->getBeginLoc(), 512 diag::note_expr_requirement_constraints_not_satisfied) 513 << (int)First << ConstraintExpr; 514 } 515 S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction()); 516 break; 517 } 518 case concepts::ExprRequirement::SS_Satisfied: 519 llvm_unreachable("We checked this above"); 520 } 521 } 522 523 static void diagnoseUnsatisfiedRequirement(Sema &S, 524 concepts::TypeRequirement *Req, 525 bool First) { 526 assert(!Req->isSatisfied() 527 && "Diagnose() can only be used on an unsatisfied requirement"); 528 switch (Req->getSatisfactionStatus()) { 529 case concepts::TypeRequirement::SS_Dependent: 530 llvm_unreachable("Diagnosing a dependent requirement"); 531 return; 532 case concepts::TypeRequirement::SS_SubstitutionFailure: { 533 auto *SubstDiag = Req->getSubstitutionDiagnostic(); 534 if (!SubstDiag->DiagMessage.empty()) 535 S.Diag(SubstDiag->DiagLoc, 536 diag::note_type_requirement_substitution_error) << (int)First 537 << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage; 538 else 539 S.Diag(SubstDiag->DiagLoc, 540 diag::note_type_requirement_unknown_substitution_error) 541 << (int)First << SubstDiag->SubstitutedEntity; 542 return; 543 } 544 default: 545 llvm_unreachable("Unknown satisfaction status"); 546 return; 547 } 548 } 549 550 static void diagnoseUnsatisfiedRequirement(Sema &S, 551 concepts::NestedRequirement *Req, 552 bool First) { 553 if (Req->isSubstitutionFailure()) { 554 concepts::Requirement::SubstitutionDiagnostic *SubstDiag = 555 Req->getSubstitutionDiagnostic(); 556 if (!SubstDiag->DiagMessage.empty()) 557 S.Diag(SubstDiag->DiagLoc, 558 diag::note_nested_requirement_substitution_error) 559 << (int)First << SubstDiag->SubstitutedEntity 560 << SubstDiag->DiagMessage; 561 else 562 S.Diag(SubstDiag->DiagLoc, 563 diag::note_nested_requirement_unknown_substitution_error) 564 << (int)First << SubstDiag->SubstitutedEntity; 565 return; 566 } 567 S.DiagnoseUnsatisfiedConstraint(Req->getConstraintSatisfaction(), First); 568 } 569 570 571 static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S, 572 Expr *SubstExpr, 573 bool First = true) { 574 SubstExpr = SubstExpr->IgnoreParenImpCasts(); 575 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) { 576 switch (BO->getOpcode()) { 577 // These two cases will in practice only be reached when using fold 578 // expressions with || and &&, since otherwise the || and && will have been 579 // broken down into atomic constraints during satisfaction checking. 580 case BO_LOr: 581 // Or evaluated to false - meaning both RHS and LHS evaluated to false. 582 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First); 583 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), 584 /*First=*/false); 585 return; 586 case BO_LAnd: { 587 bool LHSSatisfied = 588 BO->getLHS()->EvaluateKnownConstInt(S.Context).getBoolValue(); 589 if (LHSSatisfied) { 590 // LHS is true, so RHS must be false. 591 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), First); 592 return; 593 } 594 // LHS is false 595 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First); 596 597 // RHS might also be false 598 bool RHSSatisfied = 599 BO->getRHS()->EvaluateKnownConstInt(S.Context).getBoolValue(); 600 if (!RHSSatisfied) 601 diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), 602 /*First=*/false); 603 return; 604 } 605 case BO_GE: 606 case BO_LE: 607 case BO_GT: 608 case BO_LT: 609 case BO_EQ: 610 case BO_NE: 611 if (BO->getLHS()->getType()->isIntegerType() && 612 BO->getRHS()->getType()->isIntegerType()) { 613 Expr::EvalResult SimplifiedLHS; 614 Expr::EvalResult SimplifiedRHS; 615 BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.Context, 616 Expr::SE_NoSideEffects, 617 /*InConstantContext=*/true); 618 BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context, 619 Expr::SE_NoSideEffects, 620 /*InConstantContext=*/true); 621 if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) { 622 S.Diag(SubstExpr->getBeginLoc(), 623 diag::note_atomic_constraint_evaluated_to_false_elaborated) 624 << (int)First << SubstExpr 625 << toString(SimplifiedLHS.Val.getInt(), 10) 626 << BinaryOperator::getOpcodeStr(BO->getOpcode()) 627 << toString(SimplifiedRHS.Val.getInt(), 10); 628 return; 629 } 630 } 631 break; 632 633 default: 634 break; 635 } 636 } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) { 637 if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) { 638 S.Diag( 639 CSE->getSourceRange().getBegin(), 640 diag:: 641 note_single_arg_concept_specialization_constraint_evaluated_to_false) 642 << (int)First 643 << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument() 644 << CSE->getNamedConcept(); 645 } else { 646 S.Diag(SubstExpr->getSourceRange().getBegin(), 647 diag::note_concept_specialization_constraint_evaluated_to_false) 648 << (int)First << CSE; 649 } 650 S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction()); 651 return; 652 } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) { 653 for (concepts::Requirement *Req : RE->getRequirements()) 654 if (!Req->isDependent() && !Req->isSatisfied()) { 655 if (auto *E = dyn_cast<concepts::ExprRequirement>(Req)) 656 diagnoseUnsatisfiedRequirement(S, E, First); 657 else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req)) 658 diagnoseUnsatisfiedRequirement(S, T, First); 659 else 660 diagnoseUnsatisfiedRequirement( 661 S, cast<concepts::NestedRequirement>(Req), First); 662 break; 663 } 664 return; 665 } 666 667 S.Diag(SubstExpr->getSourceRange().getBegin(), 668 diag::note_atomic_constraint_evaluated_to_false) 669 << (int)First << SubstExpr; 670 } 671 672 template<typename SubstitutionDiagnostic> 673 static void diagnoseUnsatisfiedConstraintExpr( 674 Sema &S, const Expr *E, 675 const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record, 676 bool First = true) { 677 if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){ 678 S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed) 679 << Diag->second; 680 return; 681 } 682 683 diagnoseWellFormedUnsatisfiedConstraintExpr(S, 684 Record.template get<Expr *>(), First); 685 } 686 687 void 688 Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction, 689 bool First) { 690 assert(!Satisfaction.IsSatisfied && 691 "Attempted to diagnose a satisfied constraint"); 692 for (auto &Pair : Satisfaction.Details) { 693 diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First); 694 First = false; 695 } 696 } 697 698 void Sema::DiagnoseUnsatisfiedConstraint( 699 const ASTConstraintSatisfaction &Satisfaction, 700 bool First) { 701 assert(!Satisfaction.IsSatisfied && 702 "Attempted to diagnose a satisfied constraint"); 703 for (auto &Pair : Satisfaction) { 704 diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First); 705 First = false; 706 } 707 } 708 709 const NormalizedConstraint * 710 Sema::getNormalizedAssociatedConstraints( 711 NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) { 712 auto CacheEntry = NormalizationCache.find(ConstrainedDecl); 713 if (CacheEntry == NormalizationCache.end()) { 714 auto Normalized = 715 NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl, 716 AssociatedConstraints); 717 CacheEntry = 718 NormalizationCache 719 .try_emplace(ConstrainedDecl, 720 Normalized 721 ? new (Context) NormalizedConstraint( 722 std::move(*Normalized)) 723 : nullptr) 724 .first; 725 } 726 return CacheEntry->second; 727 } 728 729 static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, 730 ConceptDecl *Concept, ArrayRef<TemplateArgument> TemplateArgs, 731 const ASTTemplateArgumentListInfo *ArgsAsWritten) { 732 if (!N.isAtomic()) { 733 if (substituteParameterMappings(S, N.getLHS(), Concept, TemplateArgs, 734 ArgsAsWritten)) 735 return true; 736 return substituteParameterMappings(S, N.getRHS(), Concept, TemplateArgs, 737 ArgsAsWritten); 738 } 739 TemplateParameterList *TemplateParams = Concept->getTemplateParameters(); 740 741 AtomicConstraint &Atomic = *N.getAtomicConstraint(); 742 TemplateArgumentListInfo SubstArgs; 743 MultiLevelTemplateArgumentList MLTAL; 744 MLTAL.addOuterTemplateArguments(TemplateArgs); 745 if (!Atomic.ParameterMapping) { 746 llvm::SmallBitVector OccurringIndices(TemplateParams->size()); 747 S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false, 748 /*Depth=*/0, OccurringIndices); 749 Atomic.ParameterMapping.emplace( 750 MutableArrayRef<TemplateArgumentLoc>( 751 new (S.Context) TemplateArgumentLoc[OccurringIndices.count()], 752 OccurringIndices.count())); 753 for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I) 754 if (OccurringIndices[I]) 755 new (&(*Atomic.ParameterMapping)[J++]) TemplateArgumentLoc( 756 S.getIdentityTemplateArgumentLoc(TemplateParams->begin()[I], 757 // Here we assume we do not support things like 758 // template<typename A, typename B> 759 // concept C = ...; 760 // 761 // template<typename... Ts> requires C<Ts...> 762 // struct S { }; 763 // The above currently yields a diagnostic. 764 // We still might have default arguments for concept parameters. 765 ArgsAsWritten->NumTemplateArgs > I ? 766 ArgsAsWritten->arguments()[I].getLocation() : 767 SourceLocation())); 768 } 769 Sema::InstantiatingTemplate Inst( 770 S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(), 771 Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept, 772 SourceRange(ArgsAsWritten->arguments()[0].getSourceRange().getBegin(), 773 ArgsAsWritten->arguments().back().getSourceRange().getEnd())); 774 if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs)) 775 return true; 776 Atomic.ParameterMapping.emplace( 777 MutableArrayRef<TemplateArgumentLoc>( 778 new (S.Context) TemplateArgumentLoc[SubstArgs.size()], 779 SubstArgs.size())); 780 std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(), 781 N.getAtomicConstraint()->ParameterMapping->begin()); 782 return false; 783 } 784 785 Optional<NormalizedConstraint> 786 NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D, 787 ArrayRef<const Expr *> E) { 788 assert(E.size() != 0); 789 auto Conjunction = fromConstraintExpr(S, D, E[0]); 790 if (!Conjunction) 791 return None; 792 for (unsigned I = 1; I < E.size(); ++I) { 793 auto Next = fromConstraintExpr(S, D, E[I]); 794 if (!Next) 795 return None; 796 *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction), 797 std::move(*Next), CCK_Conjunction); 798 } 799 return Conjunction; 800 } 801 802 llvm::Optional<NormalizedConstraint> 803 NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) { 804 assert(E != nullptr); 805 806 // C++ [temp.constr.normal]p1.1 807 // [...] 808 // - The normal form of an expression (E) is the normal form of E. 809 // [...] 810 E = E->IgnoreParenImpCasts(); 811 if (LogicalBinOp BO = E) { 812 auto LHS = fromConstraintExpr(S, D, BO.getLHS()); 813 if (!LHS) 814 return None; 815 auto RHS = fromConstraintExpr(S, D, BO.getRHS()); 816 if (!RHS) 817 return None; 818 819 return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS), 820 BO.isAnd() ? CCK_Conjunction : CCK_Disjunction); 821 } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) { 822 const NormalizedConstraint *SubNF; 823 { 824 Sema::InstantiatingTemplate Inst( 825 S, CSE->getExprLoc(), 826 Sema::InstantiatingTemplate::ConstraintNormalization{}, D, 827 CSE->getSourceRange()); 828 // C++ [temp.constr.normal]p1.1 829 // [...] 830 // The normal form of an id-expression of the form C<A1, A2, ..., AN>, 831 // where C names a concept, is the normal form of the 832 // constraint-expression of C, after substituting A1, A2, ..., AN for C’s 833 // respective template parameters in the parameter mappings in each atomic 834 // constraint. If any such substitution results in an invalid type or 835 // expression, the program is ill-formed; no diagnostic is required. 836 // [...] 837 ConceptDecl *CD = CSE->getNamedConcept(); 838 SubNF = S.getNormalizedAssociatedConstraints(CD, 839 {CD->getConstraintExpr()}); 840 if (!SubNF) 841 return None; 842 } 843 844 Optional<NormalizedConstraint> New; 845 New.emplace(S.Context, *SubNF); 846 847 if (substituteParameterMappings( 848 S, *New, CSE->getNamedConcept(), 849 CSE->getTemplateArguments(), CSE->getTemplateArgsAsWritten())) 850 return None; 851 852 return New; 853 } 854 return NormalizedConstraint{new (S.Context) AtomicConstraint(S, E)}; 855 } 856 857 using NormalForm = 858 llvm::SmallVector<llvm::SmallVector<AtomicConstraint *, 2>, 4>; 859 860 static NormalForm makeCNF(const NormalizedConstraint &Normalized) { 861 if (Normalized.isAtomic()) 862 return {{Normalized.getAtomicConstraint()}}; 863 864 NormalForm LCNF = makeCNF(Normalized.getLHS()); 865 NormalForm RCNF = makeCNF(Normalized.getRHS()); 866 if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Conjunction) { 867 LCNF.reserve(LCNF.size() + RCNF.size()); 868 while (!RCNF.empty()) 869 LCNF.push_back(RCNF.pop_back_val()); 870 return LCNF; 871 } 872 873 // Disjunction 874 NormalForm Res; 875 Res.reserve(LCNF.size() * RCNF.size()); 876 for (auto &LDisjunction : LCNF) 877 for (auto &RDisjunction : RCNF) { 878 NormalForm::value_type Combined; 879 Combined.reserve(LDisjunction.size() + RDisjunction.size()); 880 std::copy(LDisjunction.begin(), LDisjunction.end(), 881 std::back_inserter(Combined)); 882 std::copy(RDisjunction.begin(), RDisjunction.end(), 883 std::back_inserter(Combined)); 884 Res.emplace_back(Combined); 885 } 886 return Res; 887 } 888 889 static NormalForm makeDNF(const NormalizedConstraint &Normalized) { 890 if (Normalized.isAtomic()) 891 return {{Normalized.getAtomicConstraint()}}; 892 893 NormalForm LDNF = makeDNF(Normalized.getLHS()); 894 NormalForm RDNF = makeDNF(Normalized.getRHS()); 895 if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Disjunction) { 896 LDNF.reserve(LDNF.size() + RDNF.size()); 897 while (!RDNF.empty()) 898 LDNF.push_back(RDNF.pop_back_val()); 899 return LDNF; 900 } 901 902 // Conjunction 903 NormalForm Res; 904 Res.reserve(LDNF.size() * RDNF.size()); 905 for (auto &LConjunction : LDNF) { 906 for (auto &RConjunction : RDNF) { 907 NormalForm::value_type Combined; 908 Combined.reserve(LConjunction.size() + RConjunction.size()); 909 std::copy(LConjunction.begin(), LConjunction.end(), 910 std::back_inserter(Combined)); 911 std::copy(RConjunction.begin(), RConjunction.end(), 912 std::back_inserter(Combined)); 913 Res.emplace_back(Combined); 914 } 915 } 916 return Res; 917 } 918 919 template<typename AtomicSubsumptionEvaluator> 920 static bool subsumes(NormalForm PDNF, NormalForm QCNF, 921 AtomicSubsumptionEvaluator E) { 922 // C++ [temp.constr.order] p2 923 // Then, P subsumes Q if and only if, for every disjunctive clause Pi in the 924 // disjunctive normal form of P, Pi subsumes every conjunctive clause Qj in 925 // the conjuctive normal form of Q, where [...] 926 for (const auto &Pi : PDNF) { 927 for (const auto &Qj : QCNF) { 928 // C++ [temp.constr.order] p2 929 // - [...] a disjunctive clause Pi subsumes a conjunctive clause Qj if 930 // and only if there exists an atomic constraint Pia in Pi for which 931 // there exists an atomic constraint, Qjb, in Qj such that Pia 932 // subsumes Qjb. 933 bool Found = false; 934 for (const AtomicConstraint *Pia : Pi) { 935 for (const AtomicConstraint *Qjb : Qj) { 936 if (E(*Pia, *Qjb)) { 937 Found = true; 938 break; 939 } 940 } 941 if (Found) 942 break; 943 } 944 if (!Found) 945 return false; 946 } 947 } 948 return true; 949 } 950 951 template<typename AtomicSubsumptionEvaluator> 952 static bool subsumes(Sema &S, NamedDecl *DP, ArrayRef<const Expr *> P, 953 NamedDecl *DQ, ArrayRef<const Expr *> Q, bool &Subsumes, 954 AtomicSubsumptionEvaluator E) { 955 // C++ [temp.constr.order] p2 956 // In order to determine if a constraint P subsumes a constraint Q, P is 957 // transformed into disjunctive normal form, and Q is transformed into 958 // conjunctive normal form. [...] 959 auto *PNormalized = S.getNormalizedAssociatedConstraints(DP, P); 960 if (!PNormalized) 961 return true; 962 const NormalForm PDNF = makeDNF(*PNormalized); 963 964 auto *QNormalized = S.getNormalizedAssociatedConstraints(DQ, Q); 965 if (!QNormalized) 966 return true; 967 const NormalForm QCNF = makeCNF(*QNormalized); 968 969 Subsumes = subsumes(PDNF, QCNF, E); 970 return false; 971 } 972 973 bool Sema::IsAtLeastAsConstrained(NamedDecl *D1, ArrayRef<const Expr *> AC1, 974 NamedDecl *D2, ArrayRef<const Expr *> AC2, 975 bool &Result) { 976 if (AC1.empty()) { 977 Result = AC2.empty(); 978 return false; 979 } 980 if (AC2.empty()) { 981 // TD1 has associated constraints and TD2 does not. 982 Result = true; 983 return false; 984 } 985 986 std::pair<NamedDecl *, NamedDecl *> Key{D1, D2}; 987 auto CacheEntry = SubsumptionCache.find(Key); 988 if (CacheEntry != SubsumptionCache.end()) { 989 Result = CacheEntry->second; 990 return false; 991 } 992 993 if (subsumes(*this, D1, AC1, D2, AC2, Result, 994 [this] (const AtomicConstraint &A, const AtomicConstraint &B) { 995 return A.subsumes(Context, B); 996 })) 997 return true; 998 SubsumptionCache.try_emplace(Key, Result); 999 return false; 1000 } 1001 1002 bool Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1, 1003 ArrayRef<const Expr *> AC1, NamedDecl *D2, ArrayRef<const Expr *> AC2) { 1004 if (isSFINAEContext()) 1005 // No need to work here because our notes would be discarded. 1006 return false; 1007 1008 if (AC1.empty() || AC2.empty()) 1009 return false; 1010 1011 auto NormalExprEvaluator = 1012 [this] (const AtomicConstraint &A, const AtomicConstraint &B) { 1013 return A.subsumes(Context, B); 1014 }; 1015 1016 const Expr *AmbiguousAtomic1 = nullptr, *AmbiguousAtomic2 = nullptr; 1017 auto IdenticalExprEvaluator = 1018 [&] (const AtomicConstraint &A, const AtomicConstraint &B) { 1019 if (!A.hasMatchingParameterMapping(Context, B)) 1020 return false; 1021 const Expr *EA = A.ConstraintExpr, *EB = B.ConstraintExpr; 1022 if (EA == EB) 1023 return true; 1024 1025 // Not the same source level expression - are the expressions 1026 // identical? 1027 llvm::FoldingSetNodeID IDA, IDB; 1028 EA->Profile(IDA, Context, /*Canonical=*/true); 1029 EB->Profile(IDB, Context, /*Canonical=*/true); 1030 if (IDA != IDB) 1031 return false; 1032 1033 AmbiguousAtomic1 = EA; 1034 AmbiguousAtomic2 = EB; 1035 return true; 1036 }; 1037 1038 { 1039 // The subsumption checks might cause diagnostics 1040 SFINAETrap Trap(*this); 1041 auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1); 1042 if (!Normalized1) 1043 return false; 1044 const NormalForm DNF1 = makeDNF(*Normalized1); 1045 const NormalForm CNF1 = makeCNF(*Normalized1); 1046 1047 auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2); 1048 if (!Normalized2) 1049 return false; 1050 const NormalForm DNF2 = makeDNF(*Normalized2); 1051 const NormalForm CNF2 = makeCNF(*Normalized2); 1052 1053 bool Is1AtLeastAs2Normally = subsumes(DNF1, CNF2, NormalExprEvaluator); 1054 bool Is2AtLeastAs1Normally = subsumes(DNF2, CNF1, NormalExprEvaluator); 1055 bool Is1AtLeastAs2 = subsumes(DNF1, CNF2, IdenticalExprEvaluator); 1056 bool Is2AtLeastAs1 = subsumes(DNF2, CNF1, IdenticalExprEvaluator); 1057 if (Is1AtLeastAs2 == Is1AtLeastAs2Normally && 1058 Is2AtLeastAs1 == Is2AtLeastAs1Normally) 1059 // Same result - no ambiguity was caused by identical atomic expressions. 1060 return false; 1061 } 1062 1063 // A different result! Some ambiguous atomic constraint(s) caused a difference 1064 assert(AmbiguousAtomic1 && AmbiguousAtomic2); 1065 1066 Diag(AmbiguousAtomic1->getBeginLoc(), diag::note_ambiguous_atomic_constraints) 1067 << AmbiguousAtomic1->getSourceRange(); 1068 Diag(AmbiguousAtomic2->getBeginLoc(), 1069 diag::note_ambiguous_atomic_constraints_similar_expression) 1070 << AmbiguousAtomic2->getSourceRange(); 1071 return true; 1072 } 1073 1074 concepts::ExprRequirement::ExprRequirement( 1075 Expr *E, bool IsSimple, SourceLocation NoexceptLoc, 1076 ReturnTypeRequirement Req, SatisfactionStatus Status, 1077 ConceptSpecializationExpr *SubstitutedConstraintExpr) : 1078 Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent, 1079 Status == SS_Dependent && 1080 (E->containsUnexpandedParameterPack() || 1081 Req.containsUnexpandedParameterPack()), 1082 Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc), 1083 TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr), 1084 Status(Status) { 1085 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) && 1086 "Simple requirement must not have a return type requirement or a " 1087 "noexcept specification"); 1088 assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) == 1089 (SubstitutedConstraintExpr != nullptr)); 1090 } 1091 1092 concepts::ExprRequirement::ExprRequirement( 1093 SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple, 1094 SourceLocation NoexceptLoc, ReturnTypeRequirement Req) : 1095 Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(), 1096 Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false), 1097 Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req), 1098 Status(SS_ExprSubstitutionFailure) { 1099 assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) && 1100 "Simple requirement must not have a return type requirement or a " 1101 "noexcept specification"); 1102 } 1103 1104 concepts::ExprRequirement::ReturnTypeRequirement:: 1105 ReturnTypeRequirement(TemplateParameterList *TPL) : 1106 TypeConstraintInfo(TPL, false) { 1107 assert(TPL->size() == 1); 1108 const TypeConstraint *TC = 1109 cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint(); 1110 assert(TC && 1111 "TPL must have a template type parameter with a type constraint"); 1112 auto *Constraint = 1113 cast<ConceptSpecializationExpr>(TC->getImmediatelyDeclaredConstraint()); 1114 bool Dependent = 1115 Constraint->getTemplateArgsAsWritten() && 1116 TemplateSpecializationType::anyInstantiationDependentTemplateArguments( 1117 Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1)); 1118 TypeConstraintInfo.setInt(Dependent ? true : false); 1119 } 1120 1121 concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T) : 1122 Requirement(RK_Type, T->getType()->isInstantiationDependentType(), 1123 T->getType()->containsUnexpandedParameterPack(), 1124 // We reach this ctor with either dependent types (in which 1125 // IsSatisfied doesn't matter) or with non-dependent type in 1126 // which the existence of the type indicates satisfaction. 1127 /*IsSatisfied=*/true), 1128 Value(T), 1129 Status(T->getType()->isInstantiationDependentType() ? SS_Dependent 1130 : SS_Satisfied) {} 1131