This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: alias sets problem


>>>>> "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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]