Skip to content

Commit 877bd0a

Browse files
committed
Save the checkpoint
There are 6 tests failing now! Failed Tests (6): Clang :: AST/ByteCode/libcxx/deref-to-array.cpp Clang :: AST/ByteCode/libcxx/primitive-temporary.cpp Clang :: CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp Clang :: CXX/temp/temp.constr/temp.constr.normal/p1.cpp Clang :: Modules/GH60336.cpp Clang :: SemaTemplate/concepts-recursive-inst.cpp
1 parent e3dd06f commit 877bd0a

File tree

4 files changed

+115
-63
lines changed

4 files changed

+115
-63
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include "clang/Sema/Redeclaration.h"
6666
#include "clang/Sema/Scope.h"
6767
#include "clang/Sema/SemaBase.h"
68+
#include "clang/Sema/SemaConcept.h"
6869
#include "clang/Sema/TypoCorrection.h"
6970
#include "clang/Sema/Weak.h"
7071
#include "llvm/ADT/APInt.h"
@@ -14901,8 +14902,6 @@ class Sema final : public SemaBase {
1490114902
const NamedDecl *D1, ArrayRef<AssociatedConstraint> AC1,
1490214903
const NamedDecl *D2, ArrayRef<AssociatedConstraint> AC2);
1490314904

14904-
llvm::DenseMap<unsigned, MutableArrayRef<TemplateArgumentLoc>>
14905-
ParameterMappingCache;
1490614905
private:
1490714906
/// Caches pairs of template-like decls whose associated constraints were
1490814907
/// checked for subsumption and whether or not the first's constraints did in

