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]
Other format: [Raw text]

[PATCH][RFC] Fix alias-set generation for array types


Currently array types get assigned an alias-set different from their
element type.  This creates various problems such as variable-sized
arrays of the same effective size getting two different alias-sets
and thus no conflicts.  While in C you never have lvalues of array type
this happens in Fortran and causes miscompilations if we start to
TBAA-prune points-to sets more aggressively.

The correct fix is to assign the same alias-set to the array type as
to their element type.

Now this breaks the Wstrict-aliasing check

  char c[6];
  return *(int *)c;

because now c is assigned alias-set zero and thus the simple
alias_sets_conflict_p check in c-common.c says yes.  Now it is
also undefined to do

  char c;
  return *(int *)c;

which would have gotten no alias warning as well.

The warning is easily fixed by treating the alias-set zero cases
explicit - a target alias-set zero is ok while a source alias-set
zero is not, unless the target is also alias-set zero.

Unfortunately this breaks bootstrap, as dfp.c is full of alias violations
like

*((uint32_t *) d32.bytes) = (uint32_t) buf[0];

which we didn't warn for previously.  Fixed by adding -Wno-error for
dfp.o.


Boostrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?

Thanks,
Richard.

2008-06-03  Richard Guenther  <rguenther@suse.de>

	* alias.c (get_alias_set): Use the element alias-set for arrays.
	(record_component_aliases): For arrays and vectors do nothing.
	* c-common.c (strict_aliasing_warning): Handle the cases
	of alias set zero explicitly.
	* Makefile.in (dfp.o-warn): Add -Wno-error.

Index: trunk/gcc/alias.c
===================================================================
*** trunk.orig/gcc/alias.c	2008-05-30 12:02:24.000000000 +0200
--- trunk/gcc/alias.c	2008-06-02 13:19:20.000000000 +0200
*************** get_alias_set (tree t)
*** 640,645 ****
--- 640,656 ----
    else if (TREE_CODE (t) == VECTOR_TYPE)
      set = get_alias_set (TREE_TYPE (t));
  
+   /* Unless the language specifies otherwise, treat array types the
+      same as their components.  This avoids the asymmetry we get
+      through recording the components.  Consider accessing a
+      character(kind=1) through a reference to a character(kind=1)[1:1].
+      Or consider if we want to assign integer(kind=4)[0:D.1387] and
+      integer(kind=4)[4] the same alias set or not.
+      Just be pragmatic here and make sure the array and its element
+      type get the same alias set assigned.  */
+   else if (TREE_CODE (t) == ARRAY_TYPE)
+     set = get_alias_set (TREE_TYPE (t));
+ 
    else
      /* Otherwise make a new alias set for this type.  */
      set = new_alias_set ();
*************** record_component_aliases (tree type)
*** 747,757 ****
  
    switch (TREE_CODE (type))
      {
-     case ARRAY_TYPE:
-       if (!TYPE_NONALIASED_COMPONENT (type))
- 	record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
-       break;
- 
      case RECORD_TYPE:
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
--- 758,763 ----
*************** record_component_aliases (tree type)
*** 775,780 ****
--- 781,789 ----
        record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
        break;
  
+     /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
+        element type.  */
+ 
      default:
        break;
      }
Index: trunk/gcc/c-common.c
===================================================================
*** trunk.orig/gcc/c-common.c	2008-06-02 17:22:45.000000000 +0200
--- trunk/gcc/c-common.c	2008-06-02 17:47:19.000000000 +0200
*************** strict_aliasing_warning (tree otype, tre
*** 1093,1099 ****
  	    get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
            alias_set_type set2 = get_alias_set (TREE_TYPE (type));
  
!           if (!alias_sets_conflict_p (set1, set2))
  	    {
  	      warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
  		       "pointer will break strict-aliasing rules");
--- 1093,1100 ----
  	    get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
            alias_set_type set2 = get_alias_set (TREE_TYPE (type));
  
!           if (set1 != set2 && set2 != 0
! 	      && (set1 == 0 || !alias_sets_conflict_p (set1, set2)))
  	    {
  	      warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
  		       "pointer will break strict-aliasing rules");
Index: trunk/gcc/Makefile.in
===================================================================
*** trunk.orig/gcc/Makefile.in	2008-05-30 12:04:03.000000000 +0200
--- trunk/gcc/Makefile.in	2008-06-03 11:11:49.000000000 +0200
*************** GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-
*** 187,192 ****
--- 187,194 ----
  build/gengtype-lex.o-warn = -Wno-error
  # SYSCALLS.c misses prototypes
  SYSCALLS.c.X-warn = -Wno-strict-prototypes -Wno-error
+ # dfp.c contains alias violations
+ dfp.o-warn = -Wno-error
  
  # All warnings have to be shut off in stage1 if the compiler used then
  # isn't gcc; configure determines that.  WARN_CFLAGS will be either


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