Skip to content

Commit ba2fdcd

Browse files
authored
Merge pull request #49 from zyn0217/fix-access-checking-after-normalization
Checkpoint
2 parents 4c738cb + ddc2803 commit ba2fdcd

File tree

8 files changed

+146
-60
lines changed

8 files changed

+146
-60
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12065,6 +12065,13 @@ class Sema final : public SemaBase {
1206512065
bool UpdateArgsWithConversions = true,
1206612066
bool *ConstraintsNotSatisfied = nullptr);
1206712067

12068+
bool CheckTemplateArgumentList(
12069+
TemplateDecl *Template, TemplateParameterList *Params,
12070+
SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs,
12071+
const DefaultArguments &DefaultArgs, bool PartialTemplateArgs,
12072+
CheckTemplateArgumentInfo &CTAI, bool UpdateArgsWithConversions = true,
12073+
bool *ConstraintsNotSatisfied = nullptr);
12074+
1206812075
bool CheckTemplateTypeArgument(
1206912076
TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg,
1207012077
SmallVectorImpl<TemplateArgument> &SugaredConverted,
@@ -13402,7 +13409,7 @@ class Sema final : public SemaBase {
1340213409
TemplateArgumentListInfo &Outputs);
1340313410

1340413411
bool SubstTemplateArgumentsInParameterMapping(
13405-
ArrayRef<TemplateArgumentLoc> Args,
13412+
ArrayRef<TemplateArgumentLoc> Args, SourceLocation BaseLoc,
1340613413
const MultiLevelTemplateArgumentList &TemplateArgs,
1340713414
TemplateArgumentListInfo &Out);
1340813415

clang/include/clang/Sema/SemaConcept.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ struct NormalizedConstraint {
6969
unsigned PackSubstitutionIndex : 26;
7070
llvm::SmallBitVector Indexes;
7171
TemplateArgumentLoc *Args;
72+
TemplateParameterList *ParamList;
7273
ExprOrConcept ConstraintExpr;
7374
const NamedDecl *ConstraintDecl;
7475
};
@@ -81,6 +82,7 @@ struct NormalizedConstraint {
8182
unsigned Placeholder : 26;
8283
OccurenceList Indexes;
8384
TemplateArgumentLoc *Args;
85+
TemplateParameterList *ParamList;
8486
const Expr *Pattern;
8587
NormalizedConstraint *Constraint;
8688
};
@@ -118,6 +120,7 @@ struct NormalizedConstraint {
118120
PackIndex.toInternalRepresentation(),
119121
/*Indexes=*/{},
120122
/*Args=*/nullptr,
123+
/*ParamList=*/nullptr,
121124
ConstraintExpr,
122125
ConstraintDecl} {}
123126

@@ -128,6 +131,7 @@ struct NormalizedConstraint {
128131
/*Placeholder=*/0,
129132
/*Indexes=*/{},
130133
/*Args=*/nullptr,
134+
/*ParamList=*/nullptr,
131135
Pattern,
132136
Constraint} {}
133137

@@ -138,7 +142,8 @@ struct NormalizedConstraint {
138142
: ConceptId{{llvm::to_underlying(ConstraintKind::ConceptId),
139143
/*Placeholder=*/0, PackIndex.toInternalRepresentation(),
140144
/*Indexes=*/{},
141-
/*Args=*/nullptr, ConceptId, ConstraintDecl},
145+
/*Args=*/nullptr, /*ParamList=*/nullptr, ConceptId,
146+
ConstraintDecl},
142147
SubConstraint} {}
143148

144149
NormalizedConstraint(NormalizedConstraint *LHS, CompoundConstraintKind CCK,
@@ -160,15 +165,18 @@ struct NormalizedConstraint {
160165
return {Atomic.Args, Atomic.Indexes.count()};
161166
}
162167

163-
void InitParameterMapping(TemplateParameterList *TemplateParams, const Expr *,
164-
const ASTTemplateArgumentListInfo *ArgsAsWritten);
168+
TemplateParameterList *getUsedTemplateParamList() const {
169+
return Atomic.ParamList;
170+
}
165171

166172
void updateParameterMapping(OccurenceList Indexes,
167-
llvm::MutableArrayRef<TemplateArgumentLoc> Args) {
173+
llvm::MutableArrayRef<TemplateArgumentLoc> Args,
174+
TemplateParameterList *ParamList) {
168175
assert(getKind() != ConstraintKind::Compound);
169176
assert(Indexes.count() == Args.size());
170177
Atomic.Indexes = Indexes;
171178
Atomic.Args = Args.data();
179+
Atomic.ParamList = ParamList;
172180
}
173181

174182
bool hasMatchingParameterMapping(ASTContext &C,
@@ -283,6 +291,7 @@ class NormalizedConstraintWithParamMapping : public NormalizedConstraint {
283291
using NormalizedConstraint::hasParameterMapping;
284292
using NormalizedConstraint::mappingOccurenceList;
285293
using NormalizedConstraint::updateParameterMapping;
294+
using NormalizedConstraint::getUsedTemplateParamList;
286295

287296
const NamedDecl *getConstraintDecl() const { return Atomic.ConstraintDecl; }
288297

@@ -307,12 +316,6 @@ class AtomicConstraint : public NormalizedConstraintWithParamMapping {
307316
const Expr *getConstraintExpr() const {
308317
return cast<const Expr *>(Atomic.ConstraintExpr);
309318
}
310-
311-
void InitParameterMapping(const ASTTemplateArgumentListInfo *ArgsAsWritten) {
312-
NormalizedConstraint::InitParameterMapping(
313-
cast<TemplateDecl>(Atomic.ConstraintDecl)->getTemplateParameters(),
314-
getConstraintExpr(), ArgsAsWritten);
315-
}
316319
};
317320

318321
class FoldExpandedConstraint : public NormalizedConstraint {

clang/lib/Sema/SemaConcept.cpp

Lines changed: 76 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -377,24 +377,36 @@ SubstitutionInTemplateArguments(
377377
? Constraint.getPackSubstitutionIndex()
378378
: PackSubstitutionIndex);
379379
if (S.SubstTemplateArgumentsInParameterMapping(
380-
Constraint.getParameterMapping(), MLTAL, SubstArgs) ||
380+
Constraint.getParameterMapping(), Constraint.getBeginLoc(), MLTAL,
381+
SubstArgs) ||
381382
Trap.hasErrorOccurred())
382383
return std::nullopt;
384+
Sema::CheckTemplateArgumentInfo CTAI;
385+
auto *TD = const_cast<TemplateDecl *>(
386+
cast<TemplateDecl>(Constraint.getConstraintDecl()));
387+
if (S.CheckTemplateArgumentList(TD, Constraint.getUsedTemplateParamList(),
388+
TD->getLocation(), SubstArgs,
389+
/*DefaultArguments=*/{},
390+
/*PartialTemplateArgs=*/false, CTAI))
391+
return std::nullopt;
383392
NormalizedConstraint::OccurenceList Used =
384393
Constraint.mappingOccurenceList();
385394
SubstitutedOuterMost =
386395
llvm::to_vector_of<TemplateArgument>(MLTAL.getOutermost());
387-
for (unsigned I = 0, MappedIndex = 0; I < SubstArgs.size(); I++)
388-
if (I < Used.size() && Used[I]) {
396+
for (unsigned I = 0, MappedIndex = 0; I < Used.size(); I++) {
397+
TemplateArgument Arg;
398+
if (Used[I])
389399
// SubstitutedOuterMost[I].dump();
390400
// SubstArgs[MappedIndex].getArgument().dump();
391-
TemplateArgument Arg = S.Context.getCanonicalTemplateArgument(
392-
SubstArgs[MappedIndex++].getArgument());
393-
if (I < SubstitutedOuterMost.size())
394-
SubstitutedOuterMost[I] = Arg;
395-
else
396-
SubstitutedOuterMost.push_back(Arg);
397-
}
401+
// Arg = S.Context.getCanonicalTemplateArgument(
402+
// SubstArgs[MappedIndex++].getArgument());
403+
Arg = S.Context.getCanonicalTemplateArgument(
404+
CTAI.SugaredConverted[MappedIndex++]);
405+
if (I < SubstitutedOuterMost.size())
406+
SubstitutedOuterMost[I] = Arg;
407+
else
408+
SubstitutedOuterMost.push_back(Arg);
409+
}
398410
MLTAL.replaceOutermostTemplateArguments(
399411
const_cast<NamedDecl *>(Constraint.getConstraintDecl()),
400412
SubstitutedOuterMost);
@@ -681,7 +693,7 @@ static bool calculateConstraintSatisfaction(
681693
Ok = calculateConstraintSatisfaction(S, Constraint.getRHS(), Template,
682694
TemplateNameLoc, MLTAL, Satisfaction,
683695
PackSubstitutionIndex);
684-
if(Ok && Satisfaction.IsSatisfied && !Satisfaction.ContainsErrors)
696+
if (Ok && Satisfaction.IsSatisfied && !Satisfaction.ContainsErrors)
685697
Satisfaction.Details.erase(Satisfaction.Details.begin() + EffectiveDetailEndIndex,
686698
Satisfaction.Details.end());
687699
return Ok;
@@ -1574,26 +1586,37 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
15741586
/*OnlyDeduced=*/false,
15751587
/*Depth=*/0, OccurringIndices);
15761588
} else if (N.getKind() == NormalizedConstraint::ConstraintKind::ConceptId) {
1577-
auto Args = static_cast<ConceptIdConstraint &>(N)
1578-
.getConceptId()
1579-
->getTemplateArgsAsWritten();
1589+
auto *Args = static_cast<ConceptIdConstraint &>(N)
1590+
.getConceptId()
1591+
->getTemplateArgsAsWritten();
15801592
if (Args)
15811593
S.MarkUsedTemplateParameters(Args->arguments(),
15821594
/*Depth=*/0, OccurringIndices);
15831595
}
15841596
TemplateArgumentLoc *TempArgs =
15851597
new (S.Context) TemplateArgumentLoc[OccurringIndices.count()];
1598+
llvm::SmallVector<NamedDecl *> UsedParams;
15861599
for (unsigned I = 0, J = 0, C = TemplateParams->size(); I != C; ++I) {
15871600
SourceLocation Loc = ArgsAsWritten->NumTemplateArgs > I
15881601
? ArgsAsWritten->arguments()[I].getLocation()
15891602
: SourceLocation();
1590-
if (OccurringIndices[I])
1591-
new (&(TempArgs)[J++]) TemplateArgumentLoc(
1592-
S.getIdentityTemplateArgumentLoc(TemplateParams->begin()[I], Loc));
1603+
if (OccurringIndices[I]) {
1604+
NamedDecl *Param = TemplateParams->begin()[I];
1605+
new (&(TempArgs)[J])
1606+
TemplateArgumentLoc(S.getIdentityTemplateArgumentLoc(Param, Loc));
1607+
UsedParams.push_back(Param);
1608+
J++;
1609+
}
15931610
}
1611+
auto *UsedList = TemplateParameterList::Create(
1612+
S.Context, TemplateParams->getTemplateLoc(),
1613+
TemplateParams->getLAngleLoc(), UsedParams,
1614+
/*RAngleLoc=*/SourceLocation(),
1615+
/*RequiresClause=*/nullptr);
15941616
N.updateParameterMapping(OccurringIndices,
15951617
MutableArrayRef<TemplateArgumentLoc>{
1596-
TempArgs, OccurringIndices.count()});
1618+
TempArgs, OccurringIndices.count()},
1619+
UsedList);
15971620
}
15981621
SourceLocation InstLocBegin =
15991622
ArgsAsWritten->arguments().empty()
@@ -1610,15 +1633,39 @@ substituteParameterMappings(Sema &S, NormalizedConstraintWithParamMapping &N,
16101633
{InstLocBegin, InstLocEnd});
16111634
if (Inst.isInvalid())
16121635
return true;
1613-
if (S.SubstTemplateArgumentsInParameterMapping(N.getParameterMapping(), MLTAL,
1614-
SubstArgs))
1636+
// TransformTemplateArguments is unable to preserve the source location of a
1637+
// pack. The SourceLocation is necessary for the instantiation location.
1638+
// FIXME: The BaseLoc will be used as the location of the pack expansion,
1639+
// which is wrong.
1640+
if (S.SubstTemplateArgumentsInParameterMapping(
1641+
N.getParameterMapping(), N.getBeginLoc(), MLTAL, SubstArgs))
1642+
return true;
1643+
Sema::CheckTemplateArgumentInfo CTAI;
1644+
auto *TD =
1645+
const_cast<TemplateDecl *>(cast<TemplateDecl>(N.getConstraintDecl()));
1646+
if (S.CheckTemplateArgumentList(TD, N.getUsedTemplateParamList(),
1647+
TD->getLocation(), SubstArgs,
1648+
/*DefaultArguments=*/{},
1649+
/*PartialTemplateArgs=*/false, CTAI))
16151650
return true;
16161651
TemplateArgumentLoc *TempArgs =
1617-
new (S.Context) TemplateArgumentLoc[SubstArgs.size()];
1618-
llvm::copy(SubstArgs.arguments(), TempArgs);
1619-
N.updateParameterMapping(
1620-
N.mappingOccurenceList(),
1621-
MutableArrayRef<TemplateArgumentLoc>(TempArgs, SubstArgs.size()));
1652+
new (S.Context) TemplateArgumentLoc[CTAI.SugaredConverted.size()];
1653+
for (unsigned I = 0; I < CTAI.SugaredConverted.size(); ++I) {
1654+
SourceLocation Loc;
1655+
// If this is an empty pack, we have no corresponding SubstArgs.
1656+
if (I < SubstArgs.size())
1657+
Loc = SubstArgs.arguments()[I].getLocation();
1658+
TempArgs[I] = S.getTrivialTemplateArgumentLoc(CTAI.SugaredConverted[I],
1659+
QualType(), Loc);
1660+
}
1661+
// llvm::copy(SubstArgs.arguments(), TempArgs);
1662+
// N.updateParameterMapping(
1663+
// N.mappingOccurenceList(),
1664+
// MutableArrayRef<TemplateArgumentLoc>(TempArgs, SubstArgs.size()));
1665+
N.updateParameterMapping(N.mappingOccurenceList(),
1666+
MutableArrayRef<TemplateArgumentLoc>(
1667+
TempArgs, CTAI.SugaredConverted.size()),
1668+
N.getUsedTemplateParamList());
16221669
return false;
16231670
}
16241671