clang/include/clang/Sema/SemaConcept.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ struct NormalizedConstraint {
8989

9090
struct ConceptIdBits : AtomicBits {
9191
NormalizedConstraint *Sub;
92+
93+
// Only used for parameter mapping.
94+
const ConceptSpecializationExpr *CSE;
9295
};
9396

9497
struct CompoundBits {
@@ -138,13 +141,15 @@ struct NormalizedConstraint {
138141
NormalizedConstraint(const ConceptReference *ConceptId,
139142
const NamedDecl *ConstraintDecl,
140143
NormalizedConstraint *SubConstraint,
144+
const ConceptSpecializationExpr *CSE,
141145
UnsignedOrNone PackIndex)
142146
: ConceptId{{llvm::to_underlying(ConstraintKind::ConceptId),
143147
/*Placeholder=*/0, PackIndex.toInternalRepresentation(),
144148
/*Indexes=*/{},
145149
/*Args=*/nullptr, /*ParamList=*/nullptr, ConceptId,
146150
ConstraintDecl},
147-
SubConstraint} {}
151+
SubConstraint,
152+
CSE} {}
148153

149154
NormalizedConstraint(NormalizedConstraint *LHS, CompoundConstraintKind CCK,
150155
NormalizedConstraint *RHS)
@@ -357,9 +362,14 @@ class ConceptIdConstraint : public NormalizedConstraintWithParamMapping {
357362
const ConceptReference *ConceptId,
358363
NormalizedConstraint *SubConstraint,
359364
const NamedDecl *ConstraintDecl,
365+
const ConceptSpecializationExpr *CSE,
360366
UnsignedOrNone PackIndex) {
361367
return new (Ctx) ConceptIdConstraint(ConceptId, ConstraintDecl,
362-
SubConstraint, PackIndex);
368+
SubConstraint, CSE, PackIndex);
369+
}
370+
371+
const ConceptSpecializationExpr *getConceptSpecializationExpr() const {
372+
return ConceptId.CSE;
363373
}
364374

365375
const ConceptReference *getConceptId() const {

clang/lib/Sema/SemaConcept.cpp

Lines changed: 100 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
#include "llvm/ADT/PointerUnion.h"
3636
#include "llvm/ADT/SmallVector.h"
3737
#include "llvm/ADT/StringExtras.h"
38+
#include "llvm/Support/Timer.h"
39+
#include "llvm/Support/WithColor.h"
3840
#include <cstddef>
3941
#include <optional>
4042

@@ -390,16 +392,23 @@ SubstitutionInTemplateArguments(
390392
Constraint.mappingOccurenceList();
391393
SubstitutedOuterMost =
392394
llvm::to_vector_of<TemplateArgument>(MLTAL.getOutermost());
395+
unsigned Offset = 0;
393396
for (unsigned I = 0, MappedIndex = 0; I < Used.size(); I++) {
394397
TemplateArgument Arg;
395398
if (Used[I])
396399
Arg = S.Context.getCanonicalTemplateArgument(
397400
CTAI.SugaredConverted[MappedIndex++]);
398-
if (I < SubstitutedOuterMost.size())
401+
if (I < SubstitutedOuterMost.size()) {
399402
SubstitutedOuterMost[I] = Arg;
400-
else
403+
Offset = I + 1;
404+
} else {
401405
SubstitutedOuterMost.push_back(Arg);
406+
Offset = SubstitutedOuterMost.size();
407+
}
402408
}
409+
if (Offset < SubstitutedOuterMost.size())
410+
SubstitutedOuterMost.erase(SubstitutedOuterMost.begin() + Offset);
411+
403412
MLTAL.replaceOutermostTemplateArguments(
404413
const_cast<NamedDecl *>(Constraint.getConstraintDecl()),
405414
SubstitutedOuterMost);
@@ -765,7 +774,8 @@ static bool CheckConstraintSatisfaction(
765774
if (TopLevelConceptId) {
766775
C = ConceptIdConstraint::Create(S.getASTContext(), TopLevelConceptId,
767776
const_cast<NormalizedConstraint *>(C),
768-
Template, S.ArgPackSubstIndex);
777+
Template, /*CSE=*/nullptr,
778+
S.ArgPackSubstIndex);
769779
}
770780

771781
return !calculateConstraintSatisfaction(
@@ -1535,27 +1545,6 @@ void Sema::DiagnoseUnsatisfiedConstraint(
15351545
ConstraintExpr->getBeginLoc(), First);
15361546
}
15371547

1538-
const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints(
1539-
ConstrainedDeclOrNestedRequirement ConstrainedDeclOrNestedReq,
1540-
ArrayRef<AssociatedConstraint> AssociatedConstraints) {
1541-
if (!ConstrainedDeclOrNestedReq)
1542-
return NormalizedConstraint::fromAssociatedConstraints(
1543-
*this, nullptr, AssociatedConstraints);
1544-
1545-
// FIXME: ConstrainedDeclOrNestedReq is never a NestedRequirement!
1546-
const NamedDecl *ND =
1547-
ConstrainedDeclOrNestedReq.dyn_cast<const NamedDecl *>();
1548-
auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq);
1549-
if (CacheEntry == NormalizationCache.end()) {
1550-
auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
1551-
*this, ND, AssociatedConstraints);
1552-
CacheEntry =
1553-
NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized)
1554-
.first;
1555-
}
1556-
return CacheEntry->second;
1557-
}
1558-
15591548
static bool
15601549
substituteParameterMappings(Sema &S, NormalizedConstraint &N,
15611550
const MultiLevelTemplateArgumentList &MLTAL,
@@ -1626,30 +1615,6 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
16261615
if (Inst.isInvalid())
16271616
return true;
16281617

1629-
unsigned Hash;
1630-
llvm::FoldingSetNodeID ID;
1631-
auto &Context = S.getASTContext();
1632-
if (N.getKind() == NormalizedConstraint::ConstraintKind::ConceptId) {
1633-
ID.AddPointer(static_cast<ConceptIdConstraint &>(N)
1634-
.getConceptId()
1635-
->getNamedConcept()
1636-
->getCanonicalDecl());
1637-
for (auto &ArgLoc : static_cast<ConceptIdConstraint &>(N)
1638-
.getConceptId()
1639-
->getTemplateArgsAsWritten()
1640-
->arguments())
1641-
ArgLoc.getArgument().Profile(ID, Context);
1642-
1643-
Hash = ID.ComputeHash();
1644-
if (auto Iter = S.ParameterMappingCache.find(Hash);
1645-
Iter != S.ParameterMappingCache.end()) {
1646-
N.updateParameterMapping(N.mappingOccurenceList(), Iter->second,
1647-
N.getUsedTemplateParamList());
1648-
return false;
1649-
}
1650-
}
1651-
// FIXME: Cache for atomic constraints.
1652-
16531618
// TransformTemplateArguments is unable to preserve the source location of a
16541619
// pack. The SourceLocation is necessary for the instantiation location.
16551620
// FIXME: The BaseLoc will be used as the location of the pack expansion,
@@ -1683,23 +1648,46 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
16831648
CTAI.SugaredConverted.size());
16841649
N.updateParameterMapping(N.mappingOccurenceList(), Mapping,
16851650
N.getUsedTemplateParamList());
1686-
if (N.getKind() == NormalizedConstraint::ConstraintKind::ConceptId)
1687-
S.ParameterMappingCache.insert({Hash, Mapping});
16881651
return false;
16891652
}
16901653

