Skip to content

Commit 4774916

Browse files
mizvekovmahesh-attarde
authored andcommitted
[clang] fix transformation of subst constant template parameter nodes (llvm#161029)
This simplifies those transforms a lot, removing a bunch of workarounds which were introducing problems. The transforms become independent of the template instantiator, so they are moved to TreeTransform instead. Fixes llvm#131342 This PR was already reviewed and approved at llvm#160777, but I accidentally merged that into another PR, instead of main.
1 parent 69069bf commit 4774916

File tree

13 files changed

+168
-215
lines changed

13 files changed

+168
-215
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ Bug Fixes in This Version
361361
first parameter. (#GH113323).
362362
- Fixed a crash with incompatible pointer to integer conversions in designated
363363
initializers involving string literals. (#GH154046)
364+
- Fix crash on CTAD for alias template. (#GH131342)
364365
- Clang now emits a frontend error when a function marked with the `flatten` attribute
365366
calls another function that requires target features not enabled in the caller. This
366367
prevents a fatal error in the backend.

clang/include/clang/AST/ExprCXX.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4714,7 +4714,7 @@ class SubstNonTypeTemplateParmExpr : public Expr {
47144714
// sugared: it doesn't need to be resugared later.
47154715
bool getFinal() const { return Final; }
47164716

4717-
NamedDecl *getParameter() const;
4717+
NonTypeTemplateParmDecl *getParameter() const;
47184718

47194719
bool isReferenceParameter() const { return AssociatedDeclAndRef.getInt(); }
47204720

clang/include/clang/AST/TypeBase.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3495,7 +3495,9 @@ class AdjustedType : public Type, public llvm::FoldingSetNode {
34953495

34963496
AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
34973497
QualType CanonicalPtr)
3498-
: Type(TC, CanonicalPtr, OriginalTy->getDependence()),
3498+
: Type(TC, CanonicalPtr,
3499+
AdjustedTy->getDependence() |
3500+
(OriginalTy->getDependence() & ~TypeDependence::Dependent)),
34993501
OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
35003502

35013503
public:

clang/include/clang/Sema/Sema.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11714,6 +11714,23 @@ class Sema final : public SemaBase {
1171411714
const TemplateArgumentListInfo *TemplateArgs,
1171511715
bool IsAddressOfOperand);
1171611716

11717+
UnsignedOrNone getPackIndex(TemplateArgument Pack) const {
11718+
return Pack.pack_size() - 1 - *ArgPackSubstIndex;
11719+
}
11720+
11721+
TemplateArgument
11722+
getPackSubstitutedTemplateArgument(TemplateArgument Arg) const {
11723+
Arg = Arg.pack_elements()[*ArgPackSubstIndex];
11724+
if (Arg.isPackExpansion())
11725+
Arg = Arg.getPackExpansionPattern();
11726+
return Arg;
11727+
}
11728+
11729+
ExprResult BuildSubstNonTypeTemplateParmExpr(
11730+
Decl *AssociatedDecl, const NonTypeTemplateParmDecl *NTTP,
11731+
SourceLocation loc, TemplateArgument Replacement,
11732+
UnsignedOrNone PackIndex, bool Final);
11733+
1171711734
/// Form a template name from a name that is syntactically required to name a
1171811735
/// template, either due to use of the 'template' keyword or because a name in
1171911736
/// this syntactic context is assumed to name a template (C++

clang/lib/AST/ExprCXX.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,8 +1725,8 @@ SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
17251725
return new (Storage) SizeOfPackExpr(EmptyShell(), NumPartialArgs);
17261726
}
17271727

1728-
NamedDecl *SubstNonTypeTemplateParmExpr::getParameter() const {
1729-
return cast<NamedDecl>(
1728+
NonTypeTemplateParmDecl *SubstNonTypeTemplateParmExpr::getParameter() const {
1729+
return cast<NonTypeTemplateParmDecl>(
17301730
getReplacedTemplateParameterList(getAssociatedDecl())->asArray()[Index]);
17311731
}
17321732

clang/lib/AST/StmtProfile.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,8 @@ void StmtProfiler::VisitExpr(const Expr *S) {
13531353
}
13541354

13551355
void StmtProfiler::VisitConstantExpr(const ConstantExpr *S) {
1356-
VisitExpr(S);
1356+
// Profile exactly as the sub-expression.
1357+
Visit(S->getSubExpr());
13571358
}
13581359

13591360
void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,40 @@ Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
775775
TemplateArgs);
776776
}
777777

778+
ExprResult Sema::BuildSubstNonTypeTemplateParmExpr(
779+
Decl *AssociatedDecl, const NonTypeTemplateParmDecl *NTTP,
780+
SourceLocation Loc, TemplateArgument Arg, UnsignedOrNone PackIndex,
781+
bool Final) {
782+
// The template argument itself might be an expression, in which case we just
783+
// return that expression. This happens when substituting into an alias
784+
// template.
785+
Expr *Replacement;
786+
bool refParam = true;
787+
if (Arg.getKind() == TemplateArgument::Expression) {
788+
Replacement = Arg.getAsExpr();
789+
refParam = Replacement->isLValue();
790+
if (refParam && Replacement->getType()->isRecordType()) {
791+
QualType ParamType =
792+
NTTP->isExpandedParameterPack()
793+
? NTTP->getExpansionType(*SemaRef.ArgPackSubstIndex)
794+
: NTTP->getType();
795+
if (const auto *PET = dyn_cast<PackExpansionType>(ParamType))
796+
ParamType = PET->getPattern();
797+
refParam = ParamType->isReferenceType();
798+
}
799+
} else {
800+
ExprResult result =
801+
SemaRef.BuildExpressionFromNonTypeTemplateArgument(Arg, Loc);
802+
if (result.isInvalid())
803+
return ExprError();
804+
Replacement = result.get();
805+
refParam = Arg.getNonTypeTemplateArgumentType()->isReferenceType();
806+
}
807+
return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(
808+
Replacement->getType(), Replacement->getValueKind(), Loc, Replacement,
809+
AssociatedDecl, NTTP->getIndex(), PackIndex, refParam, Final);
810+
}
811+
778812
bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
779813
NamedDecl *Instantiation,
780814
bool InstantiatedFromMember,

0 commit comments

Comments
 (0)