public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: Fix Bases(args...)... base initializer [PR88580]
@ 2021-04-26 16:17 Patrick Palka
  2021-04-27 15:31 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Patrick Palka @ 2021-04-26 16:17 UTC (permalink / raw)
  To: gcc-patches

When substituting into the arguments of a base initializer pack
expansion, tsubst_initializer_list uses a dummy EXPR_PACK_EXPANSION
in order to expand an initializer such as Bases(args)... into
Bases#{0}(args#{0}) and so on.  But when an argument inside the base
initializer is itself an pack expansion, e.g. in Bases(args...)..., the
argument is already an EXPR_PACK_EXPANSION so we don't need to wrap it,
it's also is independent from the outer one for Bases, so we need to
multiplicatively append all expanded arguments onto the argument list
for each expanded base.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

gcc/cp/ChangeLog:

	PR c++/88580
	* pt.c (tsubst_initializer_list): Correctly handle the case
	where an argument inside a base initializer pack expansion is
	itself a pack expansion.

gcc/testsuite/ChangeLog:

	PR c++/88580
	* g++.dg/cpp0x/variadic182.C: New test.
---
 gcc/cp/pt.c                              | 28 +++++++++++++++++-------
 gcc/testsuite/g++.dg/cpp0x/variadic182.C | 18 +++++++++++++++
 2 files changed, 38 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic182.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8c3c814ce55..eaf46659f85 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -26389,9 +26389,16 @@ tsubst_initializer_list (tree t, tree argvec)
 		  tree expanded_exprs;
 
 		  /* Expand the argument.  */
-		  SET_PACK_EXPANSION_PATTERN (expr, TREE_VALUE (arg));
+		  tree value;
+		  if (TREE_CODE (TREE_VALUE (arg)) == EXPR_PACK_EXPANSION)
+		    value = TREE_VALUE (arg);
+		  else
+		    {
+		      value = expr;
+		      SET_PACK_EXPANSION_PATTERN (value, TREE_VALUE (arg));
+		    }
 		  expanded_exprs
-		    = tsubst_pack_expansion (expr, argvec,
+		    = tsubst_pack_expansion (value, argvec,
 					     tf_warning_or_error,
 					     NULL_TREE);
 		  if (expanded_exprs == error_mark_node)
@@ -26400,12 +26407,17 @@ tsubst_initializer_list (tree t, tree argvec)
 		  /* Prepend each of the expanded expressions to the
 		     corresponding TREE_LIST in EXPANDED_ARGUMENTS.  */
 		  for (i = 0; i < len; i++)
-		    {
-		      TREE_VEC_ELT (expanded_arguments, i) =
-			tree_cons (NULL_TREE,
-				   TREE_VEC_ELT (expanded_exprs, i),
-				   TREE_VEC_ELT (expanded_arguments, i));
-		    }
+		    if (TREE_CODE (TREE_VALUE (arg)) == EXPR_PACK_EXPANSION)
+		      for (int j = 0; j < TREE_VEC_LENGTH (expanded_exprs); j++)
+			TREE_VEC_ELT (expanded_arguments, i)
+			  = tree_cons (NULL_TREE,
+				       TREE_VEC_ELT (expanded_exprs, j),
+				       TREE_VEC_ELT (expanded_arguments, i));
+		    else
+		      TREE_VEC_ELT (expanded_arguments, i)
+			= tree_cons (NULL_TREE,
+				     TREE_VEC_ELT (expanded_exprs, i),
+				     TREE_VEC_ELT (expanded_arguments, i));
 		}
 	      in_base_initializer = 0;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic182.C b/gcc/testsuite/g++.dg/cpp0x/variadic182.C
new file mode 100644
index 00000000000..078de740e01
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic182.C
@@ -0,0 +1,18 @@
+// PR c++/88580
+// { dg-do compile { target c++11 } }
+
+template <class... Bases>
+struct Derived : Bases... {
+  template <class... Ts>
+  Derived(Ts... args) : Bases(args, args..., args)... { }
+};
+
+struct A { };
+struct B { };
+struct C { };
+
+struct Base1 { Base1(A, A, B, C, A); };
+struct Base2 { Base2(B, A, B, C, B); };
+struct Base3 { Base3(C, A, B, C, C); };
+
+Derived<Base1, Base2, Base3> d(A{}, B{}, C{});
-- 
2.31.1.362.g311531c9de


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] c++: Fix Bases(args...)... base initializer [PR88580]
  2021-04-26 16:17 [PATCH] c++: Fix Bases(args...)... base initializer [PR88580] Patrick Palka
