c++ modules: stream non-trailing default targs [PR105045]

This fixes the below testcase in which we neglect to stream the default
argument for T only because the subsequent parameter U doesn't also have
a default argument.

	PR c++/105045

gcc/cp/ChangeLog:

	* module.cc (trees_out::tpl_parms_fini): Don't assume default
	template arguments must be trailing.
	(trees_in::tpl_parms_fini): Likewise.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/pr105045_a.C: New test.
	* g++.dg/modules/pr105045_b.C: New test.
This commit is contained in:
Patrick Palka 2022-10-18 10:57:30 -04:00
parent c70b44f2c1
commit 0101137c7c
3 changed files with 19 additions and 14 deletions

View file

@ -10034,15 +10034,11 @@ trees_out::tpl_parms_fini (tree tmpl, unsigned tpl_levels)
tree vec = TREE_VALUE (parms);
tree_node (TREE_TYPE (vec));
tree dflt = error_mark_node;
for (unsigned ix = TREE_VEC_LENGTH (vec); ix--;)
{
tree parm = TREE_VEC_ELT (vec, ix);
if (dflt)
{
dflt = TREE_PURPOSE (parm);
tree_node (dflt);
}
tree dflt = TREE_PURPOSE (parm);
tree_node (dflt);
if (streaming_p ())
{
@ -10072,19 +10068,15 @@ trees_in::tpl_parms_fini (tree tmpl, unsigned tpl_levels)
tpl_levels--; parms = TREE_CHAIN (parms))
{
tree vec = TREE_VALUE (parms);
tree dflt = error_mark_node;
TREE_TYPE (vec) = tree_node ();
for (unsigned ix = TREE_VEC_LENGTH (vec); ix--;)
{
tree parm = TREE_VEC_ELT (vec, ix);
if (dflt)
{
dflt = tree_node ();
if (get_overrun ())
return false;
TREE_PURPOSE (parm) = dflt;
}
tree dflt = tree_node ();
if (get_overrun ())
return false;
TREE_PURPOSE (parm) = dflt;
tree decl = TREE_VALUE (parm);
if (TREE_CODE (decl) == TEMPLATE_DECL)

View file

@ -0,0 +1,7 @@
// PR c++/105045
// { dg-additional-options -fmodules-ts }
// { dg-module-cmi pr105045 }
export module pr105045;
export template<int T=0, class U> void f(U) { }

View file

@ -0,0 +1,6 @@
// PR c++/105045
// { dg-additional-options -fmodules-ts }
import pr105045;
int main() { f(0); }