C++ PATCH for c++/91877 - ICE with converting member of packed struct.

Message ID 20190924151732.GD14737@redhat.com
State New
Headers show
Series
  • C++ PATCH for c++/91877 - ICE with converting member of packed struct.
Related show

Commit Message

Marek Polacek Sept. 24, 2019, 3:17 p.m.
This started to ICE with my CWG 2352 fix.  In reference_binding, we now bind
directly when the types are similar, not just when they are the same.  But even
direct binding can involve a temporary, e.g. for a bit-field, or, as in this
test, for a packed field.

convert_like will actually create the temporary, but we were triggering the
assert checking that the types are the same.  Now they don't have to be, so
adjust the assert accordingly.

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

2019-09-24  Marek Polacek  <polacek@redhat.com>

	PR c++/91877 - ICE with converting member of packed struct.
	* call.c (convert_like_real): Use similar_type_p in an assert.

	* g++.dg/conversion/packed1.C: New test.

Comments

Jason Merrill Sept. 25, 2019, 4:28 a.m. | #1
On 9/24/19 11:17 AM, Marek Polacek wrote:
> This started to ICE with my CWG 2352 fix.  In reference_binding, we now bind

> directly when the types are similar, not just when they are the same.  But even

> direct binding can involve a temporary, e.g. for a bit-field, or, as in this

> test, for a packed field.


Well, if there's a temporary, it isn't direct binding.

> convert_like will actually create the temporary, but we were triggering the

> assert checking that the types are the same.  Now they don't have to be, so

> adjust the assert accordingly.


Previously we could have gotten a derived class, but we would have a 
ck_base to make the assert succeed.  Do we want a ck_qual under the 
ck_ref_bind?  It isn't necessary for adjustment, but might be helpful 
for conversion sequence ranking (which seems to be missing some standard 
wording).  On the other hand, it might be too much trouble making things 
understand ck_ref_bind around ck_qual, and compare_ics can probably do 
just fine without.

The patch is OK, but please add some testcases for overload resolution 
with more and less-qualified similar types.

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

> 

> 2019-09-24  Marek Polacek  <polacek@redhat.com>

> 

> 	PR c++/91877 - ICE with converting member of packed struct.

> 	* call.c (convert_like_real): Use similar_type_p in an assert.

> 

> 	* g++.dg/conversion/packed1.C: New test.

> 

> diff --git gcc/cp/call.c gcc/cp/call.c

> index 77f10a9f5f1..45b984ecb11 100644

> --- gcc/cp/call.c

> +++ gcc/cp/call.c

> @@ -7382,8 +7382,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,

>   	    tree type = TREE_TYPE (ref_type);

>   	    cp_lvalue_kind lvalue = lvalue_kind (expr);

>   

> -	    gcc_assert (same_type_ignoring_top_level_qualifiers_p

> -			(type, next_conversion (convs)->type));

> +	    gcc_assert (similar_type_p (type, next_conversion (convs)->type));

>   	    if (!CP_TYPE_CONST_NON_VOLATILE_P (type)

>   		&& !TYPE_REF_IS_RVALUE (ref_type))

>   	      {

> diff --git gcc/testsuite/g++.dg/conversion/packed1.C gcc/testsuite/g++.dg/conversion/packed1.C

> new file mode 100644

> index 00000000000..c4be930bc19

> --- /dev/null

> +++ gcc/testsuite/g++.dg/conversion/packed1.C

> @@ -0,0 +1,12 @@

> +// PR c++/91877 - ICE with converting member of packed struct.

> +// { dg-do compile { target c++11 } }

> +// { dg-options "-fpack-struct" }

> +

> +template <typename a> class b {

> +public:

> +  b(const a &);

> +};

> +struct {

> +  int *c;

> +} d;

> +void e() { b<const int *>(d.c); }

>

Patch

diff --git gcc/cp/call.c gcc/cp/call.c
index 77f10a9f5f1..45b984ecb11 100644
--- gcc/cp/call.c
+++ gcc/cp/call.c
@@ -7382,8 +7382,7 @@  convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 	    tree type = TREE_TYPE (ref_type);
 	    cp_lvalue_kind lvalue = lvalue_kind (expr);
 
-	    gcc_assert (same_type_ignoring_top_level_qualifiers_p
-			(type, next_conversion (convs)->type));
+	    gcc_assert (similar_type_p (type, next_conversion (convs)->type));
 	    if (!CP_TYPE_CONST_NON_VOLATILE_P (type)
 		&& !TYPE_REF_IS_RVALUE (ref_type))
 	      {
diff --git gcc/testsuite/g++.dg/conversion/packed1.C gcc/testsuite/g++.dg/conversion/packed1.C
new file mode 100644
index 00000000000..c4be930bc19
--- /dev/null
+++ gcc/testsuite/g++.dg/conversion/packed1.C
@@ -0,0 +1,12 @@ 
+// PR c++/91877 - ICE with converting member of packed struct.
+// { dg-do compile { target c++11 } }
+// { dg-options "-fpack-struct" }
+
+template <typename a> class b {
+public:
+  b(const a &);
+};
+struct {
+  int *c;
+} d;
+void e() { b<const int *>(d.c); }