[PATCH] D79800: [Sema] Remove default values for arguments prior to a parameter pack if the pack is used
Raul Tambre via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed May 13 10:17:19 PDT 2020
tambre updated this revision to Diff 263759.
tambre added a comment.
Simplify code, improve comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D79800/new/
https://reviews.llvm.org/D79800
Files:
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/test/CXX/drs/dr7xx.cpp
Index: clang/test/CXX/drs/dr7xx.cpp
===================================================================
--- clang/test/CXX/drs/dr7xx.cpp
+++ clang/test/CXX/drs/dr7xx.cpp
@@ -230,5 +230,12 @@
template <typename... T>
void h(int i = 0, T ...args, int j = 1) {}
+
+// PR23029
+// Ensure passing parameters using the parameter packs actually works.
+void use() {
+ f(0, 1);
+ h(0, 1);
+}
#endif
}
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1974,6 +1974,47 @@
TemplateArgumentList::CreateCopy(SemaRef.Context,
Innermost),
/*InsertPos=*/nullptr);
+
+ // Parameter packs are allowed after parameters with default values.
+ // If the specialized Function has more parameters than the TemplatedDecl
+ // then the default values aren't used and the parameter pack is used and we
+ // need to remove default values from non-pack parameters to prevent it
+ // being diagnosed as invalid code due to the expanded parameters lacking
+ // default values.
+ FunctionDecl *TemplatedDecl = FunctionTemplate->getTemplatedDecl();
+ unsigned NumTemplatedParams = TemplatedDecl->getNumParams();
+
+ if (Function->getNumParams() >= NumTemplatedParams) {
+ unsigned FirstDefault = 0;
+ bool FoundDefault = false;
+
+ for (unsigned p = 0; p < NumTemplatedParams; ++p) {
+ ParmVarDecl *Param = TemplatedDecl->getParamDecl(p);
+
+ if (FoundDefault) {
+ if (Param->isParameterPack()) {
+ // Found a parameter pack. Remove default arguments for all
+ // parameters prior to this since we now know this is valid code
+ // without them.
+ for (unsigned d = FirstDefault; d < p; ++d) {
+ ParmVarDecl *Param = Function->getParamDecl(d);
+ Param->setDefaultArg(nullptr);
+ }
+
+ break;
+ }
+
+ // If we encounter a regular parameter with no default value after
+ // we've encountered any with a default, then this is invalid code and
+ // we bail out. This is diagnosed later in CheckCXXDefaultArguments().
+ if (!Param->hasDefaultArg())
+ break;
+ } else if (Param->hasDefaultArg()) {
+ FirstDefault = p;
+ FoundDefault = true;
+ }
+ }
+ }
} else if (isFriend && D->isThisDeclarationADefinition()) {
// Do not connect the friend to the template unless it's actually a
// definition. We don't want non-template functions to be marked as being
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79800.263759.patch
Type: text/x-patch
Size: 2808 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200513/7608b498/attachment.bin>
More information about the cfe-commits
mailing list