c-typeck.c (comptypes_internal): Handle comparisons of INTEGER_TYPE, FIXED_POINT_TYPE...
authorMarek Polacek <polacek@redhat.com>
Mon, 6 Jun 2016 15:50:23 +0000 (15:50 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Mon, 6 Jun 2016 15:50:23 +0000 (15:50 +0000)
* 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.

* 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.

From-SVN: r237137

gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/attr-may-alias-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/attr-may-alias-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr39464.c

index 1262c82cedb2ff97e887cc6f2b4bab8e97aab4ed..f0b03d2c8d743c9ea4fff1b02daaf715e278331d 100644 (file)
@@ -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
index 0ff28f2ec2810c50f51adce76e4c43536277f7ff..cee566f8322cc00a020c14f5529495c911d77974 100644 (file)
@@ -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),
index 0940e916b1667dfa3ab1cc54b247e56c9ab1a03f..1a7e9eef59bd731bc974e91269b99986d86bae94 100644 (file)
@@ -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 (file)
index 0000000..978b9a5
--- /dev/null
@@ -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 (file)
index 0000000..44ea926
--- /dev/null
@@ -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;
+}
index cd745406da8b32994b271b206b2fac576b6c9c42..021c54e60b1057d86f688fb299f6becb03e965b8 100644 (file)
@@ -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;