public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] c++: order of trailing arguments in a trait expr
@ 2021-09-30 16:52 Patrick Palka
  2021-09-30 16:52 ` [PATCH 2/2] c++: __is_trivially_xible and multi-arg aggr paren init [PR102535] Patrick Palka
  2021-09-30 20:13 ` [PATCH 1/2] c++: order of trailing arguments in a trait expr Jason Merrill
  0 siblings, 2 replies; 4+ messages in thread
From: Patrick Palka @ 2021-09-30 16:52 UTC (permalink / raw)
  To: gcc-patches

When parsing a variadic trait expression, we build up the list of
trailing arguments in reverse, but we're neglecting to reverse the list
to its true order afterwards.  This causes us to confuse the meaning of
e.g. __is_xible(x, y, z) and __is_xible(x, z, y).

Note that bug isn't exposed in the standard type traits within libstdc++
because there we pass a pack expansion as the single trailing argument
to __is_xible, which indeed gets expanded correctly by tsubst_tree_list.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?  What about backports?  This isn't a regression AFAICT.

gcc/cp/ChangeLog:

	* parser.c (cp_parser_trait_expr): Call nreverse on the list of
	trailing arguments.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/is_constructible6.C: New test.
---
 gcc/cp/parser.c                              |  1 +
 gcc/testsuite/g++.dg/ext/is_constructible6.C | 10 ++++++++++
 2 files changed, 11 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_constructible6.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 8430445ef8c..04f5a24cc03 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10832,6 +10832,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
 	    return error_mark_node;
 	  type2 = tree_cons (NULL_TREE, elt, type2);
 	}
+      type2 = nreverse (type2);
     }
 
   location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
diff --git a/gcc/testsuite/g++.dg/ext/is_constructible6.C b/gcc/testsuite/g++.dg/ext/is_constructible6.C
new file mode 100644
index 00000000000..7fce153fa75
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_constructible6.C
@@ -0,0 +1,10 @@
+// Verify we respect the order of trailing arguments passed to
+// __is_constructible.
+
+struct A { };
+struct B { };
+struct C { C(A, B); };
+
+extern int n[true];
+extern int n[ __is_constructible(C, A, B)];
+extern int n[!__is_constructible(C, B, A)];
-- 
2.33.0.610.gcefe983a32


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

* [PATCH 2/2] c++: __is_trivially_xible and multi-arg aggr paren init [PR102535]
  2021-09-30 16:52 [PATCH 1/2] c++: order of trailing arguments in a trait expr Patrick Palka
@ 2021-09-30 16:52 ` Patrick Palka
  2021-09-30 20:15   ` Jason Merrill
  2021-09-30 20:13 ` [PATCH 1/2] c++: order of trailing arguments in a trait expr Jason Merrill
  1 sibling, 1 reply; 4+ messages in thread
From: Patrick Palka @ 2021-09-30 16:52 UTC (permalink / raw)
  To: gcc-patches

is_xible_helper assumes only 0- and 1-argument ctors can be trivial, but
C++20 aggregate paren init means multi-arg ctors can now be trivial too.

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

	PR c++/102535

gcc/cp/ChangeLog:

	* method.c (is_xible_helper): Don't exit early for multi-arg
	ctors in C++20.

gcc/testsuite/ChangeLog:

	* g++.dg/ext/is_trivially_constructible7.C: New test.
---
 gcc/cp/method.c                                 |  4 +++-
 .../g++.dg/ext/is_trivially_constructible7.C    | 17 +++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 3c3495227ce..c38912a7ce9 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -2094,8 +2094,10 @@ is_xible_helper (enum tree_code code, tree to, tree from, bool trivial)
   tree expr;
   if (code == MODIFY_EXPR)
     expr = assignable_expr (to, from);
-  else if (trivial && from && TREE_CHAIN (from))
+  else if (trivial && from && TREE_CHAIN (from)
+	   && cxx_dialect < cxx20)
     return error_mark_node; // only 0- and 1-argument ctors can be trivial
+			    // before C++20 aggregate paren init
   else if (TREE_CODE (to) == ARRAY_TYPE && !TYPE_DOMAIN (to))
     return error_mark_node; // can't construct an array of unknown bound
   else
diff --git a/gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C b/gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C
new file mode 100644
index 00000000000..f6fbf8f2d9e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C
@@ -0,0 +1,17 @@
+// PR c++/102535
+// Verify __is_trivially_constructible works with multi-arg paren init of
+// aggrs.
+
+struct A { int x; };
+struct B { float y; };
+struct C { char z; };
+struct D { A a; B b; C c; };
+
+extern int n[1 + __is_trivially_constructible(D, A)];
+extern int n[1 + __is_trivially_constructible(D, A, B)];
+extern int n[1 + __is_trivially_constructible(D, A, B, C)];
+#if __cpp_aggregate_paren_init
+extern int n[1 + true];
+#else
+extern int n[1 + false];
+#endif
-- 
2.33.0.610.gcefe983a32


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

* Re: [PATCH 1/2] c++: order of trailing arguments in a trait expr
  2021-09-30 16:52 [PATCH 1/2] c++: order of trailing arguments in a trait expr Patrick Palka
  2021-09-30 16:52 ` [PATCH 2/2] c++: __is_trivially_xible and multi-arg aggr paren init [PR102535] Patrick Palka
