summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/c-common.c13
-rw-r--r--gcc/doc/extend.texi14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c41
-rw-r--r--gcc/tree.c13
6 files changed, 87 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b4df1d50e8c..7ea39a7e316 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2008-07-15 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.
+
2008-07-15 Kaz Kojima <kkojima@gcc.gnu.org>
PR target/36780
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 1af2120f84b..e93d2fba6df 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1242,8 +1242,13 @@ warn_logical_operator (enum tree_code code, tree arg1, tree
bool
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 (!(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
@@ -3464,10 +3469,6 @@ c_common_get_alias_set (tree t)
|| 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. */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index eecb4ca5bf4..4a4c9a3a4a1 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4240,10 +4240,16 @@ The @code{deprecated} attribute can also be used for functions and
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.
+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. In the context of 6.5/7 an lvalue expression
+dereferencing such a pointer is treated like having a character type.
+See @option{-fstrict-aliasing} for more information on aliasing issues.
+This extension exists to support some vector APIs, in which pointers to
+one vector type are permitted to alias pointers to a different vector type.
+
+Note that an object of a type with this attribute does not have any
+special semantics.
Example of use:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4526d9fcb83..33d94fceaec 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-07-15 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/36369
+ * gcc.dg/Wstrict-aliasing-bogus-ref-all.c: New testcase.
+
2008-07-15 Andrew Pinski <andrew_pinski@playstation.sony.com>
PR target/31568
diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c
new file mode 100644
index 00000000000..7e8d1771568
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c
@@ -0,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;
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 0bb9fd9367f..6441ae6ef33 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5499,6 +5499,11 @@ build_pointer_type_for_mode (tree to_type, enum machine_mode mode,
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
@@ -5555,6 +5560,14 @@ build_reference_type_for_mode (tree to_type, enum machine_mode mode,
{
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