Coverage Report

Created: 2021-09-21 08:58

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