Coverage Report

Created: 2022-05-14 11:35

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