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]

Re: [PATCH][RFC] Fix PR36369, clarify may_alias attribute documentation


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


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