This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][RFC] Fix PR36369, clarify may_alias attribute documentation
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 11 Jun 2008 19:35:32 +0200 (CEST)
- Subject: [PATCH][RFC] Fix PR36369, clarify may_alias attribute documentation
This fixes PR36369 where we warn about strict-aliasing violations
despite a may_alias pointer is used. This is because the may_alias
attribute is not properly handled - the fix is to set
TYPE_REF_CAN_ALIAS_ALL on pointer types to types that have the
may_alias attribute set and to not warn for TYPE_REF_CAN_ALIAS_ALL
pointers.
The docs for the may_alias attribute are confusing IMHO, so I
adjusted them. I also removed the (wrong) assigning of alias-set
zero to types with may_alias set.
Instead of looking up the may_alias attribute everytime we build
a pointer type we might want to spare a bit in tree flags we could
use for it instead. OTOH the may_alias attribute design looks
bogus - but we probably have to support it anyway :(
Bootstrapped and tested on x86_64-unknown-linux-gnu - ok for mainline?
Thanks,
Richard.
2008-06-11 Richard Guenther <rguenther@suse.de>
PR middle-end/36369
* c-common.c (strict_aliasing_warning): Do not warn for
TYPE_REF_CAN_ALIAS_ALL pointers.
(c_common_get_alias_set): may_alias types are not special.
* tree.c (build_pointer_type_for_mode): Look up the may_alias
attribute and set can_ref_all accordingly.
(build_reference_type_for_mode): Likewise.
* doc/extend.texi (may_alias): Clarify.
* gcc.dg/Wstrict-aliasing-bogus-ref-all.c: New testcase.
Index: trunk/gcc/c-common.c
===================================================================
*** trunk.orig/gcc/c-common.c 2008-06-11 16:30:10.000000000 +0200
--- trunk/gcc/c-common.c 2008-06-11 16:30:27.000000000 +0200
*************** bool
*** 1070,1076 ****
strict_aliasing_warning (tree otype, tree type, tree expr)
{
if (!(flag_strict_aliasing && POINTER_TYPE_P (type)
! && POINTER_TYPE_P (otype) && !VOID_TYPE_P (TREE_TYPE (type))))
return false;
if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR
--- 1070,1079 ----
strict_aliasing_warning (tree otype, tree type, tree expr)
{
if (!(flag_strict_aliasing && POINTER_TYPE_P (type)
! && POINTER_TYPE_P (otype) && !VOID_TYPE_P (TREE_TYPE (type)))
! /* If the type we are casting to is a ref-all pointer
! dereferencing it is always valid. */
! || TYPE_REF_CAN_ALIAS_ALL (type))
return false;
if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR
*************** c_common_get_alias_set (tree t)
*** 3252,3261 ****
|| t == unsigned_char_type_node)
return 0;
- /* If it has the may_alias attribute, it can alias anything. */
- if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t)))
- return 0;
-
/* The C standard specifically allows aliasing between signed and
unsigned variants of the same type. We treat the signed
variant as canonical. */
--- 3255,3260 ----
Index: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c 2008-06-11 16:17:40.000000000 +0200
--- trunk/gcc/tree.c 2008-06-11 16:30:18.000000000 +0200
*************** build_pointer_type_for_mode (tree to_typ
*** 5399,5404 ****
--- 5399,5409 ----
if (to_type == error_mark_node)
return error_mark_node;
+ /* If the pointed-to type has the may_alias attribute set, force
+ a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */
+ if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)))
+ can_alias_all = true;
+
/* In some cases, languages will have things that aren't a POINTER_TYPE
(such as a RECORD_TYPE for fat pointers in Ada) as TYPE_POINTER_TO.
In that case, return that type without regard to the rest of our
*************** build_reference_type_for_mode (tree to_t
*** 5455,5460 ****
--- 5460,5473 ----
{
tree t;
+ if (to_type == error_mark_node)
+ return error_mark_node;
+
+ /* If the pointed-to type has the may_alias attribute set, force
+ a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */
+ if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)))
+ can_alias_all = true;
+
/* In some cases, languages will have things that aren't a REFERENCE_TYPE
(such as a RECORD_TYPE for fat pointers in Ada) as TYPE_REFERENCE_TO.
In that case, return that type without regard to the rest of our
Index: trunk/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c 2008-06-11 16:30:18.000000000 +0200
***************
*** 0 ****
--- 1,41 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -Wall" } */
+
+ struct g { long a; };
+ unsigned long f(struct g *a) { return *(unsigned long *)&a->a; }
+
+ struct A
+ {
+ void *a;
+ };
+
+ int g(const struct A *x, long *y)
+ {
+ typedef long __attribute__ ((may_alias)) long_a;
+ *y = *(const long_a *) (&x->a);
+ return 1;
+ }
+
+ void *a;
+
+ int
+ f0 (long *y)
+ {
+ *y = *(const long *) &a; /* { dg-warning "will break" } */
+ return 1;
+ }
+
+ int
+ f1 (long *y)
+ {
+ typedef long __attribute__ ((may_alias)) long_a;
+ *y = *(const long_a *) &a;
+ return 1;
+ }
+
+ int
+ f2 (long *y)
+ {
+ *y = *(const long *) &a; /* { dg-warning "will break" } */
+ return 1;
+ }
Index: trunk/gcc/doc/extend.texi
===================================================================
*** trunk.orig/gcc/doc/extend.texi 2008-06-09 15:43:07.000000000 +0200
--- trunk/gcc/doc/extend.texi 2008-06-11 16:34:14.000000000 +0200
*************** The @code{deprecated} attribute can also
*** 4240,4249 ****
variables (@pxref{Function Attributes}, @pxref{Variable Attributes}.)
@item may_alias
! Accesses to objects with types with this attribute are not subjected to
! type-based alias analysis, but are instead assumed to be able to alias
! any other type of objects, just like the @code{char} type. See
! @option{-fstrict-aliasing} for more information on aliasing issues.
Example of use:
--- 4240,4253 ----
variables (@pxref{Function Attributes}, @pxref{Variable Attributes}.)
@item may_alias
! Accesses through pointers to types with this attribute are not subject
! to type-based alias analysis, but are instead assumed to be able to alias
! any other type of objects. These lvalue expressions are treated like
! having a character type. See @option{-fstrict-aliasing} for more information
! on aliasing issues.
!
! Note that an object of a type with this attribute does not have any
! special semantics.
Example of use: