Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Sema/SemaConcept.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- SemaConcept.cpp - Semantic Analysis for Constraints and Concepts --===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file implements semantic analysis for C++ constraints and concepts.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Sema/SemaConcept.h"
14
#include "TreeTransform.h"
15
#include "clang/AST/ASTLambda.h"
16
#include "clang/AST/DeclCXX.h"
17
#include "clang/AST/ExprConcepts.h"
18
#include "clang/AST/RecursiveASTVisitor.h"
19
#include "clang/Basic/OperatorPrecedence.h"
20
#include "clang/Sema/EnterExpressionEvaluationContext.h"
21
#include "clang/Sema/Initialization.h"
22
#include "clang/Sema/Overload.h"
23
#include "clang/Sema/ScopeInfo.h"
24
#include "clang/Sema/Sema.h"
25
#include "clang/Sema/SemaDiagnostic.h"
26
#include "clang/Sema/SemaInternal.h"
27
#include "clang/Sema/Template.h"
28
#include "clang/Sema/TemplateDeduction.h"
29
#include "llvm/ADT/DenseMap.h"
30
#include "llvm/ADT/PointerUnion.h"
31
#include "llvm/ADT/StringExtras.h"
32
#include <optional>
33
34
using namespace clang;
35
using namespace sema;
36
37
namespace {
38
class LogicalBinOp {
39
  SourceLocation Loc;
40
  OverloadedOperatorKind Op = OO_None;
41
  const Expr *LHS = nullptr;
42
  const Expr *RHS = nullptr;
43
44
public:
45
0
  LogicalBinOp(const Expr *E) {
46
0
    if (auto *BO = dyn_cast<BinaryOperator>(E)) {
47
0
      Op = BinaryOperator::getOverloadedOperator(BO->getOpcode());
48
0
      LHS = BO->getLHS();
49
0
      RHS = BO->getRHS();
50
0
      Loc = BO->getExprLoc();
51
0
    } else if (auto *OO = dyn_cast<CXXOperatorCallExpr>(E)) {
52
      // If OO is not || or && it might not have exactly 2 arguments.
53
0
      if (OO->getNumArgs() == 2) {
54
0
        Op = OO->getOperator();
55
0
        LHS = OO->getArg(0);
56
0
        RHS = OO->getArg(1);
57
0
        Loc = OO->getOperatorLoc();
58
0
      }
59
0
    }
60
0
  }
61
62
0
  bool isAnd() const { return Op == OO_AmpAmp; }
63
0
  bool isOr() const { return Op == OO_PipePipe; }
64
0
  explicit operator bool() const { return isAnd() || isOr(); }
65
66
0
  const Expr *getLHS() const { return LHS; }
67
0
  const Expr *getRHS() const { return RHS; }
68
69
0
  ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS) const {
70
0
    return recreateBinOp(SemaRef, LHS, const_cast<Expr *>(getRHS()));
71
0
  }
72
73
  ExprResult recreateBinOp(Sema &SemaRef, ExprResult LHS,
74
0
                           ExprResult RHS) const {
75
0
    assert((isAnd() || isOr()) && "Not the right kind of op?");
76
0
    assert((!LHS.isInvalid() && !RHS.isInvalid()) && "not good expressions?");
77
78
0
    if (!LHS.isUsable() || !RHS.isUsable())
79
0
      return ExprEmpty();
80
81
    // We should just be able to 'normalize' these to the builtin Binary
82
    // Operator, since that is how they are evaluated in constriant checks.
83
0
    return BinaryOperator::Create(SemaRef.Context, LHS.get(), RHS.get(),
84
0
                                  BinaryOperator::getOverloadedOpcode(Op),
85
0
                                  SemaRef.Context.BoolTy, VK_PRValue,
86
0
                                  OK_Ordinary, Loc, FPOptionsOverride{});
87
0
  }
88
};
89
}
90
91
bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
92
                                     Token NextToken, bool *PossibleNonPrimary,
93
0
                                     bool IsTrailingRequiresClause) {
94
  // C++2a [temp.constr.atomic]p1
95
  // ..E shall be a constant expression of type bool.
96
97
0
  ConstraintExpression = ConstraintExpression->IgnoreParenImpCasts();
98
99
0
  if (LogicalBinOp BO = ConstraintExpression) {
100
0
    return CheckConstraintExpression(BO.getLHS(), NextToken,
101
0
                                     PossibleNonPrimary) &&
102
0
           CheckConstraintExpression(BO.getRHS(), NextToken,
103
0
                                     PossibleNonPrimary);
104
0
  } else if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpression))
105
0
    return CheckConstraintExpression(C->getSubExpr(), NextToken,
106
0
                                     PossibleNonPrimary);
107
108
0
  QualType Type = ConstraintExpression->getType();
109
110
0
  auto CheckForNonPrimary = [&] {
111
0
    if (!PossibleNonPrimary)
112
0
      return;
113
114
0
    *PossibleNonPrimary =
115
        // We have the following case:
116
        // template<typename> requires func(0) struct S { };
117
        // The user probably isn't aware of the parentheses required around
118
        // the function call, and we're only going to parse 'func' as the
119
        // primary-expression, and complain that it is of non-bool type.
120
        //
121
        // However, if we're in a lambda, this might also be:
122
        // []<typename> requires var () {};
123
        // Which also looks like a function call due to the lambda parentheses,
124
        // but unlike the first case, isn't an error, so this check is skipped.
125
0
        (NextToken.is(tok::l_paren) &&
126
0
         (IsTrailingRequiresClause ||
127
0
          (Type->isDependentType() &&
128
0
           isa<UnresolvedLookupExpr>(ConstraintExpression) &&
129
0
           !dyn_cast_if_present<LambdaScopeInfo>(getCurFunction())) ||
130
0
          Type->isFunctionType() ||
131
0
          Type->isSpecificBuiltinType(BuiltinType::Overload))) ||
132
        // We have the following case:
133
        // template<typename T> requires size_<T> == 0 struct S { };
134
        // The user probably isn't aware of the parentheses required around
135
        // the binary operator, and we're only going to parse 'func' as the
136
        // first operand, and complain that it is of non-bool type.
137
0
        getBinOpPrecedence(NextToken.getKind(),
138
0
                           /*GreaterThanIsOperator=*/true,
139
0
                           getLangOpts().CPlusPlus11) > prec::LogicalAnd;
140
0
  };
141
142
  // An atomic constraint!
143
0
  if (ConstraintExpression->isTypeDependent()) {
144
0
    CheckForNonPrimary();
145
0
    return true;
146
0
  }
147
148
0
  if (!Context.hasSameUnqualifiedType(Type, Context.BoolTy)) {
149
0
    Diag(ConstraintExpression->getExprLoc(),
150
0
         diag::err_non_bool_atomic_constraint) << Type
151
0
        << ConstraintExpression->getSourceRange();
152
0
    CheckForNonPrimary();
153
0
    return false;
154
0
  }
155
156
0
  if (PossibleNonPrimary)
157
0
      *PossibleNonPrimary = false;
158
0
  return true;
159
0
}
160
161
namespace {
162
struct SatisfactionStackRAII {
163
  Sema &SemaRef;
164
  bool Inserted = false;
165
  SatisfactionStackRAII(Sema &SemaRef, const NamedDecl *ND,
166
                        const llvm::FoldingSetNodeID &FSNID)
167
0
      : SemaRef(SemaRef) {
168
0
      if (ND) {
169
0
      SemaRef.PushSatisfactionStackEntry(ND, FSNID);
170
0
      Inserted = true;
171
0
      }
172
0
  }
173
0
  ~SatisfactionStackRAII() {
174
0
        if (Inserted)
175
0
          SemaRef.PopSatisfactionStackEntry();
176
0
  }
177
};
178
} // namespace
179
180
template <typename AtomicEvaluator>
181
static ExprResult
182
calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
183
                                ConstraintSatisfaction &Satisfaction,
184
0
                                AtomicEvaluator &&Evaluator) {
185
0
  ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts();
186
187
0
  if (LogicalBinOp BO = ConstraintExpr) {
188
0
    size_t EffectiveDetailEndIndex = Satisfaction.Details.size();
189
0
    ExprResult LHSRes = calculateConstraintSatisfaction(
190
0
        S, BO.getLHS(), Satisfaction, Evaluator);
191
192
0
    if (LHSRes.isInvalid())
193
0
      return ExprError();
194
195
0
    bool IsLHSSatisfied = Satisfaction.IsSatisfied;
196
197
0
    if (BO.isOr() && IsLHSSatisfied)
198
      // [temp.constr.op] p3
199
      //    A disjunction is a constraint taking two operands. To determine if
200
      //    a disjunction is satisfied, the satisfaction of the first operand
201
      //    is checked. If that is satisfied, the disjunction is satisfied.
202
      //    Otherwise, the disjunction is satisfied if and only if the second
203
      //    operand is satisfied.
204
      // LHS is instantiated while RHS is not. Skip creating invalid BinaryOp.
205
0
      return LHSRes;
206
207
0
    if (BO.isAnd() && !IsLHSSatisfied)
208
      // [temp.constr.op] p2
209
      //    A conjunction is a constraint taking two operands. To determine if
210
      //    a conjunction is satisfied, the satisfaction of the first operand
211
      //    is checked. If that is not satisfied, the conjunction is not
212
      //    satisfied. Otherwise, the conjunction is satisfied if and only if
213
      //    the second operand is satisfied.
214
      // LHS is instantiated while RHS is not. Skip creating invalid BinaryOp.
215
0
      return LHSRes;
216
217
0
    ExprResult RHSRes = calculateConstraintSatisfaction(
218
0
        S, BO.getRHS(), Satisfaction, std::forward<AtomicEvaluator>(Evaluator));
219
0
    if (RHSRes.isInvalid())
220
0
      return ExprError();
221
222
0
    bool IsRHSSatisfied = Satisfaction.IsSatisfied;
223
    // Current implementation adds diagnostic information about the falsity
224
    // of each false atomic constraint expression when it evaluates them.
225
    // When the evaluation results to `false || true`, the information
226
    // generated during the evaluation of left-hand side is meaningless
227
    // because the whole expression evaluates to true.
228
    // The following code removes the irrelevant diagnostic information.
229
    // FIXME: We should probably delay the addition of diagnostic information
230
    // until we know the entire expression is false.
231
0
    if (BO.isOr() && IsRHSSatisfied) {
232
0
      auto EffectiveDetailEnd = Satisfaction.Details.begin();
233
0
      std::advance(EffectiveDetailEnd, EffectiveDetailEndIndex);
234
0
      Satisfaction.Details.erase(EffectiveDetailEnd,
235
0
                                 Satisfaction.Details.end());
236
0
    }
237
238
0
    return BO.recreateBinOp(S, LHSRes, RHSRes);
239
0
  }
240
241
0
  if (auto *C = dyn_cast<ExprWithCleanups>(ConstraintExpr)) {
242
    // These aren't evaluated, so we don't care about cleanups, so we can just
243
    // evaluate these as if the cleanups didn't exist.
244
0
    return calculateConstraintSatisfaction(
245
0
        S, C->getSubExpr(), Satisfaction,
246
0
        std::forward<AtomicEvaluator>(Evaluator));
247
0
  }
248
249
  // An atomic constraint expression
250
0
  ExprResult SubstitutedAtomicExpr = Evaluator(ConstraintExpr);
251
252
0
  if (SubstitutedAtomicExpr.isInvalid())
253
0
    return ExprError();
254
255
0
  if (!SubstitutedAtomicExpr.isUsable())
256
    // Evaluator has decided satisfaction without yielding an expression.
257
0
    return ExprEmpty();
258
259
  // We don't have the ability to evaluate this, since it contains a
260
  // RecoveryExpr, so we want to fail overload resolution.  Otherwise,
261
  // we'd potentially pick up a different overload, and cause confusing
262
  // diagnostics. SO, add a failure detail that will cause us to make this
263
  // overload set not viable.
264
0
  if (SubstitutedAtomicExpr.get()->containsErrors()) {
265
0
    Satisfaction.IsSatisfied = false;
266
0
    Satisfaction.ContainsErrors = true;
267
268
0
    PartialDiagnostic Msg = S.PDiag(diag::note_constraint_references_error);
269
0
    SmallString<128> DiagString;
270
0
    DiagString = ": ";
271
0
    Msg.EmitToString(S.getDiagnostics(), DiagString);
272
0
    unsigned MessageSize = DiagString.size();
273
0
    char *Mem = new (S.Context) char[MessageSize];
274
0
    memcpy(Mem, DiagString.c_str(), MessageSize);
275
0
    Satisfaction.Details.emplace_back(
276
0
        ConstraintExpr,
277
0
        new (S.Context) ConstraintSatisfaction::SubstitutionDiagnostic{
278
0
            SubstitutedAtomicExpr.get()->getBeginLoc(),
279
0
            StringRef(Mem, MessageSize)});
280
0
    return SubstitutedAtomicExpr;
281
0
  }
282
283
0
  EnterExpressionEvaluationContext ConstantEvaluated(
284
0
      S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
285
0
  SmallVector<PartialDiagnosticAt, 2> EvaluationDiags;
286
0
  Expr::EvalResult EvalResult;
287
0
  EvalResult.Diag = &EvaluationDiags;
288
0
  if (!SubstitutedAtomicExpr.get()->EvaluateAsConstantExpr(EvalResult,
289
0
                                                           S.Context) ||
290
0
      !EvaluationDiags.empty()) {
291
    // C++2a [temp.constr.atomic]p1
292
    //   ...E shall be a constant expression of type bool.
293
0
    S.Diag(SubstitutedAtomicExpr.get()->getBeginLoc(),
294
0
           diag::err_non_constant_constraint_expression)
295
0
        << SubstitutedAtomicExpr.get()->getSourceRange();
296
0
    for (const PartialDiagnosticAt &PDiag : EvaluationDiags)
297
0
      S.Diag(PDiag.first, PDiag.second);
298
0
    return ExprError();
299
0
  }
300
301
0
  assert(EvalResult.Val.isInt() &&
302
0
         "evaluating bool expression didn't produce int");
303
0
  Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue();
304
0
  if (!Satisfaction.IsSatisfied)
305
0
    Satisfaction.Details.emplace_back(ConstraintExpr,
306
0
                                      SubstitutedAtomicExpr.get());
307
308
0
  return SubstitutedAtomicExpr;
309
0
}
Unexecuted instantiation: SemaConcept.cpp:clang::ActionResult<clang::Expr*, true> calculateConstraintSatisfaction<calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, clang::SourceLocation, clang::MultiLevelTemplateArgumentList const&, clang::Expr const*, clang::ConstraintSatisfaction&)::$_7>(clang::Sema&, clang::Expr const*, clang::ConstraintSatisfaction&, calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, clang::SourceLocation, clang::MultiLevelTemplateArgumentList const&, clang::Expr const*, clang::ConstraintSatisfaction&)::$_7&&)
Unexecuted instantiation: SemaConcept.cpp:clang::ActionResult<clang::Expr*, true> calculateConstraintSatisfaction<calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, clang::SourceLocation, clang::MultiLevelTemplateArgumentList const&, clang::Expr const*, clang::ConstraintSatisfaction&)::$_7&>(clang::Sema&, clang::Expr const*, clang::ConstraintSatisfaction&, calculateConstraintSatisfaction(clang::Sema&, clang::NamedDecl const*, clang::SourceLocation, clang::MultiLevelTemplateArgumentList const&, clang::Expr const*, clang::ConstraintSatisfaction&)::$_7&)
Unexecuted instantiation: SemaConcept.cpp:clang::ActionResult<clang::Expr*, true> calculateConstraintSatisfaction<clang::Sema::CheckConstraintSatisfaction(clang::Expr const*, clang::ConstraintSatisfaction&)::$_1>(clang::Sema&, clang::Expr const*, clang::ConstraintSatisfaction&, clang::Sema::CheckConstraintSatisfaction(clang::Expr const*, clang::ConstraintSatisfaction&)::$_1&&)
Unexecuted instantiation: SemaConcept.cpp:clang::ActionResult<clang::Expr*, true> calculateConstraintSatisfaction<clang::Sema::CheckConstraintSatisfaction(clang::Expr const*, clang::ConstraintSatisfaction&)::$_1&>(clang::Sema&, clang::Expr const*, clang::ConstraintSatisfaction&, clang::Sema::CheckConstraintSatisfaction(clang::Expr const*, clang::ConstraintSatisfaction&)::$_1&)
310
311
static bool
312
DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID,
313
                            const NamedDecl *Templ, const Expr *E,
314
0
                            const MultiLevelTemplateArgumentList &MLTAL) {
315
0
  E->Profile(ID, S.Context, /*Canonical=*/true);
316
0
  for (const auto &List : MLTAL)
317
0
    for (const auto &TemplateArg : List.Args)
318
0
      TemplateArg.Profile(ID, S.Context);
319
320
  // Note that we have to do this with our own collection, because there are
321
  // times where a constraint-expression check can cause us to need to evaluate
322
  // other constriants that are unrelated, such as when evaluating a recovery
323
  // expression, or when trying to determine the constexpr-ness of special
324
  // members. Otherwise we could just use the
325
  // Sema::InstantiatingTemplate::isAlreadyBeingInstantiated function.
326
0
  if (S.SatisfactionStackContains(Templ, ID)) {
327
0
    S.Diag(E->getExprLoc(), diag::err_constraint_depends_on_self)
328
0
        << const_cast<Expr *>(E) << E->getSourceRange();
329
0
    return true;
330
0
  }
331
332
0
  return false;
333
0
}
334
335
static ExprResult calculateConstraintSatisfaction(
336
    Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc,
337
    const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr,
338
0
    ConstraintSatisfaction &Satisfaction) {
339
0
  return calculateConstraintSatisfaction(
340
0
      S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) {
341
0
        EnterExpressionEvaluationContext ConstantEvaluated(
342
0
            S, Sema::ExpressionEvaluationContext::ConstantEvaluated,
343
0
            Sema::ReuseLambdaContextDecl);
344
345
        // Atomic constraint - substitute arguments and check satisfaction.
346
0
        ExprResult SubstitutedExpression;
347
0
        {
348
0
          TemplateDeductionInfo Info(TemplateNameLoc);
349
0
          Sema::InstantiatingTemplate Inst(S, AtomicExpr->getBeginLoc(),
350
0
              Sema::InstantiatingTemplate::ConstraintSubstitution{},
351
0
              const_cast<NamedDecl *>(Template), Info,
352
0
              AtomicExpr->getSourceRange());
353
0
          if (Inst.isInvalid())
354
0
            return ExprError();
355
356
0
          llvm::FoldingSetNodeID ID;
357
0
          if (Template &&
358
0
              DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, MLTAL)) {
359
0
            Satisfaction.IsSatisfied = false;
360
0
            Satisfaction.ContainsErrors = true;
361
0
            return ExprEmpty();
362
0
          }
363
364
0
          SatisfactionStackRAII StackRAII(S, Template, ID);
365
366
          // We do not want error diagnostics escaping here.
367
0
          Sema::SFINAETrap Trap(S);
368
0
          SubstitutedExpression =
369
0
              S.SubstConstraintExpr(const_cast<Expr *>(AtomicExpr), MLTAL);
370
371
0
          if (SubstitutedExpression.isInvalid() || Trap.hasErrorOccurred()) {
372
            // C++2a [temp.constr.atomic]p1
373
            //   ...If substitution results in an invalid type or expression, the
374
            //   constraint is not satisfied.
375
0
            if (!Trap.hasErrorOccurred())
376
              // A non-SFINAE error has occurred as a result of this
377
              // substitution.
378
0
              return ExprError();
379
380
0
            PartialDiagnosticAt SubstDiag{SourceLocation(),
381
0
                                          PartialDiagnostic::NullDiagnostic()};
382
0
            Info.takeSFINAEDiagnostic(SubstDiag);
383
            // FIXME: Concepts: This is an unfortunate consequence of there
384
            //  being no serialization code for PartialDiagnostics and the fact
385
            //  that serializing them would likely take a lot more storage than
386
            //  just storing them as strings. We would still like, in the
387
            //  future, to serialize the proper PartialDiagnostic as serializing
388
            //  it as a string defeats the purpose of the diagnostic mechanism.
389
0
            SmallString<128> DiagString;
390
0
            DiagString = ": ";
391
0
            SubstDiag.second.EmitToString(S.getDiagnostics(), DiagString);
392
0
            unsigned MessageSize = DiagString.size();
393
0
            char *Mem = new (S.Context) char[MessageSize];
394
0
            memcpy(Mem, DiagString.c_str(), MessageSize);
395
0
            Satisfaction.Details.emplace_back(
396
0
                AtomicExpr,
397
0
                new (S.Context) ConstraintSatisfaction::SubstitutionDiagnostic{
398
0
                        SubstDiag.first, StringRef(Mem, MessageSize)});
399
0
            Satisfaction.IsSatisfied = false;
400
0
            return ExprEmpty();
401
0
          }
402
0
        }
403
404
0
        if (!S.CheckConstraintExpression(SubstitutedExpression.get()))
405
0
          return ExprError();
406
407
        // [temp.constr.atomic]p3: To determine if an atomic constraint is
408
        // satisfied, the parameter mapping and template arguments are first
409
        // substituted into its expression.  If substitution results in an
410
        // invalid type or expression, the constraint is not satisfied.
411
        // Otherwise, the lvalue-to-rvalue conversion is performed if necessary,
412
        // and E shall be a constant expression of type bool.
413
        //
414
        // Perform the L to R Value conversion if necessary. We do so for all
415
        // non-PRValue categories, else we fail to extend the lifetime of
416
        // temporaries, and that fails the constant expression check.
417
0
        if (!SubstitutedExpression.get()->isPRValue())
418
0
          SubstitutedExpression = ImplicitCastExpr::Create(
419
0
              S.Context, SubstitutedExpression.get()->getType(),
420
0
              CK_LValueToRValue, SubstitutedExpression.get(),
421
0
              /*BasePath=*/nullptr, VK_PRValue, FPOptionsOverride());
422
423
0
        return SubstitutedExpression;
424
0
      });
425
0
}
426
427
static bool CheckConstraintSatisfaction(
428
    Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
429
    llvm::SmallVectorImpl<Expr *> &Converted,
430
    const MultiLevelTemplateArgumentList &TemplateArgsLists,
431
0
    SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
432
0
  if (ConstraintExprs.empty()) {
433
0
    Satisfaction.IsSatisfied = true;
434
0
    return false;
435
0
  }
436
437
0
  if (TemplateArgsLists.isAnyArgInstantiationDependent()) {
438
    // No need to check satisfaction for dependent constraint expressions.
439
0
    Satisfaction.IsSatisfied = true;
440
0
    return false;
441
0
  }
442
443
0
  ArrayRef<TemplateArgument> TemplateArgs =
444
0
      TemplateArgsLists.getNumSubstitutedLevels() > 0
445
0
          ? TemplateArgsLists.getOutermost()
446
0
          : ArrayRef<TemplateArgument> {};
447
0
  Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
448
0
      Sema::InstantiatingTemplate::ConstraintsCheck{},
449
0
      const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
450
0
  if (Inst.isInvalid())
451
0
    return true;
452
453
0
  for (const Expr *ConstraintExpr : ConstraintExprs) {
454
0
    ExprResult Res = calculateConstraintSatisfaction(
455
0
        S, Template, TemplateIDRange.getBegin(), TemplateArgsLists,
456
0
        ConstraintExpr, Satisfaction);
457
0
    if (Res.isInvalid())
458
0
      return true;
459
460
0
    Converted.push_back(Res.get());
461
0
    if (!Satisfaction.IsSatisfied) {
462
      // Backfill the 'converted' list with nulls so we can keep the Converted
463
      // and unconverted lists in sync.
464
0
      Converted.append(ConstraintExprs.size() - Converted.size(), nullptr);
465
      // [temp.constr.op] p2
466
      // [...] To determine if a conjunction is satisfied, the satisfaction
467
      // of the first operand is checked. If that is not satisfied, the
468
      // conjunction is not satisfied. [...]
469
0
      return false;
470
0
    }
471
0
  }
472
0
  return false;
473
0
}
474
475
bool Sema::CheckConstraintSatisfaction(
476
    const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
477
    llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
478
    const MultiLevelTemplateArgumentList &TemplateArgsLists,
479
0
    SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) {
480
0
  if (ConstraintExprs.empty()) {
481
0
    OutSatisfaction.IsSatisfied = true;
482
0
    return false;
483
0
  }
484
0
  if (!Template) {
485
0
    return ::CheckConstraintSatisfaction(
486
0
        *this, nullptr, ConstraintExprs, ConvertedConstraints,
487
0
        TemplateArgsLists, TemplateIDRange, OutSatisfaction);
488
0
  }
489
490
  // A list of the template argument list flattened in a predictible manner for
491
  // the purposes of caching. The ConstraintSatisfaction type is in AST so it
492
  // has no access to the MultiLevelTemplateArgumentList, so this has to happen
493
  // here.
494
0
  llvm::SmallVector<TemplateArgument, 4> FlattenedArgs;
495
0
  for (auto List : TemplateArgsLists)
496
0
    FlattenedArgs.insert(FlattenedArgs.end(), List.Args.begin(),
497
0
                         List.Args.end());
498
499
0
  llvm::FoldingSetNodeID ID;
500
0
  ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs);
501
0
  void *InsertPos;
502
0
  if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
503
0
    OutSatisfaction = *Cached;
504
0
    return false;
505
0
  }
506
507
0
  auto Satisfaction =
508
0
      std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs);
509
0
  if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
510
0
                                    ConvertedConstraints, TemplateArgsLists,
511
0
                                    TemplateIDRange, *Satisfaction)) {
512
0
    OutSatisfaction = *Satisfaction;
513
0
    return true;
514
0
  }
515
516
0
  if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) {
517
    // The evaluation of this constraint resulted in us trying to re-evaluate it
518
    // recursively. This isn't really possible, except we try to form a
519
    // RecoveryExpr as a part of the evaluation.  If this is the case, just
520
    // return the 'cached' version (which will have the same result), and save
521
    // ourselves the extra-insert. If it ever becomes possible to legitimately
522
    // recursively check a constraint, we should skip checking the 'inner' one
523
    // above, and replace the cached version with this one, as it would be more
524
    // specific.
525
0
    OutSatisfaction = *Cached;
526
0
    return false;
527
0
  }
528
529
  // Else we can simply add this satisfaction to the list.
530
0
  OutSatisfaction = *Satisfaction;
531
  // We cannot use InsertPos here because CheckConstraintSatisfaction might have
532
  // invalidated it.
533
  // Note that entries of SatisfactionCache are deleted in Sema's destructor.
534
0
  SatisfactionCache.InsertNode(Satisfaction.release());
535
0
  return false;
536
0
}
537
538
bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
539
0
                                       ConstraintSatisfaction &Satisfaction) {
540
0
  return calculateConstraintSatisfaction(
541
0
             *this, ConstraintExpr, Satisfaction,
542
0
             [this](const Expr *AtomicExpr) -> ExprResult {
543
               // We only do this to immitate lvalue-to-rvalue conversion.
544
0
               return PerformContextuallyConvertToBool(
545
0
                   const_cast<Expr *>(AtomicExpr));
546
0
             })
547
0
      .isInvalid();
548
0
}
549
550
bool Sema::addInstantiatedCapturesToScope(
551
    FunctionDecl *Function, const FunctionDecl *PatternDecl,
552
    LocalInstantiationScope &Scope,
553
0
    const MultiLevelTemplateArgumentList &TemplateArgs) {
554
0
  const auto *LambdaClass = cast<CXXMethodDecl>(Function)->getParent();
555
0
  const auto *LambdaPattern = cast<CXXMethodDecl>(PatternDecl)->getParent();
556
557
0
  unsigned Instantiated = 0;
558
559
0
  auto AddSingleCapture = [&](const ValueDecl *CapturedPattern,
560
0
                              unsigned Index) {
561
0
    ValueDecl *CapturedVar = LambdaClass->getCapture(Index)->getCapturedVar();
562
0
    if (CapturedVar->isInitCapture())
563
0
      Scope.InstantiatedLocal(CapturedPattern, CapturedVar);
564
0
  };
565
566
0
  for (const LambdaCapture &CapturePattern : LambdaPattern->captures()) {
567
0
    if (!CapturePattern.capturesVariable()) {
568
0
      Instantiated++;
569
0
      continue;
570
0
    }
571
0
    const ValueDecl *CapturedPattern = CapturePattern.getCapturedVar();
572
0
    if (!CapturedPattern->isParameterPack()) {
573
0
      AddSingleCapture(CapturedPattern, Instantiated++);
574
0
    } else {
575
0
      Scope.MakeInstantiatedLocalArgPack(CapturedPattern);
576
0
      std::optional<unsigned> NumArgumentsInExpansion =
577
0
          getNumArgumentsInExpansion(CapturedPattern->getType(), TemplateArgs);
578
0
      if (!NumArgumentsInExpansion)
579
0
        continue;
580
0
      for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg)
581
0
        AddSingleCapture(CapturedPattern, Instantiated++);
582
0
    }
583
0
  }
584
0
  return false;
585
0
}
586
587
bool Sema::SetupConstraintScope(
588
    FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
589
0
    MultiLevelTemplateArgumentList MLTAL, LocalInstantiationScope &Scope) {
590
0
  if (FD->isTemplateInstantiation() && FD->getPrimaryTemplate()) {
591
0
    FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
592
0
    InstantiatingTemplate Inst(
593
0
        *this, FD->getPointOfInstantiation(),
594
0
        Sema::InstantiatingTemplate::ConstraintsCheck{}, PrimaryTemplate,
595
0
        TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
596
0
        SourceRange());
597
0
    if (Inst.isInvalid())
598
0
      return true;
599
600
    // addInstantiatedParametersToScope creates a map of 'uninstantiated' to
601
    // 'instantiated' parameters and adds it to the context. For the case where
602
    // this function is a template being instantiated NOW, we also need to add
603
    // the list of current template arguments to the list so that they also can
604
    // be picked out of the map.
605
0
    if (auto *SpecArgs = FD->getTemplateSpecializationArgs()) {
606
0
      MultiLevelTemplateArgumentList JustTemplArgs(FD, SpecArgs->asArray(),
607
0
                                                   /*Final=*/false);
608
0
      if (addInstantiatedParametersToScope(
609
0
              FD, PrimaryTemplate->getTemplatedDecl(), Scope, JustTemplArgs))
610
0
        return true;
611
0
    }
612
613
    // If this is a member function, make sure we get the parameters that
614
    // reference the original primary template.
615
0
    if (const auto *FromMemTempl =
616
0
            PrimaryTemplate->getInstantiatedFromMemberTemplate()) {
617
0
      if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
618
0
                                           Scope, MLTAL))
619
0
        return true;
620
0
    }
621
622
0
    return false;
623
0
  }
624
625
0
  if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||
