This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [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
- Cc: Diego Novillo <dnovillo at google dot com>, iant at google dot com
- Date: Mon, 14 Jul 2008 11:27:35 +0200 (CEST)
- Subject: Re: [PATCH][RFC] Fix PR36369, clarify may_alias attribute documentation
- References: <Pine.LNX.4.64.0806111928560.4140@zhemvz.fhfr.qr> <Pine.LNX.4.64.0806241501160.4145@zhemvz.fhfr.qr>
On Tue, 24 Jun 2008, Richard Guenther wrote:
> Ping!
Ping^2!
> On Wed, 11 Jun 2008, Richard Guenther wrote:
>
> >
> > 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:
> >
> >
>
>
--
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex