[clang] [Sema] Default arguments for template parameters affect ContainsUnexpandedPacks (PR #99880)
Ilya Biryukov via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 23 10:14:40 PDT 2024
https://github.com/ilya-biryukov updated https://github.com/llvm/llvm-project/pull/99880
>From ad2d2f42282d5493761fa0af13b77dc7aab73bba Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Mon, 22 Jul 2024 15:19:07 +0200
Subject: [PATCH 1/5] [Sema] Default arguments for template parameters affect
ContainsUnexpandedPacks
This addresses the FIXME in the code. There are tests for the new
behavior in a follow up fix for #99877, which also addresses other bugs
that prevent exposing the wrong results of `ContainsUnexpandedPacks` in
the outputs of the compiler without crashes.
---
clang/lib/AST/DeclTemplate.cpp | 38 ++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 722c7fcf0b0df..f95be88e6c087 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -61,27 +61,43 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C,
bool IsPack = P->isTemplateParameterPack();
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
- if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
- ContainsUnexpandedParameterPack = true;
+ if (!IsPack) {
+ if (NTTP->getType()->containsUnexpandedParameterPack())
+ ContainsUnexpandedParameterPack = true;
+ else if (NTTP->hasDefaultArgument() &&
+ NTTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+ ContainsUnexpandedParameterPack = true;
+ }
if (NTTP->hasPlaceholderTypeConstraint())
HasConstrainedParameters = true;
} else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
- if (!IsPack &&
- TTP->getTemplateParameters()->containsUnexpandedParameterPack())
- ContainsUnexpandedParameterPack = true;
- } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
- if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
- if (TC->getImmediatelyDeclaredConstraint()
- ->containsUnexpandedParameterPack())
+ if (!IsPack) {
+ if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
ContainsUnexpandedParameterPack = true;
+ else if (TTP->hasDefaultArgument() &&
+ TTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack())
+ ContainsUnexpandedParameterPack = true;
+ }
+ } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
+ if (!IsPack && TTP->hasDefaultArgument() &&
+ TTP->getDefaultArgument()
+ .getArgument()
+ .containsUnexpandedParameterPack()) {
+ ContainsUnexpandedParameterPack = true;
+ } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
+ TC && TC->getImmediatelyDeclaredConstraint()
+ ->containsUnexpandedParameterPack()) {
+ ContainsUnexpandedParameterPack = true;
}
if (TTP->hasTypeConstraint())
HasConstrainedParameters = true;
} else {
llvm_unreachable("unexpected template parameter type");
}
- // FIXME: If a default argument contains an unexpanded parameter pack, the
- // template parameter list does too.
}
if (HasRequiresClause) {
>From 34a18e0c78c2915df201aea368f6c2763f885fbe Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Tue, 23 Jul 2024 13:01:10 +0200
Subject: [PATCH 2/5] fixup! [Sema] Default arguments for template parameters
affect ContainsUnexpandedPacks
Add a helper function to avoid code duplication.
---
clang/lib/AST/DeclTemplate.cpp | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index f95be88e6c087..5d207cfbecb97 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -45,6 +45,14 @@ using namespace clang;
//===----------------------------------------------------------------------===//
+namespace {
+template<class TemplateParam>
+bool DefaultArgumentContainsUnexpandedPack(const TemplateParam& P) {
+ return P.hasDefaultArgument() &&
+ P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
+}
+}
+
TemplateParameterList::TemplateParameterList(const ASTContext& C,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
@@ -64,10 +72,7 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C,
if (!IsPack) {
if (NTTP->getType()->containsUnexpandedParameterPack())
ContainsUnexpandedParameterPack = true;
- else if (NTTP->hasDefaultArgument() &&
- NTTP->getDefaultArgument()
- .getArgument()
- .containsUnexpandedParameterPack())
+ else if (DefaultArgumentContainsUnexpandedPack(*NTTP))
ContainsUnexpandedParameterPack = true;
}
if (NTTP->hasPlaceholderTypeConstraint())
@@ -76,17 +81,11 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C,
if (!IsPack) {
if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
ContainsUnexpandedParameterPack = true;
- else if (TTP->hasDefaultArgument() &&
- TTP->getDefaultArgument()
- .getArgument()
- .containsUnexpandedParameterPack())
+ else if (DefaultArgumentContainsUnexpandedPack(*TTP))
ContainsUnexpandedParameterPack = true;
}
} else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
- if (!IsPack && TTP->hasDefaultArgument() &&
- TTP->getDefaultArgument()
- .getArgument()
- .containsUnexpandedParameterPack()) {
+ if (!IsPack && DefaultArgumentContainsUnexpandedPack(*TTP)) {
ContainsUnexpandedParameterPack = true;
} else if (const TypeConstraint *TC = TTP->getTypeConstraint();
TC && TC->getImmediatelyDeclaredConstraint()
>From d8e2db25421c459e6f2a19baf5e387ab377378ee Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Tue, 23 Jul 2024 13:07:26 +0200
Subject: [PATCH 3/5] fixup! [Sema] Default arguments for template parameters
affect ContainsUnexpandedPacks
reformat the code
---
clang/lib/AST/DeclTemplate.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 5d207cfbecb97..c1a4181d9b6e2 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -44,14 +44,13 @@ using namespace clang;
// TemplateParameterList Implementation
//===----------------------------------------------------------------------===//
-
namespace {
-template<class TemplateParam>
-bool DefaultArgumentContainsUnexpandedPack(const TemplateParam& P) {
+template <class TemplateParam>
+bool DefaultArgumentContainsUnexpandedPack(const TemplateParam &P) {
return P.hasDefaultArgument() &&
P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
}
-}
+} // namespace
TemplateParameterList::TemplateParameterList(const ASTContext& C,
SourceLocation TemplateLoc,
>From ae4021d31bf71622765221ac68b7ff1a316fe670 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Tue, 23 Jul 2024 15:51:04 +0200
Subject: [PATCH 4/5] fixup! [Sema] Default arguments for template parameters
affect ContainsUnexpandedPacks
Simplify the code and reduce nesting
---
clang/lib/AST/DeclTemplate.cpp | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index c1a4181d9b6e2..5a47b4e646355 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -68,20 +68,16 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C,
bool IsPack = P->isTemplateParameterPack();
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
- if (!IsPack) {
- if (NTTP->getType()->containsUnexpandedParameterPack())
- ContainsUnexpandedParameterPack = true;
- else if (DefaultArgumentContainsUnexpandedPack(*NTTP))
- ContainsUnexpandedParameterPack = true;
- }
+ if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
+ DefaultArgumentContainsUnexpandedPack(*NTTP)))
+ ContainsUnexpandedParameterPack = true;
if (NTTP->hasPlaceholderTypeConstraint())
HasConstrainedParameters = true;
} else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
- if (!IsPack) {
- if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
- ContainsUnexpandedParameterPack = true;
- else if (DefaultArgumentContainsUnexpandedPack(*TTP))
- ContainsUnexpandedParameterPack = true;
+ if (!IsPack &&
+ (TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
+ DefaultArgumentContainsUnexpandedPack(*TTP))) {
+ ContainsUnexpandedParameterPack = true;
}
} else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
if (!IsPack && DefaultArgumentContainsUnexpandedPack(*TTP)) {
>From d64b95c8df6d0a287fb1924d1ced090d33d76ce3 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Tue, 23 Jul 2024 19:11:46 +0200
Subject: [PATCH 5/5] fixup! [Sema] Default arguments for template parameters
affect ContainsUnexpandedPacks
- Rename function
- Use static instead of anonymous namespace
---
clang/lib/AST/DeclTemplate.cpp | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 5a47b4e646355..976b3a3e1eced 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -44,13 +44,12 @@ using namespace clang;
// TemplateParameterList Implementation
//===----------------------------------------------------------------------===//
-namespace {
template <class TemplateParam>
-bool DefaultArgumentContainsUnexpandedPack(const TemplateParam &P) {
+static bool
+DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) {
return P.hasDefaultArgument() &&
P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
}
-} // namespace
TemplateParameterList::TemplateParameterList(const ASTContext& C,
SourceLocation TemplateLoc,
@@ -69,18 +68,18 @@ TemplateParameterList::TemplateParameterList(const ASTContext& C,
bool IsPack = P->isTemplateParameterPack();
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
- DefaultArgumentContainsUnexpandedPack(*NTTP)))
+ DefaultTemplateArgumentContainsUnexpandedPack(*NTTP)))
ContainsUnexpandedParameterPack = true;
if (NTTP->hasPlaceholderTypeConstraint())
HasConstrainedParameters = true;
} else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
if (!IsPack &&
(TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
- DefaultArgumentContainsUnexpandedPack(*TTP))) {
+ DefaultTemplateArgumentContainsUnexpandedPack(*TTP))) {
ContainsUnexpandedParameterPack = true;
}
} else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
- if (!IsPack && DefaultArgumentContainsUnexpandedPack(*TTP)) {
+ if (!IsPack && DefaultTemplateArgumentContainsUnexpandedPack(*TTP)) {
ContainsUnexpandedParameterPack = true;
} else if (const TypeConstraint *TC = TTP->getTypeConstraint();
TC && TC->getImmediatelyDeclaredConstraint()
More information about the cfe-commits
mailing list