626
0
      FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) {
627
0
    FunctionDecl *InstantiatedFrom =
628
0
        FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization
629
0
            ? FD->getInstantiatedFromMemberFunction()
630
0
            : FD->getInstantiatedFromDecl();
631
632
0
    InstantiatingTemplate Inst(
633
0
        *this, FD->getPointOfInstantiation(),
634
0
        Sema::InstantiatingTemplate::ConstraintsCheck{}, InstantiatedFrom,
635
0
        TemplateArgs ? *TemplateArgs : ArrayRef<TemplateArgument>{},
636
0
        SourceRange());
637
0
    if (Inst.isInvalid())
638
0
      return true;
639
640
    // Case where this was not a template, but instantiated as a
641
    // child-function.
642
0
    if (addInstantiatedParametersToScope(FD, InstantiatedFrom, Scope, MLTAL))
643
0
      return true;
644
0
  }
645
646
0
  return false;
647
0
}
648
649
// This function collects all of the template arguments for the purposes of
650
// constraint-instantiation and checking.
651
std::optional<MultiLevelTemplateArgumentList>
652
Sema::SetupConstraintCheckingTemplateArgumentsAndScope(
653
    FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
654
0
    LocalInstantiationScope &Scope) {
655
0
  MultiLevelTemplateArgumentList MLTAL;
656
657
  // Collect the list of template arguments relative to the 'primary' template.
658
  // We need the entire list, since the constraint is completely uninstantiated
659
  // at this point.
660
0
  MLTAL = getTemplateInstantiationArgs(FD, FD->getLexicalDeclContext(),
661
0
                                       /*Final=*/false, /*Innermost=*/nullptr,
662
0
                                       /*RelativeToPrimary=*/true,
663
0
                                       /*Pattern=*/nullptr,
664
0
                                       /*ForConstraintInstantiation=*/true);
665
0
  if (SetupConstraintScope(FD, TemplateArgs, MLTAL, Scope))
666
0
    return std::nullopt;
667
668
0
  return MLTAL;
669
0
}
670
671
bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
672
                                    ConstraintSatisfaction &Satisfaction,
673
                                    SourceLocation UsageLoc,
674
0
                                    bool ForOverloadResolution) {
675
  // Don't check constraints if the function is dependent. Also don't check if
676
  // this is a function template specialization, as the call to
677
  // CheckinstantiatedFunctionTemplateConstraints after this will check it
678
  // better.
679
0
  if (FD->isDependentContext() ||
680
0
      FD->getTemplatedKind() ==
681
0
          FunctionDecl::TK_FunctionTemplateSpecialization) {
682
0
    Satisfaction.IsSatisfied = true;
683
0
    return false;
684
0
  }
685
686
  // A lambda conversion operator has the same constraints as the call operator
687
  // and constraints checking relies on whether we are in a lambda call operator
688
  // (and may refer to its parameters), so check the call operator instead.
689
0
  if (const auto *MD = dyn_cast<CXXConversionDecl>(FD);
690
0
      MD && isLambdaConversionOperator(const_cast<CXXConversionDecl *>(MD)))
691
0
    return CheckFunctionConstraints(MD->getParent()->getLambdaCallOperator(),
692
0
                                    Satisfaction, UsageLoc,
693
0
                                    ForOverloadResolution);
694
695
0
  DeclContext *CtxToSave = const_cast<FunctionDecl *>(FD);
696
697
0
  while (isLambdaCallOperator(CtxToSave) || FD->isTransparentContext()) {
698
0
    if (isLambdaCallOperator(CtxToSave))
699
0
      CtxToSave = CtxToSave->getParent()->getParent();
700
0
    else
701
0
      CtxToSave = CtxToSave->getNonTransparentContext();
702
0
  }
703
704
0
  ContextRAII SavedContext{*this, CtxToSave};
705
0
  LocalInstantiationScope Scope(*this, !ForOverloadResolution);
706
0
  std::optional<MultiLevelTemplateArgumentList> MLTAL =
707
0
      SetupConstraintCheckingTemplateArgumentsAndScope(
708
0
          const_cast<FunctionDecl *>(FD), {}, Scope);
709
710
0
  if (!MLTAL)
711
0
    return true;
712
713
0
  Qualifiers ThisQuals;
714
0
  CXXRecordDecl *Record = nullptr;
715
0
  if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
716
0
    ThisQuals = Method->getMethodQualifiers();
717
0
    Record = const_cast<CXXRecordDecl *>(Method->getParent());
718
0
  }
719
0
  CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
720
721
0
  LambdaScopeForCallOperatorInstantiationRAII LambdaScope(
722
0
      *this, const_cast<FunctionDecl *>(FD), *MLTAL, Scope,
723
0
      ForOverloadResolution);
724
725
0
  return CheckConstraintSatisfaction(
726
0
      FD, {FD->getTrailingRequiresClause()}, *MLTAL,
727
0
      SourceRange(UsageLoc.isValid() ? UsageLoc : FD->getLocation()),
728
0
      Satisfaction);
729
0
}
730
731
732
// Figure out the to-translation-unit depth for this function declaration for
733
// the purpose of seeing if they differ by constraints. This isn't the same as
734
// getTemplateDepth, because it includes already instantiated parents.
735
static unsigned
736
CalculateTemplateDepthForConstraints(Sema &S, const NamedDecl *ND,
737
0
                                     bool SkipForSpecialization = false) {
738
0
  MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
739
0
      ND, ND->getLexicalDeclContext(), /*Final=*/false, /*Innermost=*/nullptr,
740
0
      /*RelativeToPrimary=*/true,
741
0
      /*Pattern=*/nullptr,
742
0
      /*ForConstraintInstantiation=*/true, SkipForSpecialization);
743
0
  return MLTAL.getNumLevels();
744
0
}
745
746
namespace {
747
  class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> {
748
  unsigned TemplateDepth = 0;
749
  public:
750
  using inherited = TreeTransform<AdjustConstraintDepth>;
751
  AdjustConstraintDepth(Sema &SemaRef, unsigned TemplateDepth)
752
0
      : inherited(SemaRef), TemplateDepth(TemplateDepth) {}
753
754
  using inherited::TransformTemplateTypeParmType;
755
  QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
756
0
                                         TemplateTypeParmTypeLoc TL, bool) {
757
0
    const TemplateTypeParmType *T = TL.getTypePtr();
758
759
0
    TemplateTypeParmDecl *NewTTPDecl = nullptr;
760
0
    if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
761
0
      NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
762
0
          TransformDecl(TL.getNameLoc(), OldTTPDecl));
763
764
0
    QualType Result = getSema().Context.getTemplateTypeParmType(
765
0
        T->getDepth() + TemplateDepth, T->getIndex(), T->isParameterPack(),
766
0
        NewTTPDecl);
767
0
    TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
768
0
    NewTL.setNameLoc(TL.getNameLoc());
769
0
    return Result;
770
0
  }
771
  };
772
} // namespace
773
774
static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
775
    Sema &S, const Sema::TemplateCompareNewDeclInfo &DeclInfo,
776
0
    const Expr *ConstrExpr) {
777
0
  MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
778
0
      DeclInfo.getDecl(), DeclInfo.getLexicalDeclContext(), /*Final=*/false,
779
0
      /*Innermost=*/nullptr,
780
0
      /*RelativeToPrimary=*/true,
781
0
      /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/true,
782
0
      /*SkipForSpecialization*/ false);
783
784
0
  if (MLTAL.getNumSubstitutedLevels() == 0)
785
0
    return ConstrExpr;
786
787
0
  Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/false);
788
789
0
  Sema::InstantiatingTemplate Inst(
790
0
      S, DeclInfo.getLocation(),
791
0
      Sema::InstantiatingTemplate::ConstraintNormalization{},
792
0
      const_cast<NamedDecl *>(DeclInfo.getDecl()), SourceRange{});
793
0
  if (Inst.isInvalid())
794
0
    return nullptr;
795
796
0
  std::optional<Sema::CXXThisScopeRAII> ThisScope;
797
0
  if (auto *RD = dyn_cast<CXXRecordDecl>(DeclInfo.getDeclContext()))
798
0
    ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers());
799
0
  ExprResult SubstConstr = S.SubstConstraintExprWithoutSatisfaction(
800
0
      const_cast<clang::Expr *>(ConstrExpr), MLTAL);
801
0
  if (SFINAE.hasErrorOccurred() || !SubstConstr.isUsable())
802
0
    return nullptr;
803
0
  return SubstConstr.get();
804
0
}
805
806
bool Sema::AreConstraintExpressionsEqual(const NamedDecl *Old,
807
                                         const Expr *OldConstr,
808
                                         const TemplateCompareNewDeclInfo &New,
809
0
                                         const Expr *NewConstr) {
810
0
  if (OldConstr == NewConstr)
811
0
    return true;
812
  // C++ [temp.constr.decl]p4
813
0
  if (Old && !New.isInvalid() && !New.ContainsDecl(Old) &&
814
0
      Old->getLexicalDeclContext() != New.getLexicalDeclContext()) {
815
0
    if (const Expr *SubstConstr =
816
0
            SubstituteConstraintExpressionWithoutSatisfaction(*this, Old,
817
0
                                                              OldConstr))
818
0
      OldConstr = SubstConstr;
819
0
    else
820
0
      return false;
821
0
    if (const Expr *SubstConstr =
822
0
            SubstituteConstraintExpressionWithoutSatisfaction(*this, New,
823
0
                                                              NewConstr))
824
0
      NewConstr = SubstConstr;
825
0
    else
826
0
      return false;
827
0
  }
828
829
0
  llvm::FoldingSetNodeID ID1, ID2;
830
0
  OldConstr->Profile(ID1, Context, /*Canonical=*/true);
831
0
  NewConstr->Profile(ID2, Context, /*Canonical=*/true);
832
0
  return ID1 == ID2;
833
0
}
834
835
0
bool Sema::FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD) {
836
0
  assert(FD->getFriendObjectKind() && "Must be a friend!");
837
838
  // The logic for non-templates is handled in ASTContext::isSameEntity, so we
839
  // don't have to bother checking 'DependsOnEnclosingTemplate' for a
840
  // non-function-template.
841
0
  assert(FD->getDescribedFunctionTemplate() &&
842
0
         "Non-function templates don't need to be checked");
843
844
0
  SmallVector<const Expr *, 3> ACs;
845
0
  FD->getDescribedFunctionTemplate()->getAssociatedConstraints(ACs);
846
847
0
  unsigned OldTemplateDepth = CalculateTemplateDepthForConstraints(*this, FD);
848
0
  for (const Expr *Constraint : ACs)
849
0
    if (ConstraintExpressionDependsOnEnclosingTemplate(FD, OldTemplateDepth,
850
0
                                                       Constraint))
851
0
      return true;
852
853
0
  return false;
854
0
}
855
856
bool Sema::EnsureTemplateArgumentListConstraints(
857
    TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists,
858
0
    SourceRange TemplateIDRange) {
859
0
  ConstraintSatisfaction Satisfaction;
860
0
  llvm::SmallVector<const Expr *, 3> AssociatedConstraints;
861
0
  TD->getAssociatedConstraints(AssociatedConstraints);
862
0
  if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists,
863
0
                                  TemplateIDRange, Satisfaction))
