public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: ICE with constexpr dtor on ARM [PR105529]
@ 2022-05-09 22:41 Marek Polacek
  2022-05-10  4:13 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Marek Polacek @ 2022-05-09 22:41 UTC (permalink / raw)
  To: Jason Merrill, GCC Patches

When compiling this test on ARM with -O, we ICE in cxx_eval_store_expression
while evaluating a CALL_EXPR allocator::~allocator (&D.4529).  Its body
has this store:

  <retval> = this

The RHS is evaluated into &D.4529 of type allocator *.  The object,
<retval>, is of type void *.  Their types don't match so we go into
the new

  if (empty_base || !(same_type_ignoring_top_level_qualifiers_p
                      (TREE_TYPE (init), type)))
    {
      empty_base = true;
      gcc_assert (is_empty_class (TREE_TYPE (init)));

branch where we crash because is_empty_class will always say false for
a pointer type.  It seems like the new branch expects code like

  D.2181 = {}

where the type of the LHS is the derived type and the type of the RHS is
the base type.  But it only expects to see actual class types, not
pointers to them.  With this patch we will do what we did before the
empty bases cleanup patch: set *valp and return the initializer.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

	PR c++/105529

gcc/cp/ChangeLog:

	* constexpr.cc (cxx_eval_store_expression): Check CLASS_TYPE_P before
	checking initialization of an empty base.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/constexpr-dtor13.C: New test.
	* g++.dg/cpp2a/constexpr-dtor14.C: New test.
---
 gcc/cp/constexpr.cc                           |  5 +++--
 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C | 11 +++++++++++
 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C | 13 +++++++++++++
 3 files changed, 27 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index e560d842e8c..e4498c15f1e 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -5916,8 +5916,9 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
 
   gcc_checking_assert (!*valp || (same_type_ignoring_top_level_qualifiers_p
 				  (TREE_TYPE (*valp), type)));
-  if (empty_base || !(same_type_ignoring_top_level_qualifiers_p
-		      (TREE_TYPE (init), type)))
+  if (empty_base || (CLASS_TYPE_P (TREE_TYPE (init))
+		     && !(same_type_ignoring_top_level_qualifiers_p
+			  (TREE_TYPE (init), type))))
     {
       /* For initialization of an empty base, the original target will be
        *(base*)this, evaluation of which resolves to the object
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C
new file mode 100644
index 00000000000..7b289614fc1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C
@@ -0,0 +1,11 @@
+// PR c++/105529
+// { dg-do compile { target c++20 } }
+// { dg-options "-O" }
+
+struct allocator {
+  constexpr ~allocator() {}
+};
+struct S {
+  S(int, int, allocator = allocator());
+};
+void to_string() { S(0, '\0'); }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C
new file mode 100644
index 00000000000..9c55121eb8a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C
@@ -0,0 +1,13 @@
+// PR c++/105529
+// { dg-do compile { target c++20 } }
+// { dg-options "-O" }
+// Like constexpr-dtor13.C, except that allocator is not an empty class.
+
+struct allocator {
+  constexpr ~allocator() {}
+  int a;
+};
+struct S {
+  S(int, int, allocator = allocator());
+};
+void to_string() { S(0, '\0'); }

base-commit: 8a39c7c128dbf4405821778724c5a1017ab12e06
-- 
2.35.3


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

* Re: [PATCH] c++: ICE with constexpr dtor on ARM [PR105529]
  2022-05-09 22:41 [PATCH] c++: ICE with constexpr dtor on ARM [PR105529] Marek Polacek
@ 2022-05-10  4:13 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2022-05-10  4:13 UTC (permalink / raw)
  To: Marek Polacek, GCC Patches

On 5/9/22 18:41, Marek Polacek wrote:
> When compiling this test on ARM with -O, we ICE in cxx_eval_store_expression
> while evaluating a CALL_EXPR allocator::~allocator (&D.4529).  Its body
> has this store:
> 
>    <retval> = this
> 
> The RHS is evaluated into &D.4529 of type allocator *.  The object,
> <retval>, is of type void *.  Their types don't match

That seems like the bug, which I have a patch for.

> so we go into the new
> 
>    if (empty_base || !(same_type_ignoring_top_level_qualifiers_p
>                        (TREE_TYPE (init), type)))
>      {
>        empty_base = true;
>        gcc_assert (is_empty_class (TREE_TYPE (init)));
> 
> branch where we crash because is_empty_class will always say false for
> a pointer type.  It seems like the new branch expects code like
> 
>    D.2181 = {}
> 
> where the type of the LHS is the derived type and the type of the RHS is
> the base type.  But it only expects to see actual class types, not
> pointers to them.  With this patch we will do what we did before the
> empty bases cleanup patch: set *valp and return the initializer.

It seems reasonable to expect that the initializer has the same type as 
the target; otherwise other things are likely to get confused.

I'll incorporate your testcases in my patch, thanks.

> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> 
> 	PR c++/105529
> 
> gcc/cp/ChangeLog:
> 
> 	* constexpr.cc (cxx_eval_store_expression): Check CLASS_TYPE_P before
> 	checking initialization of an empty base.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/cpp2a/constexpr-dtor13.C: New test.
> 	* g++.dg/cpp2a/constexpr-dtor14.C: New test.
> ---
>   gcc/cp/constexpr.cc                           |  5 +++--
>   gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C | 11 +++++++++++
>   gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C | 13 +++++++++++++
>   3 files changed, 27 insertions(+), 2 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C
> 
> diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
> index e560d842e8c..e4498c15f1e 100644
> --- a/gcc/cp/constexpr.cc
> +++ b/gcc/cp/constexpr.cc
> @@ -5916,8 +5916,9 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
>   
>     gcc_checking_assert (!*valp || (same_type_ignoring_top_level_qualifiers_p
>   				  (TREE_TYPE (*valp), type)));
> -  if (empty_base || !(same_type_ignoring_top_level_qualifiers_p
> -		      (TREE_TYPE (init), type)))
> +  if (empty_base || (CLASS_TYPE_P (TREE_TYPE (init))
> +		     && !(same_type_ignoring_top_level_qualifiers_p
> +			  (TREE_TYPE (init), type))))
>       {
>         /* For initialization of an empty base, the original target will be
>          *(base*)this, evaluation of which resolves to the object
> diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C
> new file mode 100644
> index 00000000000..7b289614fc1
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor13.C
> @@ -0,0 +1,11 @@
> +// PR c++/105529
> +// { dg-do compile { target c++20 } }
> +// { dg-options "-O" }
> +
> +struct allocator {
> +  constexpr ~allocator() {}
> +};
> +struct S {
> +  S(int, int, allocator = allocator());
> +};
> +void to_string() { S(0, '\0'); }
> diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C
> new file mode 100644
> index 00000000000..9c55121eb8a
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor14.C
> @@ -0,0 +1,13 @@
> +// PR c++/105529
> +// { dg-do compile { target c++20 } }
> +// { dg-options "-O" }
> +// Like constexpr-dtor13.C, except that allocator is not an empty class.
> +
> +struct allocator {
> +  constexpr ~allocator() {}
> +  int a;
> +};
> +struct S {
> +  S(int, int, allocator = allocator());
> +};
> +void to_string() { S(0, '\0'); }
> 
> base-commit: 8a39c7c128dbf4405821778724c5a1017ab12e06


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

end of thread, other threads:[~2022-05-10  4:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-09 22:41 [PATCH] c++: ICE with constexpr dtor on ARM [PR105529] Marek Polacek
2022-05-10  4:13 ` 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).