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