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