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