@@ -1627,12 +1674,10 @@ substituteParameterMappings(Sema &S, ConceptIdConstraint &N,
16271674
const MultiLevelTemplateArgumentList &MLTAL,
16281675
const ASTTemplateArgumentListInfo *ArgsAsWritten) {
16291676

1630-
{
1631-
if (N.getConstraintDecl()) {
1632-
substituteParameterMappings(
1633-
S, static_cast<NormalizedConstraintWithParamMapping &>(N), MLTAL,
1634-
ArgsAsWritten);
1635-
}
1677+
if (N.getConstraintDecl()) {
1678+
substituteParameterMappings(
1679+
S, static_cast<NormalizedConstraintWithParamMapping &>(N), MLTAL,
1680+
ArgsAsWritten);
16361681
}
16371682
return substituteParameterMappings(S, N.getNormalizedConstraint(), MLTAL,
16381683
ArgsAsWritten);

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5682,6 +5682,20 @@ bool Sema::CheckTemplateArgumentList(
56825682
TemplateArgumentListInfo &TemplateArgs, const DefaultArguments &DefaultArgs,
56835683
bool PartialTemplateArgs, CheckTemplateArgumentInfo &CTAI,
56845684
bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied) {
5685+
return CheckTemplateArgumentList(
5686+
Template, GetTemplateParameterList(Template), TemplateLoc, TemplateArgs,
5687+
DefaultArgs, PartialTemplateArgs, CTAI, UpdateArgsWithConversions,
5688+
ConstraintsNotSatisfied);
5689+
}
5690+
5691+
/// Check that the given template argument list is well-formed
5692+
/// for specializing the given template.
5693+
bool Sema::CheckTemplateArgumentList(
5694+
TemplateDecl *Template, TemplateParameterList *Params,
5695+
SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs,
5696+
const DefaultArguments &DefaultArgs, bool PartialTemplateArgs,
5697+
CheckTemplateArgumentInfo &CTAI, bool UpdateArgsWithConversions,
5698+
bool *ConstraintsNotSatisfied) {
56855699

56865700
if (ConstraintsNotSatisfied)
56875701
*ConstraintsNotSatisfied = false;
@@ -5691,8 +5705,6 @@ bool Sema::CheckTemplateArgumentList(
56915705
// template.
56925706
TemplateArgumentListInfo NewArgs = TemplateArgs;
56935707

5694-
TemplateParameterList *Params = GetTemplateParameterList(Template);
5695-
56965708
SourceLocation RAngleLoc = NewArgs.getRAngleLoc();
56975709

56985710
// C++23 [temp.arg.general]p1:
@@ -5884,6 +5896,17 @@ bool Sema::CheckTemplateArgumentList(
58845896
return true;
58855897
}
58865898

5899+
// For constraint parameter mapping, we have already built a pack in
5900+
// TransformTemplateArguments
5901+
// if (inParameterMappingSubstitution()) {
5902+
// llvm::copy(SugaredArgumentPack, std::back_inserter(CTAI.SugaredConverted));
5903+
// SugaredArgumentPack.clear();
5904+
// llvm::copy(CanonicalArgumentPack, std::back_inserter(CTAI.CanonicalConverted));
5905+
// CanonicalArgumentPack.clear();
5906+
// ++Param;
5907+
// continue;
5908+
// }
5909+
58875910
CTAI.SugaredConverted.push_back(
58885911
TemplateArgument::CreatePackCopy(Context, SugaredArgumentPack));
58895912
SugaredArgumentPack.clear();

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6634,6 +6634,7 @@ struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor {
66346634
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl()))
66356635
if (NTTP->getDepth() == Depth)
66366636
Used[NTTP->getIndex()] = true;
6637+
DynamicRecursiveASTVisitor::TraverseType(E->getType());
66376638
return true;
66386639
}
66396640
};
@@ -6974,10 +6975,13 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
69746975
break;
69756976

69766977
case Type::UnaryTransform:
6977-
if (!OnlyDeduced)
6978-
MarkUsedTemplateParameters(Ctx,
6979-
cast<UnaryTransformType>(T)->getUnderlyingType(),
6980-
OnlyDeduced, Depth, Used);
6978+
if (!OnlyDeduced) {
6979+
auto *UTT = cast<UnaryTransformType>(T);
6980+
auto Next = UTT->getUnderlyingType();
6981+
if (Next.isNull())
6982+
Next = UTT->getBaseType();
6983+
MarkUsedTemplateParameters(Ctx, Next, OnlyDeduced, Depth, Used);
6984+
}
69816985
break;
69826986

69836987
case Type::PackExpansion:

0 commit comments

Comments
 (0)