864
0
    return true;
865
866
0
  if (!Satisfaction.IsSatisfied) {
867
0
    SmallString<128> TemplateArgString;
868
0
    TemplateArgString = " ";
869
0
    TemplateArgString += getTemplateArgumentBindingsText(
870
0
        TD->getTemplateParameters(), TemplateArgsLists.getInnermost().data(),
871
0
        TemplateArgsLists.getInnermost().size());
872
873
0
    Diag(TemplateIDRange.getBegin(),
874
0
         diag::err_template_arg_list_constraints_not_satisfied)
875
0
        << (int)getTemplateNameKindForDiagnostics(TemplateName(TD)) << TD
876
0
        << TemplateArgString << TemplateIDRange;
877
0
    DiagnoseUnsatisfiedConstraint(Satisfaction);
878
0
    return true;
879
0
  }
880
0
  return false;
881
0
}
882
883
bool Sema::CheckInstantiatedFunctionTemplateConstraints(
884
    SourceLocation PointOfInstantiation, FunctionDecl *Decl,
885
    ArrayRef<TemplateArgument> TemplateArgs,
886
0
    ConstraintSatisfaction &Satisfaction) {
887
  // In most cases we're not going to have constraints, so check for that first.
888
0
  FunctionTemplateDecl *Template = Decl->getPrimaryTemplate();
889
  // Note - code synthesis context for the constraints check is created
890
  // inside CheckConstraintsSatisfaction.
891
0
  SmallVector<const Expr *, 3> TemplateAC;
892
0
  Template->getAssociatedConstraints(TemplateAC);
893
0
  if (TemplateAC.empty()) {
894
0
    Satisfaction.IsSatisfied = true;
895
0
    return false;
896
0
  }
897
898
  // Enter the scope of this instantiation. We don't use
899
  // PushDeclContext because we don't have a scope.
900
0
  Sema::ContextRAII savedContext(*this, Decl);
901
0
  LocalInstantiationScope Scope(*this);
902
903
0
  std::optional<MultiLevelTemplateArgumentList> MLTAL =
904
0
      SetupConstraintCheckingTemplateArgumentsAndScope(Decl, TemplateArgs,
905
0
                                                       Scope);
906
907
0
  if (!MLTAL)
908
0
    return true;
909
910
0
  Qualifiers ThisQuals;
911
0
  CXXRecordDecl *Record = nullptr;
912
0
  if (auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
913
0
    ThisQuals = Method->getMethodQualifiers();
914
0
    Record = Method->getParent();
915
0
  }
916
917
0
  CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr);
918
0
  LambdaScopeForCallOperatorInstantiationRAII LambdaScope(
919
0
      *this, const_cast<FunctionDecl *>(Decl), *MLTAL, Scope);
920
921
0
  llvm::SmallVector<Expr *, 1> Converted;
922
0
  return CheckConstraintSatisfaction(Template, TemplateAC, Converted, *MLTAL,
923
0
                                     PointOfInstantiation, Satisfaction);
924
0
}
925
926
static void diagnoseUnsatisfiedRequirement(Sema &S,
927
                                           concepts::ExprRequirement *Req,
928
0
                                           bool First) {
929
0
  assert(!Req->isSatisfied()
930
0
         && "Diagnose() can only be used on an unsatisfied requirement");
931
0
  switch (Req->getSatisfactionStatus()) {
932
0
    case concepts::ExprRequirement::SS_Dependent:
933
0
      llvm_unreachable("Diagnosing a dependent requirement");
934
0
      break;
935
0
    case concepts::ExprRequirement::SS_ExprSubstitutionFailure: {
936
0
      auto *SubstDiag = Req->getExprSubstitutionDiagnostic();
937
0
      if (!SubstDiag->DiagMessage.empty())
938
0
        S.Diag(SubstDiag->DiagLoc,
939
0
               diag::note_expr_requirement_expr_substitution_error)
940
0
               << (int)First << SubstDiag->SubstitutedEntity
941
0
               << SubstDiag->DiagMessage;
942
0
      else
943
0
        S.Diag(SubstDiag->DiagLoc,
944
0
               diag::note_expr_requirement_expr_unknown_substitution_error)
945
0
            << (int)First << SubstDiag->SubstitutedEntity;
946
0
      break;
947
0
    }
948
0
    case concepts::ExprRequirement::SS_NoexceptNotMet:
949
0
      S.Diag(Req->getNoexceptLoc(),
950
0
             diag::note_expr_requirement_noexcept_not_met)
951
0
          << (int)First << Req->getExpr();
952
0
      break;
953
0
    case concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure: {
954
0
      auto *SubstDiag =
955
0
          Req->getReturnTypeRequirement().getSubstitutionDiagnostic();
956
0
      if (!SubstDiag->DiagMessage.empty())
957
0
        S.Diag(SubstDiag->DiagLoc,
958
0
               diag::note_expr_requirement_type_requirement_substitution_error)
959
0
            << (int)First << SubstDiag->SubstitutedEntity
960
0
            << SubstDiag->DiagMessage;
961
0
      else
962
0
        S.Diag(SubstDiag->DiagLoc,
963
0
               diag::note_expr_requirement_type_requirement_unknown_substitution_error)
964
0
            << (int)First << SubstDiag->SubstitutedEntity;
965
0
      break;
966
0
    }
967
0
    case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: {
968
0
      ConceptSpecializationExpr *ConstraintExpr =
969
0
          Req->getReturnTypeRequirementSubstitutedConstraintExpr();
970
0
      if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
971
        // A simple case - expr type is the type being constrained and the concept
972
        // was not provided arguments.
973
0
        Expr *e = Req->getExpr();
974
0
        S.Diag(e->getBeginLoc(),
975
0
               diag::note_expr_requirement_constraints_not_satisfied_simple)
976
0
            << (int)First << S.Context.getReferenceQualifiedType(e)
977
0
            << ConstraintExpr->getNamedConcept();
978
0
      } else {
979
0
        S.Diag(ConstraintExpr->getBeginLoc(),
980
0
               diag::note_expr_requirement_constraints_not_satisfied)
981
0
            << (int)First << ConstraintExpr;
982
0
      }
983
0
      S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction());
984
0
      break;
985
0
    }
986
0
    case concepts::ExprRequirement::SS_Satisfied:
987
0
      llvm_unreachable("We checked this above");
988
0
  }
989
0
}
990
991
static void diagnoseUnsatisfiedRequirement(Sema &S,
992
                                           concepts::TypeRequirement *Req,
993
0
                                           bool First) {
994
0
  assert(!Req->isSatisfied()
995
0
         && "Diagnose() can only be used on an unsatisfied requirement");
996
0
  switch (Req->getSatisfactionStatus()) {
997
0
  case concepts::TypeRequirement::SS_Dependent:
998
0
    llvm_unreachable("Diagnosing a dependent requirement");
999
0
    return;
1000
0
  case concepts::TypeRequirement::SS_SubstitutionFailure: {
1001
0
    auto *SubstDiag = Req->getSubstitutionDiagnostic();
1002
0
    if (!SubstDiag->DiagMessage.empty())
1003
0
      S.Diag(SubstDiag->DiagLoc,
1004
0
             diag::note_type_requirement_substitution_error) << (int)First
1005
0
          << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
1006
0
    else
1007
0
      S.Diag(SubstDiag->DiagLoc,
1008
0
             diag::note_type_requirement_unknown_substitution_error)
1009
0
          << (int)First << SubstDiag->SubstitutedEntity;
1010
0
    return;
1011
0
  }
1012
0
  default:
1013
0
    llvm_unreachable("Unknown satisfaction status");
1014
0
    return;
1015
0
  }
1016
0
}
1017
static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
1018
                                                        Expr *SubstExpr,
1019
                                                        bool First = true);
1020
1021
static void diagnoseUnsatisfiedRequirement(Sema &S,
1022
                                           concepts::NestedRequirement *Req,
1023
0
                                           bool First) {
1024
0
  using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
1025
0
  for (auto &Pair : Req->getConstraintSatisfaction()) {
1026
0
    if (auto *SubstDiag = Pair.second.dyn_cast<SubstitutionDiagnostic *>())
1027
0
      S.Diag(SubstDiag->first, diag::note_nested_requirement_substitution_error)
1028
0
          << (int)First << Req->getInvalidConstraintEntity() << SubstDiag->second;
1029
0
    else
1030
0
      diagnoseWellFormedUnsatisfiedConstraintExpr(
1031
0
          S, Pair.second.dyn_cast<Expr *>(), First);
1032
0
    First = false;
1033
0
  }
1034
0
}
1035
1036
static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
1037
                                                        Expr *SubstExpr,
1038
0
                                                        bool First) {
1039
0
  SubstExpr = SubstExpr->IgnoreParenImpCasts();
1040
0
  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(SubstExpr)) {
1041
0
    switch (BO->getOpcode()) {
1042
    // These two cases will in practice only be reached when using fold
1043
    // expressions with || and &&, since otherwise the || and && will have been
1044
    // broken down into atomic constraints during satisfaction checking.
1045
0
    case BO_LOr:
1046
      // Or evaluated to false - meaning both RHS and LHS evaluated to false.
1047
0
      diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First);
1048
0
      diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(),
1049
0
                                                  /*First=*/false);
1050
0
      return;
1051
0
    case BO_LAnd: {
1052
0
      bool LHSSatisfied =
1053
0
          BO->getLHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
1054
0
      if (LHSSatisfied) {
1055
        // LHS is true, so RHS must be false.
1056
0
        diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(), First);
1057
0
        return;
1058
0
      }
1059
      // LHS is false
1060
0
      diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getLHS(), First);
1061
1062
      // RHS might also be false
1063
0
      bool RHSSatisfied =
