aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-typeck.c24
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/c-c++-common/attr-may-alias-1.c26
-rw-r--r--gcc/testsuite/c-c++-common/attr-may-alias-2.c17
-rw-r--r--gcc/testsuite/gcc.dg/pr39464.c8
6 files changed, 80 insertions, 7 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 1262c82..f0b03d2 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,9 @@
+2016-06-06 Marek Polacek <polacek@redhat.com>
+
+ * c-typeck.c (comptypes_internal): Handle comparisons of
+ INTEGER_TYPE, FIXED_POINT_TYPE, and REAL_TYPE nodes. Don't check
+ TYPE_REF_CAN_ALIAS_ALL.
+
2016-06-03 Chung-Lin Tang <cltang@codesourcery.com>
* c-typeck.c (c_finish_omp_clauses): Mark OpenACC reduction
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 0ff28f2..cee566f 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -1105,10 +1105,28 @@ comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
switch (TREE_CODE (t1))
{
+ case INTEGER_TYPE:
+ case FIXED_POINT_TYPE:
+ case REAL_TYPE:
+ /* With these nodes, we can't determine type equivalence by
+ looking at what is stored in the nodes themselves, because
+ two nodes might have different TYPE_MAIN_VARIANTs but still
+ represent the same type. For example, wchar_t and int could
+ have the same properties (TYPE_PRECISION, TYPE_MIN_VALUE,
+ TYPE_MAX_VALUE, etc.), but have different TYPE_MAIN_VARIANTs
+ and are distinct types. On the other hand, int and the
+ following typedef
+
+ typedef int INT __attribute((may_alias));
+
+ have identical properties, different TYPE_MAIN_VARIANTs, but
+ represent the same type. The canonical type system keeps
+ track of equivalence in this case, so we fall back on it. */
+ return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
+
case POINTER_TYPE:
- /* Do not remove mode or aliasing information. */
- if (TYPE_MODE (t1) != TYPE_MODE (t2)
- || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
+ /* Do not remove mode information. */
+ if (TYPE_MODE (t1) != TYPE_MODE (t2))
break;
val = (TREE_TYPE (t1) == TREE_TYPE (t2)
? 1 : comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0940e91..1a7e9ee 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-06-06 Marek Polacek <polacek@redhat.com>
+
+ * c-c++-common/attr-may-alias-1.c: New test.
+ * c-c++-common/attr-may-alias-2.c: New test.
+ * gcc.dg/pr39464.c: Turn dg-warning into dg-bogus.
+
2016-06-06 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR c/24414
diff --git a/gcc/testsuite/c-c++-common/attr-may-alias-1.c b/gcc/testsuite/c-c++-common/attr-may-alias-1.c
new file mode 100644
index 0000000..978b9a5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-may-alias-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+typedef int T __attribute__((may_alias));
+
+extern T *p;
+extern int *p;
+
+extern int *p2;
+extern T *p2;
+
+void fn1 (T);
+void fn1 (int);
+
+void fn2 (int);
+void fn2 (T);
+
+/* Ensure that the composite types have may_alias. */
+void
+f (long *i)
+{
+ *i = *(__typeof (*p) *) &p;
+ asm ("" : : "r" (*p));
+ *i = *(__typeof (*p2) *) &p2;
+ asm ("" : : "r" (*p2));
+}
diff --git a/gcc/testsuite/c-c++-common/attr-may-alias-2.c b/gcc/testsuite/c-c++-common/attr-may-alias-2.c
new file mode 100644
index 0000000..44ea926
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-may-alias-2.c
@@ -0,0 +1,17 @@
+/* We used to reject this because types differentiating only in
+ TYPE_REF_CAN_ALIAS_ALL were deemed incompatible. */
+/* { dg-do compile } */
+
+struct sockaddr;
+struct sockaddr *f (void);
+
+struct __attribute__((may_alias)) sockaddr { int j; };
+struct sockaddr *
+f (void)
+{
+ return
+#ifndef __cplusplus
+ (void *)
+#endif
+ 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr39464.c b/gcc/testsuite/gcc.dg/pr39464.c
index cd74540..021c54e 100644
--- a/gcc/testsuite/gcc.dg/pr39464.c
+++ b/gcc/testsuite/gcc.dg/pr39464.c
@@ -8,10 +8,10 @@ typedef unsigned int U __attribute__((may_alias));
void
foo (void *p)
{
- T *a = (int *) p; /* { dg-warning "initialization from incompatible pointer type" } */
- int *b = (T *) p; /* { dg-warning "initialization from incompatible pointer type" } */
- U *c = (unsigned int *) p; /* { dg-warning "initialization from incompatible pointer type" } */
- unsigned int *d = (U *) p; /* { dg-warning "initialization from incompatible pointer type" } */
+ T *a = (int *) p; /* { dg-bogus "initialization from incompatible pointer type" } */
+ int *b = (T *) p; /* { dg-bogus "initialization from incompatible pointer type" } */
+ U *c = (unsigned int *) p; /* { dg-bogus "initialization from incompatible pointer type" } */
+ unsigned int *d = (U *) p; /* { dg-bogus "initialization from incompatible pointer type" } */
(void) a;
(void) b;
(void) c;