summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-29 02:42:19 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-29 02:42:19 +0000
commita2f96aea7bcce4f3a87294052e368759772ea73b (patch)
treee54a0f65a06af8a8ad80ad46289518f14eb6d73c
parent314b93ea9a11200b8b5480588f38d406cdb8d741 (diff)
downloadgcc-a2f96aea7bcce4f3a87294052e368759772ea73b.tar.gz
PR c/22192
* c-typeck.c (composite_type): Prefer constant size arrays to VLAs. testsuite: * gcc.dg/c99-vla-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102540 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-typeck.c27
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/c99-vla-2.c107
4 files changed, 142 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6f10df5e64e..0617b8f1137 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2005-07-29 Joseph S. Myers <joseph@codesourcery.com>
+ PR c/22192
+ * c-typeck.c (composite_type): Prefer constant size arrays to
+ VLAs.
+
+2005-07-29 Joseph S. Myers <joseph@codesourcery.com>
+
PR c/21720
* real.c (real_from_string): Set last bit if there is a nonzero
hex digit beyond GCC's internal precision.
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 7e98384ce28..58694cb5ceb 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -281,14 +281,30 @@ composite_type (tree t1, tree t2)
tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
int quals;
tree unqual_elt;
+ tree d1 = TYPE_DOMAIN (t1);
+ tree d2 = TYPE_DOMAIN (t2);
+ bool d1_variable, d2_variable;
+ bool d1_zero, d2_zero;
/* We should not have any type quals on arrays at all. */
gcc_assert (!TYPE_QUALS (t1) && !TYPE_QUALS (t2));
+ d1_zero = d1 == 0 || !TYPE_MAX_VALUE (d1);
+ d2_zero = d2 == 0 || !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));
+
/* Save space: see if the result is identical to one of the args. */
- if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
+ if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)
+ && (d2_variable || d2_zero || !d1_variable))
return build_type_attribute_variant (t1, attributes);
- if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
+ if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)
+ && (d1_variable || d1_zero || !d2_variable))
return build_type_attribute_variant (t2, attributes);
if (elt == TREE_TYPE (t1) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
@@ -304,7 +320,12 @@ composite_type (tree t1, tree t2)
quals = TYPE_QUALS (strip_array_types (elt));
unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED);
t1 = build_array_type (unqual_elt,
- TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+ TYPE_DOMAIN ((TYPE_DOMAIN (t1)
+ && (d2_variable
+ || d2_zero
+ || !d1_variable))
+ ? t1
+ : t2));
t1 = c_build_qualified_type (t1, quals);
return build_type_attribute_variant (t1, attributes);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 45f6324e3a5..4da38559704 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2005-07-29 Joseph S. Myers <joseph@codesourcery.com>
+ PR c/22192
+ * gcc.dg/c99-vla-2.c: New test.
+
+2005-07-29 Joseph S. Myers <joseph@codesourcery.com>
+
PR c/21720
* gcc.dg/hex-round-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/c99-vla-2.c b/gcc/testsuite/gcc.dg/c99-vla-2.c
new file mode 100644
index 00000000000..de15c73c8d4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-vla-2.c
@@ -0,0 +1,107 @@
+/* Test composite type of VLA and fixed-size array: should be the
+ fixed-size type. Bug 22192. */
+/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+/* Test that the given expression (of pointer-to-array type) points to
+ the right sort of array. */
+#define TEST_FIXED_SIZE(a) do { static int x[sizeof(*(a))]; (void)x; } while (0)
+#define TEST_VLA(a) do { (void)sizeof(*(a)); (void)(1 ? (a) : (__typeof__(**(a)) (*)[1])0); (void)(1 ? (a) : (__typeof__(**(a)) (*)[2])0); } while (0)
+#define TEST_INCOMPLETE(a) do { __typeof__(*(a)) x = { 0 }; (void)x; (void)(1 ? a : (__typeof__(**(a)) (*)[1])0); (void)(1 ? a : (__typeof__(**(a)) (*)[2])0); } while (0)
+
+#define TEST_COMP_FIX(a, b) TEST_FIXED_SIZE(i ? a : b)
+#define TEST_COMP_VLA(a, b) TEST_VLA(i ? a : b)
+#define TEST_COMP_INC(a, b) TEST_INCOMPLETE(i ? a : b)
+
+void
+foo (int i, int j)
+{
+ typedef int I;
+ int (*pf)[2];
+ int (*pv)[i];
+ int (*pi)[];
+ I (*pfI)[2];
+ I (*pvI)[i];
+ I (*piI)[];
+ TEST_COMP_FIX(pf, pf);
+ TEST_COMP_FIX(pf, pv);
+ TEST_COMP_FIX(pf, pi);
+ TEST_COMP_FIX(pf, pfI);
+ TEST_COMP_FIX(pf, pvI);
+ TEST_COMP_FIX(pf, piI);
+ TEST_COMP_FIX(pv, pf);
+ TEST_COMP_VLA(pv, pv);
+ TEST_COMP_VLA(pv, pi);
+ TEST_COMP_FIX(pv, pfI);
+ TEST_COMP_VLA(pv, pvI);
+ TEST_COMP_VLA(pv, piI);
+ TEST_COMP_FIX(pi, pf);
+ TEST_COMP_VLA(pi, pv);
+ TEST_COMP_INC(pi, pi);
+ TEST_COMP_FIX(pi, pfI);
+ TEST_COMP_VLA(pi, pvI);
+ TEST_COMP_INC(pi, piI);
+ TEST_COMP_FIX(pfI, pf);
+ TEST_COMP_FIX(pfI, pv);
+ TEST_COMP_FIX(pfI, pi);
+ TEST_COMP_FIX(pfI, pfI);
+ TEST_COMP_FIX(pfI, pvI);
+ TEST_COMP_FIX(pfI, piI);
+ TEST_COMP_FIX(pvI, pf);
+ TEST_COMP_VLA(pvI, pv);
+ TEST_COMP_VLA(pvI, pi);
+ TEST_COMP_FIX(pvI, pfI);
+ TEST_COMP_VLA(pvI, pvI);
+ TEST_COMP_VLA(pvI, piI);
+ TEST_COMP_FIX(piI, pf);
+ TEST_COMP_VLA(piI, pv);
+ TEST_COMP_INC(piI, pi);
+ TEST_COMP_FIX(piI, pfI);
+ TEST_COMP_VLA(piI, pvI);
+ TEST_COMP_INC(piI, piI);
+ typedef int (*Ti)[i];
+ typedef int (*Tj)[j];
+ Ti (*qf)[2];
+ Ti (*qv)[i];
+ Ti (*qi)[];
+ Tj (*rf)[2];
+ Tj (*rv)[j];
+ Tj (*ri)[];
+ TEST_COMP_FIX(qf, qf);
+ TEST_COMP_FIX(qf, qv);
+ TEST_COMP_FIX(qf, qi);
+ TEST_COMP_FIX(qf, rf);
+ TEST_COMP_FIX(qf, rv);
+ TEST_COMP_FIX(qf, ri);
+ TEST_COMP_FIX(qv, qf);
+ TEST_COMP_VLA(qv, qv);
+ TEST_COMP_VLA(qv, qi);
+ TEST_COMP_FIX(qv, rf);
+ TEST_COMP_VLA(qv, rv);
+ TEST_COMP_VLA(qv, ri);
+ TEST_COMP_FIX(qi, qf);
+ TEST_COMP_VLA(qi, qv);
+ TEST_COMP_INC(qi, qi);
+ TEST_COMP_FIX(qi, rf);
+ TEST_COMP_VLA(qi, rv);
+ TEST_COMP_INC(qi, ri);
+ TEST_COMP_FIX(rf, qf);
+ TEST_COMP_FIX(rf, qv);
+ TEST_COMP_FIX(rf, qi);
+ TEST_COMP_FIX(rf, rf);
+ TEST_COMP_FIX(rf, rv);
+ TEST_COMP_FIX(rf, ri);
+ TEST_COMP_FIX(rv, qf);
+ TEST_COMP_VLA(rv, qv);
+ TEST_COMP_VLA(rv, qi);
+ TEST_COMP_FIX(rv, rf);
+ TEST_COMP_VLA(rv, rv);
+ TEST_COMP_VLA(rv, ri);
+ TEST_COMP_FIX(ri, qf);
+ TEST_COMP_VLA(ri, qv);
+ TEST_COMP_INC(ri, qi);
+ TEST_COMP_FIX(ri, rf);
+ TEST_COMP_VLA(ri, rv);
+ TEST_COMP_INC(ri, ri);
+}