public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++/66270]  another may_alias crash
@ 2015-05-25 21:09 Nathan Sidwell
  2015-05-26  7:52 ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Nathan Sidwell @ 2015-05-25 21:09 UTC (permalink / raw)
  To: Jason Merrill, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1798 bytes --]

This patch addresses 66270, another case where may_alias disrupted the canonical 
type system.  We ICE as TYPE_CANONICALs differ, but comptypes think they are the 
same.

There seems to be a bit of confusion as to whether pointers that differ only in 
TYPE_REF_CAN_ALIAS_ALL are the same canonical type or not.

Firstly, in tree.c build_pointer_type_for_mode, when the pointed-to type is not 
its own canonical type, that means the newly constructed pointer type is 
(possibly) not canonical either.  So we explicitly build a canonical type with:

   else if (TYPE_CANONICAL (to_type) != to_type)
     TYPE_CANONICAL (t)
       = build_reference_type_for_mode (TYPE_CANONICAL (to_type),
				       mode, false);

But we're passing 'false' in as 'can_alias_all', rather than pass the value 
passed into us.  That'll make a difference if the caller passed in true and 
to_type doesn't have may_alias set.  This is inconsistent at least, because we 
could sometimes end up with canonical types with T_R_C_A_A set (to-type is 
canonical) and sometimes with it not set.  It seems the right solution is to 
consider T_R_C_A_A as a distinguisher, thus we should pass can_alias_all to the 
canonical type builder.  Note that it is ok to pass the possibly modified 
can_alias_all in, and not the incoming value, because we only ever modify it to 
make it true -- and in that case the same behavior would happen in the canonical 
type builder because to_type and TYPE_CANONICAL (to_type) should have the same 
may_alias attribute.

Anyway, that's a bit of collateral confusion I fell over investigating.  With 
that out of the way, we have  to teach comptypes that T_R_C_A_A affects pointer 
type equality.  Hence add such a check to POINTER_TYPE case there.

bootstrapped on x86-linux & tested, ok?

nathan

