* c-typeck.c (comptypes): Handle zero-length arrays properly.
authorRichard Henderson <rth@redhat.com>
Sun, 16 Sep 2001 00:48:52 +0000 (17:48 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 16 Sep 2001 00:48:52 +0000 (17:48 -0700)
From-SVN: r45641

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/gcc.dg/array-5.c [new file with mode: 0644]

index 5d30dcddafa14695c70422c4f893bcf75c5b575f..e36dcc210a3b679a737b4d85ffc65f857a1b1c4f 100644 (file)
@@ -1,3 +1,7 @@
+2001-09-15  Richard Henderson  <rth@redhat.com>
+
+       * c-typeck.c (comptypes): Handle zero-length arrays properly.
+
 2001-09-15  Roman Lechtchinsky  <rl@cs.tu-berlin.de>
 
        * c-common.c (c_promoting_integer_type_p): Handle ?Imode types.
index 9d2c8f4d1f8cc9614504a76b7dbed7cac2921c1c..3298062e8d7023fed0e84718ec6b6588f73f1a9f 100644 (file)
@@ -505,6 +505,8 @@ comptypes (type1, type2)
       {
        tree d1 = TYPE_DOMAIN (t1);
        tree d2 = TYPE_DOMAIN (t2);
+       bool d1_variable, d2_variable;
+       bool d1_zero, d2_zero;
        val = 1;
 
        /* Target types must match incl. qualifiers.  */
@@ -513,14 +515,25 @@ comptypes (type1, type2)
          return 0;
 
        /* Sizes must match unless one is missing or variable.  */
-       if (d1 == 0 || d2 == 0 || d1 == d2
-           || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
-           || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
-           || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST
-           || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)
+       if (d1 == 0 || d2 == 0 || d1 == d2)
          break;
 
-       if (! tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
+       d1_zero = ! TYPE_MAX_VALUE (d1);
+       d2_zero = ! TYPE_MAX_VALUE (d2);
+
+       d1_variable = (! d1_zero
+                      && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
+                          || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
+       d2_variable = (! d2_zero
+                      && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
+                          || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
+
+       if (d1_variable || d2_variable)
+         break;
+       if (d1_zero && d2_zero)
+         break;
+       if (d1_zero || d2_zero
+           || ! tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
            || ! tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
          val = 0;
 
diff --git a/gcc/testsuite/gcc.dg/array-5.c b/gcc/testsuite/gcc.dg/array-5.c
new file mode 100644 (file)
index 0000000..f5321e4
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+/* Check compatibility of array declarations.  */
+
+/* Incomplete decl matches.  */
+extern char arr0[];
+char arr0[1];
+
+/* Two integral expressions must be the same.  Note that 0 is
+   a gcc extension, but it should work like any other constant.  */
+extern char arr1[1];
+char arr1[1];
+extern char arr2[0];
+char arr2[0];
+extern char arr3[0];            /* { dg-error "previous declaration" } */
+char arr3[1];                   /* { dg-error "conflicting types" } */
+
+/* Variable size matches.  */
+void func(int n, int m)
+{
+  /* The next two are from the example in c99 6.7.5.2/9.  */
+  {
+    /* Invalid: not compatible because 4 != 6.  */
+    int a[n][6][m];
+    int (*p)[4][n+1];
+    p = a;                     /* { dg-error "incompatible" } */
+  }
+  {
+    /* Compatible, but defined behavior only if n == 6 and m == n+1.  */
+    int c[n][n][6][m];
+    int (*r)[n][n][n+1];
+    r = c;
+  }
+  {
+    /* Compatible, but undefined behavior; (2, 2) is not a constant
+       expression, and thus A is a VLA.  */
+    int a[(2, 2)];
+    int (*p)[3];
+    p = a; /* { dg-bogus "incompatible" "bad vla handling" { xfail *-*-* } } */
+  }
+}