This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][RFC] Fix alias-set generation for array types
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Diego Novillo <dnovillo at google dot com>
- Date: Tue, 3 Jun 2008 13:22:07 +0200 (CEST)
- Subject: [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