@ 2021-09-30 20:13 ` Jason Merrill
  1 sibling, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2021-09-30 20:13 UTC (permalink / raw)
  To: Patrick Palka, gcc-patches

On 9/30/21 12:52, Patrick Palka wrote:
> When parsing a variadic trait expression, we build up the list of
> trailing arguments in reverse, but we're neglecting to reverse the list
> to its true order afterwards.  This causes us to confuse the meaning of
> e.g. __is_xible(x, y, z) and __is_xible(x, z, y).
> 
> Note that bug isn't exposed in the standard type traits within libstdc++
> because there we pass a pack expansion as the single trailing argument
> to __is_xible, which indeed gets expanded correctly by tsubst_tree_list.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?  What about backports?  This isn't a regression AFAICT.

OK for trunk.  I wouldn't bother backporting, since it doesn't affect 
the library traits.

> gcc/cp/ChangeLog:
> 
> 	* parser.c (cp_parser_trait_expr): Call nreverse on the list of
> 	trailing arguments.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/ext/is_constructible6.C: New test.
> ---
>   gcc/cp/parser.c                              |  1 +
>   gcc/testsuite/g++.dg/ext/is_constructible6.C | 10 ++++++++++
>   2 files changed, 11 insertions(+)
>   create mode 100644 gcc/testsuite/g++.dg/ext/is_constructible6.C
> 
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index 8430445ef8c..04f5a24cc03 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -10832,6 +10832,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
>   	    return error_mark_node;
>   	  type2 = tree_cons (NULL_TREE, elt, type2);
>   	}
> +      type2 = nreverse (type2);
>       }
>   
>     location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
> diff --git a/gcc/testsuite/g++.dg/ext/is_constructible6.C b/gcc/testsuite/g++.dg/ext/is_constructible6.C
> new file mode 100644
> index 00000000000..7fce153fa75
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ext/is_constructible6.C
> @@ -0,0 +1,10 @@
> +// Verify we respect the order of trailing arguments passed to
> +// __is_constructible.
> +
> +struct A { };
> +struct B { };
> +struct C { C(A, B); };
> +
> +extern int n[true];
> +extern int n[ __is_constructible(C, A, B)];
> +extern int n[!__is_constructible(C, B, A)];
> 


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

* Re: [PATCH 2/2] c++: __is_trivially_xible and multi-arg aggr paren init [PR102535]
  2021-09-30 16:52 ` [PATCH 2/2] c++: __is_trivially_xible and multi-arg aggr paren init [PR102535] Patrick Palka
@ 2021-09-30 20:15   ` Jason Merrill
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2021-09-30 20:15 UTC (permalink / raw)
  To: Patrick Palka, gcc-patches

On 9/30/21 12:52, Patrick Palka wrote:
> is_xible_helper assumes only 0- and 1-argument ctors can be trivial, but
> C++20 aggregate paren init means multi-arg ctors can now be trivial too.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk/11?

OK.

> 	PR c++/102535
> 
> gcc/cp/ChangeLog:
> 
> 	* method.c (is_xible_helper): Don't exit early for multi-arg
> 	ctors in C++20.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/ext/is_trivially_constructible7.C: New test.
> ---
>   gcc/cp/method.c                                 |  4 +++-
>   .../g++.dg/ext/is_trivially_constructible7.C    | 17 +++++++++++++++++
>   2 files changed, 20 insertions(+), 1 deletion(-)
>   create mode 100644 gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C
> 
> diff --git a/gcc/cp/method.c b/gcc/cp/method.c
> index 3c3495227ce..c38912a7ce9 100644
> --- a/gcc/cp/method.c
> +++ b/gcc/cp/method.c
> @@ -2094,8 +2094,10 @@ is_xible_helper (enum tree_code code, tree to, tree from, bool trivial)
>     tree expr;
>     if (code == MODIFY_EXPR)
>       expr = assignable_expr (to, from);
> -  else if (trivial && from && TREE_CHAIN (from))
> +  else if (trivial && from && TREE_CHAIN (from)
> +	   && cxx_dialect < cxx20)
>       return error_mark_node; // only 0- and 1-argument ctors can be trivial
> +			    // before C++20 aggregate paren init
>     else if (TREE_CODE (to) == ARRAY_TYPE && !TYPE_DOMAIN (to))
>       return error_mark_node; // can't construct an array of unknown bound
>     else
> diff --git a/gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C b/gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C
> new file mode 100644
> index 00000000000..f6fbf8f2d9e
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C
> @@ -0,0 +1,17 @@
> +// PR c++/102535
> +// Verify __is_trivially_constructible works with multi-arg paren init of
> +// aggrs.
> +
> +struct A { int x; };
> +struct B { float y; };
> +struct C { char z; };
> +struct D { A a; B b; C c; };
> +
> +extern int n[1 + __is_trivially_constructible(D, A)];
> +extern int n[1 + __is_trivially_constructible(D, A, B)];
> +extern int n[1 + __is_trivially_constructible(D, A, B, C)];
> +#if __cpp_aggregate_paren_init
> +extern int n[1 + true];
> +#else
> +extern int n[1 + false];
> +#endif
> 


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

end of thread, other threads:[~2021-09-30 20:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-30 16:52 [PATCH 1/2] c++: order of trailing arguments in a trait expr Patrick Palka
2021-09-30 16:52 ` [PATCH 2/2] c++: __is_trivially_xible and multi-arg aggr paren init [PR102535] Patrick Palka
2021-09-30 20:15   ` Jason Merrill
2021-09-30 20:13 ` [PATCH 1/2] c++: order of trailing arguments in a trait expr 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).