SemaConcept.cpp 42 KB

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