This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: alias sets problem
- To: law at cygnus dot com
- Subject: Re: alias sets problem
- From: Mark Mitchell <mark at markmitchell dot com>
- Date: Sat, 31 Oct 1998 19:02:21 -0800
- CC: egcs-patches at cygnus dot com
- References: <11516.909861978@hurl.cygnus.com>
- Reply-to: mark at markmitchell dot com
>>>>> "Jeffrey" == Jeffrey A Law <law@cygnus.com> writes:
Jeffrey> Several folks have been reporting problems bootstrapping
Jeffrey> with -O3 or higher optimization levels on the x86.
Here's the fix. The deal is that build_modify_expr calls
get_unwidened for the lhs of an assignment which turns, say:
enum E {
a
};
struct S
{
enum E e : 16;
};
struct S* s1;
void f()
{
s1->e = a;
}
into an assignment into an `unsigned short' which is different than
the original `enum E' type. That's no good.
This patch notices this case in c_get_alias_set. It also allows
unrestricted type-punning through unions, per discussions with Jim Wilson
over the last few days. So
s.u.t.a[3]
where `u' has union type should yield alias set zero now. OK?
--
Mark Mitchell mark@markmitchell.com
Mark Mitchell Consulting http://www.markmitchell.com
Sat Oct 31 18:48:40 1998 Mark Mitchell <mark@markmitchell.com>
* c-common.c (c_get_alias_set): Allow all type-punning through
unions. Don't get confused about the type of a bit-field, despite
the antics of build_modify_expr.
Index: c-common.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-common.c,v
retrieving revision 1.41
diff -c -p -r1.41 c-common.c
*** c-common.c 1998/10/29 12:40:21 1.41
--- c-common.c 1998/11/01 02:55:54
*************** c_get_alias_set (t)
*** 3135,3140 ****
--- 3135,3141 ----
tree t;
{
tree type;
+ tree u;
if (t == error_mark_node)
return 0;
*************** c_get_alias_set (t)
*** 3155,3176 ****
the conservative assumption. */
return 0;
! if ((TREE_CODE (t) == COMPONENT_REF
! && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
! /* Also permit punning when accessing an array which is a union
! member. This makes the current sparc va_arg macro work, but may
! not be otherwise necessary. */
! || (TREE_CODE (t) == ARRAY_REF
! && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF
! && (TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
! == UNION_TYPE)))
! /* Permit type-punning when accessing a union, provided the
! access is directly through the union. For example, this code does
! not permit taking the address of a union member and then
! storing through it. Even the type-punning allowed here is a
! GCC extension, albeit a common and useful one; the C standard
! says that such accesses have implementation-defined behavior. */
! return 0;
if (TREE_CODE (t) == INDIRECT_REF)
{
--- 3156,3173 ----
the conservative assumption. */
return 0;
! /* Permit type-punning when accessing a union, provided the access
! is directly through the union. For example, this code does not
! permit taking the address of a union member and then storing
! through it. Even the type-punning allowed here is a GCC
! extension, albeit a common and useful one; the C standard says
! that such accesses have implementation-defined behavior. */
! for (u = t;
! TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
! u = TREE_OPERAND (u, 0))
! if (TREE_CODE (u) == COMPONENT_REF
! && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
! return 0;
if (TREE_CODE (t) == INDIRECT_REF)
{
*************** c_get_alias_set (t)
*** 3183,3188 ****
--- 3180,3194 ----
}
/* From here on, only the type matters. */
+
+ if (TREE_CODE (t) == COMPONENT_REF
+ && DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)))
+ /* Since build_modify_expr calls get_unwidened for stores to
+ component references, the type of a bit field can be changed
+ from (say) `unsigned int : 16' to `unsigned short' or from
+ `enum E : 16' to `short'. We want the real type of the
+ bit-field in this case, not some the integral equivalent. */
+ type = DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1));
if (TYPE_ALIAS_SET_KNOWN_P (type))
/* If we've already calculated the value, just return it. */