16911654
static bool
16921655
substituteParameterMappings(Sema &S, ConceptIdConstraint &N,
16931656
const MultiLevelTemplateArgumentList &MLTAL,
16941657
const ASTTemplateArgumentListInfo *ArgsAsWritten) {
1695-
1658+
assert(N.getConstraintDecl());
1659+
#if 0
1660+
return substituteParameterMappings(
1661+
S, static_cast<NormalizedConstraintWithParamMapping &>(N), MLTAL,
1662+
ArgsAsWritten);
1663+
#else
1664+
auto TemplateArgs = MLTAL;
16961665
if (N.getConstraintDecl()) {
1697-
substituteParameterMappings(
1698-
S, static_cast<NormalizedConstraintWithParamMapping &>(N), MLTAL,
1699-
ArgsAsWritten);
1666+
if (substituteParameterMappings(
1667+
S, static_cast<NormalizedConstraintWithParamMapping &>(N),
1668+
TemplateArgs, ArgsAsWritten))
1669+
return true;
1670+
auto *CSE = N.getConceptSpecializationExpr();
1671+
assert(CSE);
1672+
TemplateArgumentListInfo Out;
1673+
assert(!N.getBeginLoc().isInvalid());
1674+
if (S.SubstTemplateArgumentsInParameterMapping(
1675+
CSE->getTemplateArgsAsWritten()->arguments(), N.getBeginLoc(),
1676+
MLTAL, Out))
1677+
return true;
1678+
Sema::CheckTemplateArgumentInfo CTAI;
1679+
if (S.CheckTemplateArgumentList(CSE->getNamedConcept(),
1680+
CSE->getConceptNameInfo().getLoc(), Out,
1681+
/*DefaultArgs=*/{},
1682+
/*PartialTemplateArgs=*/false, CTAI,
1683+
/*UpdateArgsWithConversions=*/false))
1684+
return true;
1685+
TemplateArgs.replaceOutermostTemplateArguments(
1686+
TemplateArgs.getAssociatedDecl(0).first, CTAI.CanonicalConverted);
17001687
}
1701-
return substituteParameterMappings(S, N.getNormalizedConstraint(), MLTAL,
1702-
ArgsAsWritten);
1688+
return substituteParameterMappings(S, N.getNormalizedConstraint(),
1689+
TemplateArgs, ArgsAsWritten);
1690+
#endif
17031691
}
17041692

17051693
static bool
@@ -1742,10 +1730,40 @@ static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N,
17421730
// Don't build Subst* nodes to model lambda expressions.
17431731
// The transform of Subst* is oblivious to the lambda type.
17441732
MLTAL.setKind(TemplateSubstitutionKind::Rewrite);
1733+
Sema::InstantiatingTemplate Inst(
1734+
S, N.getBeginLoc(),
1735+
Sema::InstantiatingTemplate::ParameterMappingSubstitution{},
1736+
CSE->getNamedConcept(), {N.getBeginLoc(), N.getEndLoc()});
1737+
if (Inst.isInvalid())
1738+
return true;
1739+
17451740
return substituteParameterMappings(S, N, MLTAL,
17461741
CSE->getTemplateArgsAsWritten());
17471742
}
17481743