[-- Attachment #2: 66270.patch --]
[-- Type: text/x-patch, Size: 2077 bytes --]

2015-05-25  Nathan Sidwell  <nathan@acm.org>


	PR c++/66270
	* tree.c (build_pointer_type_for_mode): Pass can_alias_all to
	canonical type builder.
	(build_reference_type_for_mode): Likewise.

	cp/
	* typeck.c (structural_comptypes) [POINTER_TYPE]: Compare
	TYPE_REF_CAN_ALIAS_ALL.

	testsuite/
	* g++.dg/ext/alias-canon3.C: New.

Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 223636)
+++ cp/typeck.c	(working copy)
@@ -1307,6 +1307,8 @@ structural_comptypes (tree t1, tree t2,
       if (TYPE_MODE (t1) != TYPE_MODE (t2)
 	  || !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
 	return false;
+      if (TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
+	return false;
       break;
 
     case METHOD_TYPE:
Index: tree.c
===================================================================
--- tree.c	(revision 223636)
+++ tree.c	(working copy)
@@ -7759,7 +7759,7 @@ build_pointer_type_for_mode (tree to_typ
   else if (TYPE_CANONICAL (to_type) != to_type)
     TYPE_CANONICAL (t)
       = build_pointer_type_for_mode (TYPE_CANONICAL (to_type),
-				     mode, false);
+				     mode, can_alias_all);
 
   /* Lay out the type.  This function has many callers that are concerned
      with expression-construction, and this simplifies them all.  */
@@ -7826,7 +7826,7 @@ build_reference_type_for_mode (tree to_t
   else if (TYPE_CANONICAL (to_type) != to_type)
     TYPE_CANONICAL (t)
       = build_reference_type_for_mode (TYPE_CANONICAL (to_type),
-				       mode, false);
+				       mode, can_alias_all);
 
   layout_type (t);
 
Index: testsuite/g++.dg/ext/alias-canon3.C
===================================================================
--- testsuite/g++.dg/ext/alias-canon3.C	(revision 0)
+++ testsuite/g++.dg/ext/alias-canon3.C	(working copy)
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// PR c++/66270
+
+typedef float __m256 __attribute__ (( __vector_size__(32), __may_alias__ ));
+struct A {
+  __m256 ymm;
+  const float &f() const;
+};
+
+const float &A::f() const {
+  return ymm[1];
+}

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

* Re: [C++/66270]  another may_alias crash
  2015-05-25 21:09 [C++/66270] another may_alias crash Nathan Sidwell
@ 2015-05-26  7:52 ` Jason Merrill
  2015-05-26 19:18   ` Nathan Sidwell
  0 siblings, 1 reply; 6+ messages in thread
From: Jason Merrill @ 2015-05-26  7:52 UTC (permalink / raw)
  To: Nathan Sidwell, GCC Patches

On 05/25/2015 04:55 PM, Nathan Sidwell wrote:
> This patch addresses 66270, another case where may_alias disrupted the
> canonical type system.  We ICE as TYPE_CANONICALs differ, but comptypes
> think they are the same.
>
> There seems to be a bit of confusion as to whether pointers that differ
> only in TYPE_REF_CAN_ALIAS_ALL are the same canonical type or not.
>
> Firstly, in tree.c build_pointer_type_for_mode, when the pointed-to type
> is not its own canonical type, that means the newly constructed pointer
> type is (possibly) not canonical either.  So we explicitly build a
> canonical type with:
>
>    else if (TYPE_CANONICAL (to_type) != to_type)
>      TYPE_CANONICAL (t)
>        = build_reference_type_for_mode (TYPE_CANONICAL (to_type),
>                         mode, false);
>
> But we're passing 'false' in as 'can_alias_all', rather than pass the
> value passed into us.

Yes, I actually just changed that a month ago because we were hitting 
this same ICE from a different direction (bug 50800).  Since 
TYPE_CANONICAL (to_type) doesn't have the may_alias attribute, the 
canonical pointer shouldn't have TRCAA.

> That'll make a difference if the caller passed in
> true and to_type doesn't have may_alias set.   This is inconsistent at
> least, because we could sometimes end up with canonical types with
> T_R_C_A_A set (to-type is canonical) and sometimes with it not set.  It
> seems the right solution is to consider T_R_C_A_A as a distinguisher,
> thus we should pass can_alias_all to the canonical type builder.  Note
> that it is ok to pass the possibly modified can_alias_all in, and not
> the incoming value, because we only ever modify it to make it true --
> and in that case the same behavior would happen in the canonical type
> builder because to_type and TYPE_CANONICAL (to_type) should have the
> same may_alias attribute.

Hmm, are you seeing a case where TYPE_CANONICAL (to_type) has the 
may_alias attribute?

> Anyway, that's a bit of collateral confusion I fell over investigating.
> With that out of the way, we have  to teach comptypes that T_R_C_A_A
> affects pointer type equality.  Hence add such a check to POINTER_TYPE
> case there.

Similarly, I removed this check for bug 50800.

Jason

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

* Re: [C++/66270]  another may_alias crash
  2015-05-26  7:52 ` Jason Merrill
@ 2015-05-26 19:18   ` Nathan Sidwell
  2015-05-27 12:42     ` Nathan Sidwell
  2015-05-27 16:36     ` Jason Merrill
  0 siblings, 2 replies; 6+ messages in thread
From: Nathan Sidwell @ 2015-05-26 19:18 UTC (permalink / raw)
  To: Jason Merrill, GCC Patches

On 05/25/15 21:18, Jason Merrill wrote:
> On 05/25/2015 04:55 PM, Nathan Sidwell wrote:

>>    else if (TYPE_CANONICAL (to_type) != to_type)
>>      TYPE_CANONICAL (t)
>>        = build_reference_type_for_mode (TYPE_CANONICAL (to_type),
>>                         mode, false);
>>
>> But we're passing 'false' in as 'can_alias_all', rather than pass the
>> value passed into us.
>
> Yes, I actually just changed that a month ago because we were hitting this same
> ICE from a different direction (bug 50800).  Since TYPE_CANONICAL (to_type)
> doesn't have the may_alias attribute, the canonical pointer shouldn't have TRCAA.

Ok, so IIUC a canonical pointer to a may_alias type should have TRCAA but a 
canonical can_alias_all pointer to a non-may_alias type should not have TRCAA? 
(i.e. one where CAN_ALIAS_ALL was passed true). Or are you saying that no 
canonical pointers should have TRCAA?

> Hmm, are you seeing a case where TYPE_CANONICAL (to_type) has the may_alias
> attribute?

Yes.  This occurs when the newly created TRCAA pointer is to a self-canonical 
type.  The
  else if (TYPE_CANONICAL (to_type) != to_type)
is false, so the newly created pointer is self-canonical too (and has TRCAA).

If the canonical type should not have TRCAA we need to change the if condition to:
   else if (TYPE_CANONICAL (to_type) != to_type || could_alias_all)

where COULD_ALIAS_ALL is the incoming CAN_ALIAS_ALL value.  Does that make sense?

Making that change does stop  the ICE I was seeing, but I've not done a full 
test yet.

nathan

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

* Re: [C++/66270]  another may_alias crash
  2015-05-26 19:18   ` Nathan Sidwell
@ 2015-05-27 12:42     ` Nathan Sidwell
  2015-05-27 16:36     ` Jason Merrill
  1 sibling, 0 replies; 6+ messages in thread
From: Nathan Sidwell @ 2015-05-27 12:42 UTC (permalink / raw)
  To: Jason Merrill, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 987 bytes --]

On 05/26/15 15:00, Nathan Sidwell wrote:
> On 05/25/15 21:18, Jason Merrill wrote:

>> Hmm, are you seeing a case where TYPE_CANONICAL (to_type) has the may_alias
>> attribute?
>
> Yes.  This occurs when the newly created TRCAA pointer is to a self-canonical
> type.  The
>   else if (TYPE_CANONICAL (to_type) != to_type)
> is false, so the newly created pointer is self-canonical too (and has TRCAA).
>
> If the canonical type should not have TRCAA we need to change the if condition to:
>    else if (TYPE_CANONICAL (to_type) != to_type || could_alias_all)
>
> where COULD_ALIAS_ALL is the incoming CAN_ALIAS_ALL value.  Does that make sense?
>
> Making that change does stop  the ICE I was seeing, but I've not done a full
> test yet.

Here's a patch implementing that change,  When build_pointer_type_for_mode is 
passed true for CAN_ALIAS_ALL, we force creating a canonical type, continuing to 
pass false for that pointer's creation.

booted & tested on x86-64-linux, ok?

nathan


[-- Attachment #2: 66270-2.patch --]
[-- Type: text/x-patch, Size: 2018 bytes --]

2015-05-25  Nathan Sidwell  <nathan@acm.org>

	PR c++/66270
	* tree.c (build_pointer_type_for_mode): Canonical type does not
	inherit can_alias_all.
	(build_reference_type_for_mode): Likewise.

	PR c++/66270
	* g++.dg/ext/alias-canon3.C: New.

Index: testsuite/g++.dg/ext/alias-canon3.C
===================================================================
--- testsuite/g++.dg/ext/alias-canon3.C	(revision 0)
+++ testsuite/g++.dg/ext/alias-canon3.C	(working copy)
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// PR c++/66270
+
+typedef float __m256 __attribute__ (( __vector_size__(32), __may_alias__ ));
+struct A {
+  __m256 ymm;
+  const float &f() const;
+};
+
+const float &A::f() const {
+  return ymm[1];
+}
Index: tree.c
===================================================================
--- tree.c	(revision 223636)
+++ tree.c	(working copy)
@@ -7719,6 +7719,7 @@ build_pointer_type_for_mode (tree to_typ
 			     bool can_alias_all)
 {
   tree t;
+  bool could_alias = can_alias_all;
 
   if (to_type == error_mark_node)
     return error_mark_node;
@@ -7756,7 +7757,7 @@ build_pointer_type_for_mode (tree to_typ
 
   if (TYPE_STRUCTURAL_EQUALITY_P (to_type))
     SET_TYPE_STRUCTURAL_EQUALITY (t);
-  else if (TYPE_CANONICAL (to_type) != to_type)
+  else if (TYPE_CANONICAL (to_type) != to_type || could_alias)
     TYPE_CANONICAL (t)
       = build_pointer_type_for_mode (TYPE_CANONICAL (to_type),
 				     mode, false);
@@ -7786,6 +7787,7 @@ build_reference_type_for_mode (tree to_t
 			       bool can_alias_all)
 {
   tree t;
+  bool could_alias = can_alias_all;
 
   if (to_type == error_mark_node)
     return error_mark_node;
@@ -7823,7 +7825,7 @@ build_reference_type_for_mode (tree to_t
 
   if (TYPE_STRUCTURAL_EQUALITY_P (to_type))
     SET_TYPE_STRUCTURAL_EQUALITY (t);
-  else if (TYPE_CANONICAL (to_type) != to_type)
+  else if (TYPE_CANONICAL (to_type) != to_type || could_alias)
     TYPE_CANONICAL (t)
       = build_reference_type_for_mode (TYPE_CANONICAL (to_type),
 				       mode, false);

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

* Re: [C++/66270]  another may_alias crash
  2015-05-26 19:18   ` Nathan Sidwell
  2015-05-27 12:42     ` Nathan Sidwell
@ 2015-05-27 16:36     ` Jason Merrill
  2015-05-27 21:26       ` Nathan Sidwell
  1 sibling, 1 reply; 6+ messages in thread
From: Jason Merrill @ 2015-05-27 16:36 UTC (permalink / raw)
  To: Nathan Sidwell, GCC Patches

On 05/26/2015 03:00 PM, Nathan Sidwell wrote:
> Ok, so IIUC a canonical pointer to a may_alias type should have TRCAA
> but a canonical can_alias_all pointer to a non-may_alias type should not
> have TRCAA? (i.e. one where CAN_ALIAS_ALL was passed true). Or are you
> saying that no canonical pointers should have TRCAA?

The former: A canonical pointer should have TRCAA if and only if the 
canonical referent is may_alias.

>> Hmm, are you seeing a case where TYPE_CANONICAL (to_type) has the
>> may_alias attribute?
>
> Yes.  This occurs when the newly created TRCAA pointer is to a
> self-canonical type.

Hmm, seems like that's another problem with your testcase: the canonical 
variant of __m256 should not have may_alias.  But the canonical variant 
of a class or enum type could still have may_alias, so we still need to 
handle that case.

The patch is OK.

Jason

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

* Re: [C++/66270]  another may_alias crash
  2015-05-27 16:36     ` Jason Merrill
@ 2015-05-27 21:26       ` Nathan Sidwell
  0 siblings, 0 replies; 6+ messages in thread
From: Nathan Sidwell @ 2015-05-27 21:26 UTC (permalink / raw)
  To: Jason Merrill, GCC Patches

On 05/27/15 12:20, Jason Merrill wrote:
> On 05/26/2015 03:00 PM, Nathan Sidwell wrote:
>> Ok, so IIUC a canonical pointer to a may_alias type should have TRCAA
>> but a canonical can_alias_all pointer to a non-may_alias type should not
>> have TRCAA? (i.e. one where CAN_ALIAS_ALL was passed true). Or are you
>> saying that no canonical pointers should have TRCAA?
>
> The former: A canonical pointer should have TRCAA if and only if the canonical
> referent is may_alias.
>
>>> Hmm, are you seeing a case where TYPE_CANONICAL (to_type) has the
>>> may_alias attribute?
>>
>> Yes.  This occurs when the newly created TRCAA pointer is to a
>> self-canonical type.
>
> Hmm, seems like that's another problem with your testcase: the canonical variant
> of __m256 should not have may_alias.  But the canonical variant of a class or
> enum type could still have may_alias, so we still need to handle that case.

I was unclear in my description.  The canonical pointer type was being created 
with TRCAA set because of the incoming true CAN_ALIAS_ALL parameter.  That's 
fixed by the patch, so we're all good now.

nathan

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

end of thread, other threads:[~2015-05-27 21:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-25 21:09 [C++/66270] another may_alias crash Nathan Sidwell
2015-05-26  7:52 ` Jason Merrill
2015-05-26 19:18   ` Nathan Sidwell
2015-05-27 12:42     ` Nathan Sidwell
2015-05-27 16:36     ` Jason Merrill
2015-05-27 21:26       ` Nathan Sidwell

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).