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 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:
  


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