1064
0
          BO->getRHS()->EvaluateKnownConstInt(S.Context).getBoolValue();
1065
0
      if (!RHSSatisfied)
1066
0
        diagnoseWellFormedUnsatisfiedConstraintExpr(S, BO->getRHS(),
1067
0
                                                    /*First=*/false);
1068
0
      return;
1069
0
    }
1070
0
    case BO_GE:
1071
0
    case BO_LE:
1072
0
    case BO_GT:
1073
0
    case BO_LT:
1074
0
    case BO_EQ:
1075
0
    case BO_NE:
1076
0
      if (BO->getLHS()->getType()->isIntegerType() &&
1077
0
          BO->getRHS()->getType()->isIntegerType()) {
1078
0
        Expr::EvalResult SimplifiedLHS;
1079
0
        Expr::EvalResult SimplifiedRHS;
1080
0
        BO->getLHS()->EvaluateAsInt(SimplifiedLHS, S.Context,
1081
0
                                    Expr::SE_NoSideEffects,
1082
0
                                    /*InConstantContext=*/true);
1083
0
        BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context,
1084
0
                                    Expr::SE_NoSideEffects,
1085
0
                                    /*InConstantContext=*/true);
1086
0
        if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) {
1087
0
          S.Diag(SubstExpr->getBeginLoc(),
1088
0
                 diag::note_atomic_constraint_evaluated_to_false_elaborated)
1089
0
              << (int)First << SubstExpr
1090
0
              << toString(SimplifiedLHS.Val.getInt(), 10)
1091
0
              << BinaryOperator::getOpcodeStr(BO->getOpcode())
1092
0
              << toString(SimplifiedRHS.Val.getInt(), 10);
1093
0
          return;
1094
0
        }
1095
0
      }
1096
0
      break;
1097
1098
0
    default:
1099
0
      break;
1100
0
    }
1101
0
  } else if (auto *CSE = dyn_cast<ConceptSpecializationExpr>(SubstExpr)) {
1102
0
    if (CSE->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
1103
0
      S.Diag(
1104
0
          CSE->getSourceRange().getBegin(),
1105
0
          diag::
1106
0
          note_single_arg_concept_specialization_constraint_evaluated_to_false)
1107
0
          << (int)First
1108
0
          << CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
1109
0
          << CSE->getNamedConcept();
1110
0
    } else {
1111
0
      S.Diag(SubstExpr->getSourceRange().getBegin(),
1112
0
             diag::note_concept_specialization_constraint_evaluated_to_false)
1113
0
          << (int)First << CSE;
1114
0
    }
1115
0
    S.DiagnoseUnsatisfiedConstraint(CSE->getSatisfaction());
1116
0
    return;
1117
0
  } else if (auto *RE = dyn_cast<RequiresExpr>(SubstExpr)) {
1118
    // FIXME: RequiresExpr should store dependent diagnostics.
1119
0
    for (concepts::Requirement *Req : RE->getRequirements())
1120
0
      if (!Req->isDependent() && !Req->isSatisfied()) {
1121
0
        if (auto *E = dyn_cast<concepts::ExprRequirement>(Req))
1122
0
          diagnoseUnsatisfiedRequirement(S, E, First);
1123
0
        else if (auto *T = dyn_cast<concepts::TypeRequirement>(Req))
1124
0
          diagnoseUnsatisfiedRequirement(S, T, First);
1125
0
        else
1126
0
          diagnoseUnsatisfiedRequirement(
1127
0
              S, cast<concepts::NestedRequirement>(Req), First);
1128
0
        break;
1129
0
      }
1130
0
    return;
1131
0
  }
1132
1133
0
  S.Diag(SubstExpr->getSourceRange().getBegin(),
1134
0
         diag::note_atomic_constraint_evaluated_to_false)
1135
0
      << (int)First << SubstExpr;
1136
0
}
1137
1138
template<typename SubstitutionDiagnostic>
1139
static void diagnoseUnsatisfiedConstraintExpr(
1140
    Sema &S, const Expr *E,
1141
    const llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> &Record,
1142
0
    bool First = true) {
1143
0
  if (auto *Diag = Record.template dyn_cast<SubstitutionDiagnostic *>()){
1144
0
    S.Diag(Diag->first, diag::note_substituted_constraint_expr_is_ill_formed)
1145
0
        << Diag->second;
1146
0
    return;
1147
0
  }
1148
1149
0
  diagnoseWellFormedUnsatisfiedConstraintExpr(S,
1150
0
      Record.template get<Expr *>(), First);
1151
0
}
1152
1153
void
1154
Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction,
1155
0
                                    bool First) {
1156
0
  assert(!Satisfaction.IsSatisfied &&
1157
0
         "Attempted to diagnose a satisfied constraint");
1158
0
  for (auto &Pair : Satisfaction.Details) {
1159
0
    diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
1160
0
    First = false;
1161
0
  }
1162
0
}
1163
1164
void Sema::DiagnoseUnsatisfiedConstraint(
1165
    const ASTConstraintSatisfaction &Satisfaction,
1166
0
    bool First) {
1167
0
  assert(!Satisfaction.IsSatisfied &&
1168
0
         "Attempted to diagnose a satisfied constraint");
1169
0
  for (auto &Pair : Satisfaction) {
1170
0
    diagnoseUnsatisfiedConstraintExpr(*this, Pair.first, Pair.second, First);
1171
0
    First = false;
1172
0
  }
1173
0
}
1174
1175
const NormalizedConstraint *
1176
Sema::getNormalizedAssociatedConstraints(
1177
0
    NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints) {
1178
  // In case the ConstrainedDecl comes from modules, it is necessary to use
1179
  // the canonical decl to avoid different atomic constraints with the 'same'
1180
  // declarations.
1181
0
  ConstrainedDecl = cast<NamedDecl>(ConstrainedDecl->getCanonicalDecl());
1182
1183
0
  auto CacheEntry = NormalizationCache.find(ConstrainedDecl);
1184
0
  if (CacheEntry == NormalizationCache.end()) {
1185
0
    auto Normalized =
1186
0
        NormalizedConstraint::fromConstraintExprs(*this, ConstrainedDecl,
1187
0
                                                  AssociatedConstraints);
1188
0
    CacheEntry =
1189
0
        NormalizationCache
1190
0
            .try_emplace(ConstrainedDecl,
1191
0
                         Normalized
1192
0
                             ? new (Context) NormalizedConstraint(
1193
0
                                 std::move(*Normalized))
1194
0
                             : nullptr)
1195
0
            .first;
1196
0
  }
1197
0
  return CacheEntry->second;
1198
0
}
1199
1200
static bool
1201
substituteParameterMappings(Sema &S, NormalizedConstraint &N,
1202
                            ConceptDecl *Concept,
1203
                            const MultiLevelTemplateArgumentList &MLTAL,
1204
0
                            const ASTTemplateArgumentListInfo *ArgsAsWritten) {
1205
0
  if (!N.isAtomic()) {
1206
0
    if (substituteParameterMappings(S, N.getLHS(), Concept, MLTAL,
1207
0
                                    ArgsAsWritten))
1208
0
      return true;
1209
0
    return substituteParameterMappings(S, N.getRHS(), Concept, MLTAL,
1210
0
                                       ArgsAsWritten);
1211
0
  }
1212
0
  TemplateParameterList *TemplateParams = Concept->getTemplateParameters();
1213
1214
0
  AtomicConstraint &Atomic = *N.getAtomicConstraint();
1215
0
  TemplateArgumentListInfo SubstArgs;
1216
0
  if (!Atomic.ParameterMapping) {
1217
0
    llvm::SmallBitVector OccurringIndices(TemplateParams->size());
1218
0
    S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false,
1219
0
                                 /*Depth=*/0, OccurringIndices);
1220
0
    TemplateArgumentLoc *TempArgs =
1221
0
        new (S.Context) TemplateArgumentLoc[OccurringIndices.count()];
1222
0
    for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I)
1223
0
      if (OccurringIndices[I])
1224
0
        new (&(TempArgs)[J++])
1225
0
            TemplateArgumentLoc(S.getIdentityTemplateArgumentLoc(
1226
0
                TemplateParams->begin()[I],
1227
                // Here we assume we do not support things like
1228
                // template<typename A, typename B>
1229
                // concept C = ...;
1230
                //
1231
                // template<typename... Ts> requires C<Ts...>
1232
                // struct S { };
1233
                // The above currently yields a diagnostic.
1234
                // We still might have default arguments for concept parameters.
1235
0
                ArgsAsWritten->NumTemplateArgs > I
1236
0
                    ? ArgsAsWritten->arguments()[I].getLocation()
1237
0
                    : SourceLocation()));
1238
0
    Atomic.ParameterMapping.emplace(TempArgs,  OccurringIndices.count());
1239
0
  }
1240
0
  Sema::InstantiatingTemplate Inst(
1241
0
      S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(),
1242
0
      Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept,
1243
0
      ArgsAsWritten->arguments().front().getSourceRange());
1244
0
  if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
1245
0
    return true;
1246
1247
0
  TemplateArgumentLoc *TempArgs =
1248
0
      new (S.Context) TemplateArgumentLoc[SubstArgs.size()];
1249
0
  std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(),
1250
0
            TempArgs);
1251
0
  Atomic.ParameterMapping.emplace(TempArgs, SubstArgs.size());
1252
0
  return false;
1253
0
}
1254
1255
static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N,
1256
0
                                        const ConceptSpecializationExpr *CSE) {
1257
0
  TemplateArgumentList TAL{TemplateArgumentList::OnStack,
1258
0
                           CSE->getTemplateArguments()};
1259
0
  MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
1260
0
      CSE->getNamedConcept(), CSE->getNamedConcept()->getLexicalDeclContext(),
1261
0
      /*Final=*/false, &TAL,
1262
0
      /*RelativeToPrimary=*/true,
1263
0
      /*Pattern=*/nullptr,
1264
0
      /*ForConstraintInstantiation=*/true);
1265
1266
0
  return substituteParameterMappings(S, N, CSE->getNamedConcept(), MLTAL,
1267
0
                                     CSE->getTemplateArgsAsWritten());
