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