llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Akash Manna (akash-manna-sky)

<details>
<summary>Changes</summary>

Fixes #<!-- -->216211

When a redeclaration of a function template (or an out-of-line definition of a 
member of a class template) adds a default argument, Clang emits the right 
error but leaves the rejected default argument attached to the parameter. The 
DR1344 check that runs next locates "the first defaulted parameter" as 
`getParamDecl(getMinRequiredArguments())`, which is wrong when a parameter pack 
comes first: the pack is skipped by the count but still occupies a slot. The 
lookup lands on the pack and
`assert(NewParam-&gt;hasDefaultArg())` fails. Without assertions, a bogus 
"makes this constructor a default constructor" error is
emitted instead.

After diagnosing, we now discard the rejected default argument — the same 
recovery this file already uses for other illegal default arguments. The two 
declarations then agree on the number of required arguments, so the DR1344 
check is skipped, as it should be for an addition that was never legal. Added 
regression tests for both the function-template and class-template-member paths.

LLM tools were used for this contribution. I've reviewed, built, and tested the 
change myself before pushing to GitHub.


---
Full diff: https://github.com/llvm/llvm-project/pull/217386.diff


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+6) 
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+4) 
- (modified) clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp (+10) 
- (modified) clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp (+9) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 64979e07021dc..58c50ed2a1a1d 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -505,6 +505,12 @@ features cannot lower the translation-unit ABI level;
   to a subobject and is used in a context that requires an implicit conversion.
   (#GH215900)
 
+- Fixed a crash when a redeclaration of a function template or an out-of-line
+  definition of a member of a class template added a default argument to a
+  parameter that follows a parameter pack (e.g.
+  `template <typename... T> S::S(T..., int = 10) {}`). Clang now diagnoses the
+  invalid default argument and discards it instead of asserting. (#GH216211)
+
 #### Bug Fixes to AST Handling
 
 - Fixed a non-deterministic ordering of unused local typedefs that made
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8d5ee07c5ad49..f78c03acd720b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -624,6 +624,8 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, 
FunctionDecl *Old,
         Diag(PrevForDefaultArgs->getLocation(),
              diag::note_template_prev_declaration)
             << false;
+        // Recover by discarding the default argument.
+        NewParam->setDefaultArg(nullptr);
       } else if (New->getTemplateSpecializationKind()
                    != TSK_ImplicitInstantiation &&
                  New->getTemplateSpecializationKind() != TSK_Undeclared) {
@@ -665,6 +667,8 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, 
FunctionDecl *Old,
              diag::err_param_default_argument_member_template_redecl)
           << WhichKind
           << NewParam->getDefaultArgRange();
+        // Recover by discarding the default argument.
+        NewParam->setDefaultArg(nullptr);
       }
     }
   }
diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp 
b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
index 6014268a18601..b993e3fe0a1ac 100644
--- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
@@ -106,3 +106,13 @@ void main() {
 }
 
 } // namespace pr12724
+
+namespace GH216211 {
+
+struct S {
+  template <typename... T> S(T..., int); // expected-note{{previous template 
declaration is here}}
+};
+template <typename... T>
+S::S(T..., int = 10) {} // expected-error{{default arguments cannot be added 
to a function template that has already been declared}}
+
+} // namespace GH216211
diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp 
b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp
index 9ab0b489a2c45..43d69d8764c2a 100644
--- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p6.cpp
@@ -31,3 +31,12 @@ void X0<T>::f(int = 17) { } // expected-error{{cannot be 
added}}
 // DR217 + DR205 (reading tea leaves)
 template<typename T>
 void X0<T>::Inner::g(int = 17) { } // expected-error{{cannot be added}}
+
+// GH216211
+template<typename ...T>
+struct X1 {
+  X1(T..., int);
+};
+
+template<typename ...T>
+X1<T...>::X1(T..., int = 17) { } // expected-error{{cannot be added}}

``````````

</details>


https://github.com/llvm/llvm-project/pull/217386
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to