Re: [C++/66270] another may_alias crash
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 2015-05-25 Nathan Sidwell nat...@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);
Re: [C++/66270] another may_alias crash
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
Re: [C++/66270] another may_alias crash
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
Re: [C++/66270] another may_alias crash
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
[C++/66270] another may_alias crash
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 2015-05-25 Nathan Sidwell nat...@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]; +}
Re: [C++/66270] another may_alias crash
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