1268
0
}
1269
1270
std::optional<NormalizedConstraint>
1271
NormalizedConstraint::fromConstraintExprs(Sema &S, NamedDecl *D,
1272
0
                                          ArrayRef<const Expr *> E) {
1273
0
  assert(E.size() != 0);
1274
0
  auto Conjunction = fromConstraintExpr(S, D, E[0]);
1275
0
  if (!Conjunction)
1276
0
    return std::nullopt;
1277
0
  for (unsigned I = 1; I < E.size(); ++I) {
1278
0
    auto Next = fromConstraintExpr(S, D, E[I]);
1279
0
    if (!Next)
1280
0
      return std::nullopt;
1281
0
    *Conjunction = NormalizedConstraint(S.Context, std::move(*Conjunction),
1282
0
                                        std::move(*Next), CCK_Conjunction);
1283
0
  }
1284
0
  return Conjunction;
1285
0
}
1286
1287
std::optional<NormalizedConstraint>
1288
0
NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
1289
0
  assert(E != nullptr);
1290
1291
  // C++ [temp.constr.normal]p1.1
1292
  // [...]
1293
  // - The normal form of an expression (E) is the normal form of E.
1294
  // [...]
1295
0
  E = E->IgnoreParenImpCasts();
1296
1297
  // C++2a [temp.param]p4:
1298
  //     [...] If T is not a pack, then E is E', otherwise E is (E' && ...).
1299
  // Fold expression is considered atomic constraints per current wording.
1300
  // See http://cplusplus.github.io/concepts-ts/ts-active.html#28
1301
1302
0
  if (LogicalBinOp BO = E) {
1303
0
    auto LHS = fromConstraintExpr(S, D, BO.getLHS());
1304
0
    if (!LHS)
1305
0
      return std::nullopt;
1306
0
    auto RHS = fromConstraintExpr(S, D, BO.getRHS());
1307
0
    if (!RHS)
1308
0
      return std::nullopt;
1309
1310
0
    return NormalizedConstraint(S.Context, std::move(*LHS), std::move(*RHS),
1311
0
                                BO.isAnd() ? CCK_Conjunction : CCK_Disjunction);
1312
0
  } else if (auto *CSE = dyn_cast<const ConceptSpecializationExpr>(E)) {
1313
0
    const NormalizedConstraint *SubNF;
1314
0
    {
1315
0
      Sema::InstantiatingTemplate Inst(
1316
0
          S, CSE->getExprLoc(),
1317
0
          Sema::InstantiatingTemplate::ConstraintNormalization{}, D,
1318
0
          CSE->getSourceRange());
1319
      // C++ [temp.constr.normal]p1.1
1320
      // [...]
1321
      // The normal form of an id-expression of the form C<A1, A2, ..., AN>,
1322
      // where C names a concept, is the normal form of the
1323
      // constraint-expression of C, after substituting A1, A2, ..., AN for C’s
1324
      // respective template parameters in the parameter mappings in each atomic
1325
      // constraint. If any such substitution results in an invalid type or
1326
      // expression, the program is ill-formed; no diagnostic is required.
1327
      // [...]
1328
0
      ConceptDecl *CD = CSE->getNamedConcept();
1329
0
      SubNF = S.getNormalizedAssociatedConstraints(CD,
1330
0
                                                   {CD->getConstraintExpr()});
1331
0
      if (!SubNF)
1332
0
        return std::nullopt;
1333
0
    }
1334
1335
0
    std::optional<NormalizedConstraint> New;
1336
0
    New.emplace(S.Context, *SubNF);
1337
1338
0
    if (substituteParameterMappings(S, *New, CSE))
1339
0
      return std::nullopt;
1340
1341
0
    return New;
1342
0
  }
1343
0
  return NormalizedConstraint{new (S.Context) AtomicConstraint(S, E)};
1344
0
}
1345
1346
using NormalForm =
1347
    llvm::SmallVector<llvm::SmallVector<AtomicConstraint *, 2>, 4>;
1348
1349
0
static NormalForm makeCNF(const NormalizedConstraint &Normalized) {
1350
0
  if (Normalized.isAtomic())
1351
0
    return {{Normalized.getAtomicConstraint()}};
1352
1353
0
  NormalForm LCNF = makeCNF(Normalized.getLHS());
1354
0
  NormalForm RCNF = makeCNF(Normalized.getRHS());
1355
0
  if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Conjunction) {
1356
0
    LCNF.reserve(LCNF.size() + RCNF.size());
1357
0
    while (!RCNF.empty())
1358
0
      LCNF.push_back(RCNF.pop_back_val());
1359
0
    return LCNF;
1360
0
  }
1361
1362
  // Disjunction
1363
0
  NormalForm Res;
1364
0
  Res.reserve(LCNF.size() * RCNF.size());
1365
0
  for (auto &LDisjunction : LCNF)
1366
0
    for (auto &RDisjunction : RCNF) {
1367
0
      NormalForm::value_type Combined;
1368
0
      Combined.reserve(LDisjunction.size() + RDisjunction.size());
1369
0
      std::copy(LDisjunction.begin(), LDisjunction.end(),
1370
0
                std::back_inserter(Combined));
1371
0
      std::copy(RDisjunction.begin(), RDisjunction.end(),
1372
0
                std::back_inserter(Combined));
1373
0
      Res.emplace_back(Combined);
1374
0
    }
1375
0
  return Res;
1376
0
}
1377
1378
0
static NormalForm makeDNF(const NormalizedConstraint &Normalized) {
1379
0
  if (Normalized.isAtomic())
1380
0
    return {{Normalized.getAtomicConstraint()}};
1381
1382
0
  NormalForm LDNF = makeDNF(Normalized.getLHS());
1383
0
  NormalForm RDNF = makeDNF(Normalized.getRHS());
1384
0
  if (Normalized.getCompoundKind() == NormalizedConstraint::CCK_Disjunction) {
1385
0
    LDNF.reserve(LDNF.size() + RDNF.size());
1386
0
    while (!RDNF.empty())
1387
0
      LDNF.push_back(RDNF.pop_back_val());
1388
0
    return LDNF;
1389
0
  }
1390
1391
  // Conjunction
1392
0
  NormalForm Res;
1393
0
  Res.reserve(LDNF.size() * RDNF.size());
1394
0
  for (auto &LConjunction : LDNF) {
1395
0
    for (auto &RConjunction : RDNF) {
1396
0
      NormalForm::value_type Combined;
1397
0
      Combined.reserve(LConjunction.size() + RConjunction.size());
1398
0
      std::copy(LConjunction.begin(), LConjunction.end(),
1399
0
                std::back_inserter(Combined));
1400
0
      std::copy(RConjunction.begin(), RConjunction.end(),
1401
0
                std::back_inserter(Combined));
1402
0
      Res.emplace_back(Combined);
1403
0
    }
1404
0
  }
1405
0
  return Res;
1406
0
}
1407
1408
template<typename AtomicSubsumptionEvaluator>
1409
static bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF,
1410
0
                     AtomicSubsumptionEvaluator E) {
1411
  // C++ [temp.constr.order] p2
1412
  //   Then, P subsumes Q if and only if, for every disjunctive clause Pi in the
1413
  //   disjunctive normal form of P, Pi subsumes every conjunctive clause Qj in
1414
  //   the conjuctive normal form of Q, where [...]
1415
0
  for (const auto &Pi : PDNF) {
1416
0
    for (const auto &Qj : QCNF) {
1417
      // C++ [temp.constr.order] p2
1418
      //   - [...] a disjunctive clause Pi subsumes a conjunctive clause Qj if
1419
      //     and only if there exists an atomic constraint Pia in Pi for which
1420
      //     there exists an atomic constraint, Qjb, in Qj such that Pia
1421
      //     subsumes Qjb.
1422
0
      bool Found = false;
1423
0
      for (const AtomicConstraint *Pia : Pi) {
1424
0
        for (const AtomicConstraint *Qjb : Qj) {
1425
0
          if (E(*Pia, *Qjb)) {
1426
0
            Found = true;
1427
0
            break;
1428
0
          }
1429
0
        }
1430
0
        if (Found)
1431
0
          break;
1432
0
      }
1433
0
      if (!Found)
1434
0
        return false;
1435
0
    }
1436
0
  }
1437
0
  return true;
1438
0
}
Unexecuted instantiation: SemaConcept.cpp:bool subsumes<clang::Sema::IsAtLeastAsConstrained(clang::NamedDecl*, llvm::MutableArrayRef<clang::Expr const*>, clang::NamedDecl*, llvm::MutableArrayRef<clang::Expr const*>, bool&)::$_4>(llvm::SmallVector<llvm::SmallVector<clang::AtomicConstraint*, 2u>, 4u> const&, llvm::SmallVector<llvm::SmallVector<clang::AtomicConstraint*, 2u>, 4u> const&, clang::Sema::IsAtLeastAsConstrained(clang::NamedDecl*, llvm::MutableArrayRef<clang::Expr const*>, clang::NamedDecl*, llvm::MutableArrayRef<clang::Expr const*>, bool&)::$_4)
Unexecuted instantiation: SemaConcept.cpp:bool subsumes<clang::Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(clang::NamedDecl*, llvm::ArrayRef<clang::Expr const*>, clang::NamedDecl*, llvm::ArrayRef<clang::Expr const*>)::$_5>(llvm::SmallVector<llvm::SmallVector<clang::AtomicConstraint*, 2u>, 4u> const&, llvm::SmallVector<llvm::SmallVector<clang::AtomicConstraint*, 2u>, 4u> const&, clang::Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(clang::NamedDecl*, llvm::ArrayRef<clang::Expr const*>, clang::NamedDecl*, llvm::ArrayRef<clang::Expr const*>)::$_5)
Unexecuted instantiation: SemaConcept.cpp:bool subsumes<clang::Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(clang::NamedDecl*, llvm::ArrayRef<clang::Expr const*>, clang::NamedDecl*, llvm::ArrayRef<clang::Expr const*>)::$_6>(llvm::SmallVector<llvm::SmallVector<clang::AtomicConstraint*, 2u>, 4u> const&, llvm::SmallVector<llvm::SmallVector<clang::AtomicConstraint*, 2u>, 4u> const&, clang::Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(clang::NamedDecl*, llvm::ArrayRef<clang::Expr const*>, clang::NamedDecl*, llvm::ArrayRef<clang::Expr const*>)::$_6)
1439
1440
template<typename AtomicSubsumptionEvaluator>
1441
static bool subsumes(Sema &S, NamedDecl *DP, ArrayRef<const Expr *> P,
1442
                     NamedDecl *DQ, ArrayRef<const Expr *> Q, bool &Subsumes,
1443
0
                     AtomicSubsumptionEvaluator E) {
1444
  // C++ [temp.constr.order] p2
1445
  //   In order to determine if a constraint P subsumes a constraint Q, P is
1446
  //   transformed into disjunctive normal form, and Q is transformed into
1447
  //   conjunctive normal form. [...]
1448
0
  auto *PNormalized = S.getNormalizedAssociatedConstraints(DP, P);
1449
0
  if (!PNormalized)
1450
0
    return true;
1451
0
  const NormalForm PDNF = makeDNF(*PNormalized);
1452
1453
0
  auto *QNormalized = S.getNormalizedAssociatedConstraints(DQ, Q);
1454
0
  if (!QNormalized)
1455
0
    return true;
1456
0
  const NormalForm QCNF = makeCNF(*QNormalized);
1457
1458
0
  Subsumes = subsumes(PDNF, QCNF, E);
1459
0
  return false;
1460
0
}
1461
1462
bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
1463
                                  MutableArrayRef<const Expr *> AC1,