@ 2021-04-27 15:31 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2021-04-27 15:31 UTC (permalink / raw)
  To: Patrick Palka, gcc-patches

On 4/26/21 12:17 PM, Patrick Palka wrote:
> When substituting into the arguments of a base initializer pack
> expansion, tsubst_initializer_list uses a dummy EXPR_PACK_EXPANSION
> in order to expand an initializer such as Bases(args)... into
> Bases#{0}(args#{0}) and so on.  But when an argument inside the base
> initializer is itself an pack expansion, e.g. in Bases(args...)..., the
> argument is already an EXPR_PACK_EXPANSION so we don't need to wrap it,
> it's also is independent from the outer one for Bases, so we need to
> multiplicatively append all expanded arguments onto the argument list
> for each expanded base.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?

OK.

> gcc/cp/ChangeLog:
> 
> 	PR c++/88580
> 	* pt.c (tsubst_initializer_list): Correctly handle the case
> 	where an argument inside a base initializer pack expansion is
> 	itself a pack expansion.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/88580
> 	* g++.dg/cpp0x/variadic182.C: New test.
> ---
>   gcc/cp/pt.c                              | 28 +++++++++++++++++-------
>   gcc/testsuite/g++.dg/cpp0x/variadic182.C | 18 +++++++++++++++
>   2 files changed, 38 insertions(+), 8 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic182.C
> 
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index 8c3c814ce55..eaf46659f85 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -26389,9 +26389,16 @@ tsubst_initializer_list (tree t, tree argvec)
>   		  tree expanded_exprs;
>   
>   		  /* Expand the argument.  */
> -		  SET_PACK_EXPANSION_PATTERN (expr, TREE_VALUE (arg));
> +		  tree value;
> +		  if (TREE_CODE (TREE_VALUE (arg)) == EXPR_PACK_EXPANSION)
> +		    value = TREE_VALUE (arg);
> +		  else
> +		    {
> +		      value = expr;
> +		      SET_PACK_EXPANSION_PATTERN (value, TREE_VALUE (arg));
> +		    }
>   		  expanded_exprs
> -		    = tsubst_pack_expansion (expr, argvec,
> +		    = tsubst_pack_expansion (value, argvec,
>   					     tf_warning_or_error,
>   					     NULL_TREE);
>   		  if (expanded_exprs == error_mark_node)
> @@ -26400,12 +26407,17 @@ tsubst_initializer_list (tree t, tree argvec)
>   		  /* Prepend each of the expanded expressions to the
>   		     corresponding TREE_LIST in EXPANDED_ARGUMENTS.  */
>   		  for (i = 0; i < len; i++)
> -		    {
> -		      TREE_VEC_ELT (expanded_arguments, i) =
> -			tree_cons (NULL_TREE,
> -				   TREE_VEC_ELT (expanded_exprs, i),
> -				   TREE_VEC_ELT (expanded_arguments, i));
> -		    }
> +		    if (TREE_CODE (TREE_VALUE (arg)) == EXPR_PACK_EXPANSION)
> +		      for (int j = 0; j < TREE_VEC_LENGTH (expanded_exprs); j++)
> +			TREE_VEC_ELT (expanded_arguments, i)
> +			  = tree_cons (NULL_TREE,
> +				       TREE_VEC_ELT (expanded_exprs, j),
> +				       TREE_VEC_ELT (expanded_arguments, i));
> +		    else
> +		      TREE_VEC_ELT (expanded_arguments, i)
> +			= tree_cons (NULL_TREE,
> +				     TREE_VEC_ELT (expanded_exprs, i),
> +				     TREE_VEC_ELT (expanded_arguments, i));
>   		}
>   	      in_base_initializer = 0;
>   
> diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic182.C b/gcc/testsuite/g++.dg/cpp0x/variadic182.C
> new file mode 100644
> index 00000000000..078de740e01
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/variadic182.C
> @@ -0,0 +1,18 @@
> +// PR c++/88580
> +// { dg-do compile { target c++11 } }
> +
> +template <class... Bases>
> +struct Derived : Bases... {
> +  template <class... Ts>
> +  Derived(Ts... args) : Bases(args, args..., args)... { }
> +};
> +
> +struct A { };
> +struct B { };
> +struct C { };
> +
> +struct Base1 { Base1(A, A, B, C, A); };
> +struct Base2 { Base2(B, A, B, C, B); };
> +struct Base3 { Base3(C, A, B, C, C); };
> +
> +Derived<Base1, Base2, Base3> d(A{}, B{}, C{});
> 


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-04-27 15:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-26 16:17 [PATCH] c++: Fix Bases(args...)... base initializer [PR88580] Patrick Palka
2021-04-27 15:31 ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).