This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch for bug 22192


This patch fixes bug 22192 (composite types for VLAs computed
wrongly).

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Applied
to mainline.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2005-07-29  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/22192
	* c-typeck.c (composite_type): Prefer constant size arrays to
	VLAs.

testsuite:
2005-07-29  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/22192
	* gcc.dg/c99-vla-2.c: New test.

diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2005-07-26 11:50:10.000000000 +0000
+++ GCC/gcc/c-typeck.c	2005-07-28 23:39:34.000000000 +0000
@@ -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 -rupN GCC.orig/gcc/testsuite/gcc.dg/c99-vla-2.c GCC/gcc/testsuite/gcc.dg/c99-vla-2.c
--- GCC.orig/gcc/testsuite/gcc.dg/c99-vla-2.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/c99-vla-2.c	2005-07-29 00:14:22.000000000 +0000
@@ -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);
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]