Patchwork Fix C ICE with casts to pointers to VLAs (PR c/54552)

login
register
mail settings
Submitter Joseph S. Myers
Date Sept. 14, 2012, 9:17 p.m.
Message ID <Pine.LNX.4.64.1209142116550.12448@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/184044/
State New
Headers show

Comments

Joseph S. Myers - Sept. 14, 2012, 9:17 p.m.
Bug 54552 is a C front-end regression involving ICEs when an
expression involving C_MAYBE_CONST_EXPR, such as a compound literal of
variably modified type, is cast to a variably modified type.  This
patch fixes it by doing the appropriate folding before creating the
outer C_MAYBE_CONST_EXPR.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Applied
to mainline.  Will apply to 4.7 (when not frozen) and 4.6 branches
subject to testing there.

c:
2012-09-14  Joseph Myers  <joseph@codesourcery.com>

	PR c/54552
	* c-typeck.c (c_cast_expr): When casting to a type requiring
	C_MAYBE_CONST_EXPR to be created, pass the inner expression to
	c_fully_fold first.

testsuite:
2012-09-14  Joseph Myers  <joseph@codesourcery.com>

	PR c/54552
	* gcc.c-torture/compile/pr54552-1.c: New test.

Patch

Index: c/c-typeck.c
===================================================================
--- c/c-typeck.c	(revision 191305)
+++ c/c-typeck.c	(working copy)
@@ -4779,8 +4779,11 @@  c_cast_expr (location_t loc, struct c_type_name *t
   ret = build_c_cast (loc, type, expr);
   if (type_expr)
     {
+      bool inner_expr_const = true;
+      ret = c_fully_fold (ret, require_constant_value, &inner_expr_const);
       ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret), type_expr, ret);
-      C_MAYBE_CONST_EXPR_NON_CONST (ret) = !type_expr_const;
+      C_MAYBE_CONST_EXPR_NON_CONST (ret) = !(type_expr_const
+					     && inner_expr_const);
       SET_EXPR_LOCATION (ret, loc);
     }
 
Index: testsuite/gcc.c-torture/compile/pr54552-1.c
===================================================================
--- testsuite/gcc.c-torture/compile/pr54552-1.c	(revision 0)
+++ testsuite/gcc.c-torture/compile/pr54552-1.c	(revision 0)
@@ -0,0 +1,8 @@ 
+void
+f (void)
+{
+  unsigned n = 10;
+
+  typedef double T[n];
+  (double (*)[n])((unsigned char (*)[sizeof (T)]){ 0 });
+}