1464
                                  NamedDecl *D2,
1465
                                  MutableArrayRef<const Expr *> AC2,
1466
0
                                  bool &Result) {
1467
0
  if (const auto *FD1 = dyn_cast<FunctionDecl>(D1)) {
1468
0
    auto IsExpectedEntity = [](const FunctionDecl *FD) {
1469
0
      FunctionDecl::TemplatedKind Kind = FD->getTemplatedKind();
1470
0
      return Kind == FunctionDecl::TK_NonTemplate ||
1471
0
             Kind == FunctionDecl::TK_FunctionTemplate;
1472
0
    };
1473
0
    const auto *FD2 = dyn_cast<FunctionDecl>(D2);
1474
0
    (void)IsExpectedEntity;
1475
0
    (void)FD1;
1476
0
    (void)FD2;
1477
0
    assert(IsExpectedEntity(FD1) && FD2 && IsExpectedEntity(FD2) &&
1478
0
           "use non-instantiated function declaration for constraints partial "
1479
0
           "ordering");
1480
0
  }
1481
1482
0
  if (AC1.empty()) {
1483
0
    Result = AC2.empty();
1484
0
    return false;
1485
0
  }
1486
0
  if (AC2.empty()) {
1487
    // TD1 has associated constraints and TD2 does not.
1488
0
    Result = true;
1489
0
    return false;
1490
0
  }
1491
1492
0
  std::pair<NamedDecl *, NamedDecl *> Key{D1, D2};
1493
0
  auto CacheEntry = SubsumptionCache.find(Key);
1494
0
  if (CacheEntry != SubsumptionCache.end()) {
1495
0
    Result = CacheEntry->second;
1496
0
    return false;
1497
0
  }
1498
1499
0
  unsigned Depth1 = CalculateTemplateDepthForConstraints(*this, D1, true);
1500
0
  unsigned Depth2 = CalculateTemplateDepthForConstraints(*this, D2, true);
1501
1502
0
  for (size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
1503
0
    if (Depth2 > Depth1) {
1504
0
      AC1[I] = AdjustConstraintDepth(*this, Depth2 - Depth1)
1505
0
                   .TransformExpr(const_cast<Expr *>(AC1[I]))
1506
0
                   .get();
1507
0
    } else if (Depth1 > Depth2) {
1508
0
      AC2[I] = AdjustConstraintDepth(*this, Depth1 - Depth2)
1509
0
                   .TransformExpr(const_cast<Expr *>(AC2[I]))
1510
0
                   .get();
1511
0
    }
1512
0
  }
1513
1514
0
  if (subsumes(*this, D1, AC1, D2, AC2, Result,
1515
0
        [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
1516
0
          return A.subsumes(Context, B);
1517
0
        }))
1518
0
    return true;
1519
0
  SubsumptionCache.try_emplace(Key, Result);
1520
0
  return false;
1521
0
}
1522
1523
bool Sema::MaybeEmitAmbiguousAtomicConstraintsDiagnostic(NamedDecl *D1,
1524
0
    ArrayRef<const Expr *> AC1, NamedDecl *D2, ArrayRef<const Expr *> AC2) {
1525
0
  if (isSFINAEContext())
1526
    // No need to work here because our notes would be discarded.
1527
0
    return false;
1528
1529
0
  if (AC1.empty() || AC2.empty())
1530
0
    return false;
1531
1532
0
  auto NormalExprEvaluator =
1533
0
      [this] (const AtomicConstraint &A, const AtomicConstraint &B) {
1534
0
        return A.subsumes(Context, B);
1535
0
      };
1536
1537
0
  const Expr *AmbiguousAtomic1 = nullptr, *AmbiguousAtomic2 = nullptr;
1538
0
  auto IdenticalExprEvaluator =
1539
0
      [&] (const AtomicConstraint &A, const AtomicConstraint &B) {
1540
0
        if (!A.hasMatchingParameterMapping(Context, B))
1541
0
          return false;
1542
0
        const Expr *EA = A.ConstraintExpr, *EB = B.ConstraintExpr;
1543
0
        if (EA == EB)
1544
0
          return true;
1545
1546
        // Not the same source level expression - are the expressions
1547
        // identical?
1548
0
        llvm::FoldingSetNodeID IDA, IDB;
1549
0
        EA->Profile(IDA, Context, /*Canonical=*/true);
1550
0
        EB->Profile(IDB, Context, /*Canonical=*/true);
1551
0
        if (IDA != IDB)
1552
0
          return false;
1553
1554
0
        AmbiguousAtomic1 = EA;
1555
0
        AmbiguousAtomic2 = EB;
1556
0
        return true;
1557
0
      };
1558
1559
0
  {
1560
    // The subsumption checks might cause diagnostics
1561
0
    SFINAETrap Trap(*this);
1562
0
    auto *Normalized1 = getNormalizedAssociatedConstraints(D1, AC1);
1563
0
    if (!Normalized1)
1564
0
      return false;
1565
0
    const NormalForm DNF1 = makeDNF(*Normalized1);
1566
0
    const NormalForm CNF1 = makeCNF(*Normalized1);
1567
1568
0
    auto *Normalized2 = getNormalizedAssociatedConstraints(D2, AC2);
1569
0
    if (!Normalized2)
1570
0
      return false;
1571
0
    const NormalForm DNF2 = makeDNF(*Normalized2);
1572
0
    const NormalForm CNF2 = makeCNF(*Normalized2);
1573
1574
0
    bool Is1AtLeastAs2Normally = subsumes(DNF1, CNF2, NormalExprEvaluator);
1575
0
    bool Is2AtLeastAs1Normally = subsumes(DNF2, CNF1, NormalExprEvaluator);
1576
0
    bool Is1AtLeastAs2 = subsumes(DNF1, CNF2, IdenticalExprEvaluator);
1577
0
    bool Is2AtLeastAs1 = subsumes(DNF2, CNF1, IdenticalExprEvaluator);
1578
0
    if (Is1AtLeastAs2 == Is1AtLeastAs2Normally &&
1579
0
        Is2AtLeastAs1 == Is2AtLeastAs1Normally)
1580
      // Same result - no ambiguity was caused by identical atomic expressions.
1581
0
      return false;
1582
0
  }
1583
1584
  // A different result! Some ambiguous atomic constraint(s) caused a difference
1585
0
  assert(AmbiguousAtomic1 && AmbiguousAtomic2);
1586
1587
0
  Diag(AmbiguousAtomic1->getBeginLoc(), diag::note_ambiguous_atomic_constraints)
1588
0
      << AmbiguousAtomic1->getSourceRange();
1589
0
  Diag(AmbiguousAtomic2->getBeginLoc(),
1590
0
       diag::note_ambiguous_atomic_constraints_similar_expression)
1591
0
      << AmbiguousAtomic2->getSourceRange();
1592
0
  return true;
1593
0
}
1594
1595
concepts::ExprRequirement::ExprRequirement(
1596
    Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
1597
    ReturnTypeRequirement Req, SatisfactionStatus Status,
1598
    ConceptSpecializationExpr *SubstitutedConstraintExpr) :
1599
    Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
1600
                Status == SS_Dependent &&
1601
                (E->containsUnexpandedParameterPack() ||
1602
                 Req.containsUnexpandedParameterPack()),
1603
                Status == SS_Satisfied), Value(E), NoexceptLoc(NoexceptLoc),
1604
    TypeReq(Req), SubstitutedConstraintExpr(SubstitutedConstraintExpr),
1605
0
    Status(Status) {
1606
0
  assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1607
0
         "Simple requirement must not have a return type requirement or a "
1608
0
         "noexcept specification");
1609
0
  assert((Status > SS_TypeRequirementSubstitutionFailure && Req.isTypeConstraint()) ==
1610
0
         (SubstitutedConstraintExpr != nullptr));
1611
0
}
1612
1613
concepts::ExprRequirement::ExprRequirement(
1614
    SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple,
1615
    SourceLocation NoexceptLoc, ReturnTypeRequirement Req) :
1616
    Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
1617
                Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false),
1618
    Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
1619
0
    Status(SS_ExprSubstitutionFailure) {
1620
0
  assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
1621
0
         "Simple requirement must not have a return type requirement or a "
1622
0
         "noexcept specification");
1623
0
}
1624
1625
concepts::ExprRequirement::ReturnTypeRequirement::
1626
ReturnTypeRequirement(TemplateParameterList *TPL) :
1627
0
    TypeConstraintInfo(TPL, false) {
1628
0
  assert(TPL->size() == 1);
1629
0
  const TypeConstraint *TC =
1630
0
      cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint();
1631
0
  assert(TC &&
1632
0
         "TPL must have a template type parameter with a type constraint");
1633
0
  auto *Constraint =
1634
0
      cast<ConceptSpecializationExpr>(TC->getImmediatelyDeclaredConstraint());
1635
0
  bool Dependent =
1636
0
      Constraint->getTemplateArgsAsWritten() &&
1637
0
      TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
1638
0
          Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1));
1639
0
  TypeConstraintInfo.setInt(Dependent ? true : false);
1640
0
}
1641
1642
concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T) :
1643
    Requirement(RK_Type, T->getType()->isInstantiationDependentType(),
1644
                T->getType()->containsUnexpandedParameterPack(),
1645
                // We reach this ctor with either dependent types (in which
1646
                // IsSatisfied doesn't matter) or with non-dependent type in
1647
                // which the existence of the type indicates satisfaction.
1648
                /*IsSatisfied=*/true),
1649
    Value(T),
1650
    Status(T->getType()->isInstantiationDependentType() ? SS_Dependent
1651
0
                                                        : SS_Satisfied) {}