1744+
static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N) {
1745+
switch (N.getKind()) {
1746+
case NormalizedConstraint::ConstraintKind::Atomic:
1747+
return false;
1748+
case NormalizedConstraint::ConstraintKind::FoldExpanded: {
1749+
Sema::ArgPackSubstIndexRAII _(S, std::nullopt);
1750+
return substituteParameterMappings(
1751+
S, static_cast<FoldExpandedConstraint &>(N).getNormalizedPattern());
1752+
}
1753+
case NormalizedConstraint::ConstraintKind::ConceptId: {
1754+
auto &CC = static_cast<ConceptIdConstraint &>(N);
1755+
return substituteParameterMappings(S, CC.getNormalizedConstraint(),
1756+
CC.getConceptSpecializationExpr());
1757+
}
1758+
case NormalizedConstraint::ConstraintKind::Compound: {
1759+
auto &Compound = static_cast<CompoundConstraint &>(N);
1760+
if (substituteParameterMappings(S, Compound.getLHS()))
1761+
return true;
1762+
return substituteParameterMappings(S, Compound.getRHS());
1763+
}
1764+
}
1765+
}
1766+
17491767
NormalizedConstraint *NormalizedConstraint::fromAssociatedConstraints(
17501768
Sema &S, const NamedDecl *D, ArrayRef<AssociatedConstraint> ACs) {
17511769
assert(ACs.size() != 0);
@@ -1824,11 +1842,11 @@ NormalizedConstraint *NormalizedConstraint::fromConstraintExpr(
18241842
if (!SubNF)
18251843
return nullptr;
18261844
}
1827-
if (substituteParameterMappings(S, *SubNF, CSE))
1828-
return nullptr;
1845+
// if (substituteParameterMappings(S, *SubNF, CSE))
1846+
// return nullptr;
18291847

18301848
return ConceptIdConstraint::Create(
1831-
S.getASTContext(), CSE->getConceptReference(), SubNF, D, SubstIndex);
1849+
S.getASTContext(), CSE->getConceptReference(), SubNF, D, CSE, SubstIndex);
18321850

18331851
} else if (auto *FE = dyn_cast<const CXXFoldExpr>(E);
18341852
FE && S.getLangOpts().CPlusPlus26 &&
@@ -1870,6 +1888,29 @@ NormalizedConstraint *NormalizedConstraint::fromConstraintExpr(
18701888
return AtomicConstraint::Create(S.getASTContext(), E, D, SubstIndex);
18711889
}
18721890

1891+
const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints(
1892+
ConstrainedDeclOrNestedRequirement ConstrainedDeclOrNestedReq,
1893+
ArrayRef<AssociatedConstraint> AssociatedConstraints) {
1894+
if (!ConstrainedDeclOrNestedReq)
1895+
return NormalizedConstraint::fromAssociatedConstraints(
1896+
*this, nullptr, AssociatedConstraints);
1897+
1898+
// FIXME: ConstrainedDeclOrNestedReq is never a NestedRequirement!
1899+
const NamedDecl *ND =
1900+
ConstrainedDeclOrNestedReq.dyn_cast<const NamedDecl *>();
1901+
auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq);
1902+
if (CacheEntry == NormalizationCache.end()) {
1903+
auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
1904+
*this, ND, AssociatedConstraints);
1905+
CacheEntry =
1906+
NormalizationCache.try_emplace(ConstrainedDeclOrNestedReq, Normalized)
1907+
.first;
1908+
if (!Normalized || substituteParameterMappings(*this, *Normalized))
1909+
return nullptr;
1910+
}
1911+
return CacheEntry->second;
1912+
}
1913+
18731914
bool FoldExpandedConstraint::AreCompatibleForSubsumption(
18741915
const FoldExpandedConstraint &A, const FoldExpandedConstraint &B) {
18751916

clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// RUN: %clang_cc1 -std=c++2a -x c++ -verify %s
2+
// FIXME: RUN: %clang_cc1 -std=c++2c -x c++ -verify %s
23

34
template<typename T> concept True = true;
45
template<typename T> concept Foo = True<T*>;
56
template<typename T> concept Bar = Foo<T&>;
67
template<typename T> requires Bar<T> struct S { };
8+
// FIXME: GCC rejects: https://gcc.godbolt.org/z/c9G7G6PTx if the specialization is present.
79
template<typename T> requires Bar<T> && true struct S<T> { };
810

911
template<typename T> concept True2 = sizeof(T) >= 0;

0 commit comments

Comments
 (0)