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