This is the mail archive of the gcc@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: aliasing problem with va_arg


I finally got a chance to take a better look at the problem, and I noticed
that your aliasing code allows type punning if it sees a direct union member
reference.  However, it does not allow type punning if we have a more
complicated tree.  This test case for instance gives incorrect code for irix6
and solaris2 because none of the references are recognized as union
accesses. They are array_refs of a union field, which the current code
doesn't handle.

double
sub (int i, int k, int j)
{
  union {
    int i[4];
    double d[2];
  } u;

  u.i[2] = i;
  u.i[3] = j;
  sub2 (u.d[1]);
}

If I fix this problem, then the va_arg problem goes away.  The stores
into the temp buffer are clean accesses to a union and now get alias set 0,
which means they can alias anything.  The reads from the temp buffer are
messy, but their alias set does not matter.  This will work provided that
either all stores or all reads to the temp buffer have alias set zero, and
this is true for the sparc va_arg macro.

Does this patch look OK to check in?

It is possible that there are other problems with the union type punning
check.  What happens if we put a pointer in a union, and then indirect
through it?  Will c_get_alias_set see a COMPONENT_REF or an INDIRECT_REF
of a COMPONENT_REF?  If it see an INDIRECT_REF only, then the MEM that
reads the pointer from the union may get the wrong alias set.  I am not
going to worry about such problems unless I see them though.

Wed Oct 28 15:29:56 1998  Jim Wilson  <wilson@cygnus.com>

	* c-common.c (c_get_alias_set): Handle ARRAY_REF of union field.

Index: c-common.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/c-common.c,v
retrieving revision 1.106
diff -p -r1.106 c-common.c
*** c-common.c	1998/10/09 23:02:26	1.106
--- c-common.c	1998/10/28 23:29:52
*************** c_get_alias_set (t)
*** 3016,3023 ****
         the conservative assumption.  */
      return 0;
  
!   if (TREE_CODE (t) == COMPONENT_REF
!       && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 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
--- 3016,3029 ----
         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.  */
!       || (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


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