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 16566


This patch fixes bug 16566, a regression where certain cases only of
flexible array members in non-lvalue structures caused an ICE.  This
only occurred for structures in compound expressions, not the other
cases of non-lvalue structures, and could be triggered before 3.4 with
-pedantic but became more visible when extended lvalues were
deprecated.  It also applied only to flexible arrays, not the similar
GNU array[0] extension.

On mainline the ICE arose from an attempt to create an array-type
GIMPLE temporary for the array of unknown size.  In 3.4 the ICE is
within expand_expr (but on some testcases triggers on the stage2
compiler but not the stage1 compiler for some reason).

(The runtime validity of such references to non-lvalue flexible arrays 
isn't entirely clear - it is clear that the compiler must accept them, and 
that modifying them is runtime undefined behavior, but it appears after 
TC2 that although the contents of the temporary array in a non-lvalue 
structure have unspecified uninitialized values, those that fall within 
the bounds of sizeof(the structure) may be accessed without undefined 
behavior if they aren't trap representations.)

This patch removes the premature optimisation in build_component_ref
which moved a component reference inside a compound expression
(yielding a non-lvalue array reference to an lvalue structure), which
appears to fix this problem.  (Moving the array reference inside as
well isn't a suitable alternative as the result of the array reference
needs to be an lvalue.  Such optimisations at this early stage are of
rather doubtful utility, especially in the presence of tree-ssa.  And
a gradual move away from most non-language-specific optimisation at
parse time is generally a good idea.)

Bootstrapped with no regressions on i686-pc-linux-gnu.  Applied to
mainline.  Will be tested against 3.4 branch and applied there if it
passes testing.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
  http://www.srcf.ucam.org/~jsm28/gcc/#c90status - status of C90 for GCC 4.0
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2004-09-22  Joseph S. Myers  <jsm@polyomino.org.uk>

	PR c/16566
	* c-typeck.c (build_component_ref): Don't special-case
	COMPOUND_EXPR.

testsuite:
2004-09-22  Joseph S. Myers  <jsm@polyomino.org.uk>

	PR c/16566
	* gcc.c-torture/compile/pr16566-1.c,
	gcc.c-torture/compile/pr16566-2.c,
	gcc.c-torture/compile/pr16566-3.c: New tests.

diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2004-09-22 08:40:41.000000000 +0000
+++ GCC/gcc/c-typeck.c	2004-09-22 18:16:11.000000000 +0000
@@ -1452,26 +1452,6 @@ build_component_ref (tree datum, tree co
   if (!objc_is_public (datum, component))
     return error_mark_node;
 
-  /* If DATUM is a COMPOUND_EXPR, move our reference inside it.
-     Ensure that the arguments are not lvalues; otherwise,
-     if the component is an array, it would wrongly decay to a pointer in
-     C89 mode.
-     We cannot do this with a COND_EXPR, because in a conditional expression
-     the default promotions are applied to both sides, and this would yield
-     the wrong type of the result; for example, if the components have
-     type "char".  */
-  switch (TREE_CODE (datum))
-    {
-    case COMPOUND_EXPR:
-      {
-	tree value = build_component_ref (TREE_OPERAND (datum, 1), component);
-	return build2 (COMPOUND_EXPR, TREE_TYPE (value),
-		       TREE_OPERAND (datum, 0), non_lvalue (value));
-      }
-    default:
-      break;
-    }
-
   /* See if there is a field or component with name COMPONENT.  */
 
   if (code == RECORD_TYPE || code == UNION_TYPE)
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/compile/pr16566-1.c GCC/gcc/testsuite/gcc.c-torture/compile/pr16566-1.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/compile/pr16566-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/compile/pr16566-1.c	2004-09-22 08:50:13.000000000 +0000
@@ -0,0 +1,15 @@
+/* ICE with flexible arrays in non-lvalue structures.  Bug 16566
+   (comment #3).  */
+
+struct S;
+
+struct C {
+    int i;
+    struct S *tab[];
+};
+
+struct S { struct C c; };
+
+void foo (struct S *x) {
+  foo(((void)1, x->c).tab[0]);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c GCC/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/compile/pr16566-2.c	2004-09-22 08:50:17.000000000 +0000
@@ -0,0 +1,13 @@
+/* ICE with flexible arrays in non-lvalue structures.  Bug 16566
+   (comment #5).  */
+
+struct A
+{
+    int i;
+    int x[];
+};
+
+int foo(struct A a)
+{ 
+    return (a,a).x[0];
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/compile/pr16566-3.c GCC/gcc/testsuite/gcc.c-torture/compile/pr16566-3.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/compile/pr16566-3.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/compile/pr16566-3.c	2004-09-22 08:50:21.000000000 +0000
@@ -0,0 +1,12 @@
+/* ICE with flexible arrays in non-lvalue structures.  Bug 16566
+   (testcase from duplicate bug 16575).  */
+
+struct S;
+struct C {
+    int i;
+    struct S *tab[];
+};
+struct S { struct C c; };
+void foo (struct S *x) {
+  ((void)1, x->c).tab[0] = 0;
+}


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