[backport from gcc-4.6.4 r191337, for expedited testing <mikpe@it.uu.se>]

gcc/

2012-09-15  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.

gcc/testsuite/

2012-09-15  Joseph Myers  <joseph@codesourcery.com>

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

--- gcc-4.6.3/gcc/c-typeck.c.~1~	2011-11-04 22:49:49.000000000 +0100
+++ gcc-4.6.3/gcc/c-typeck.c	2012-09-15 14:29:05.000000000 +0200
@@ -4750,8 +4750,11 @@ c_cast_expr (location_t loc, struct c_ty
   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);
     }
 
--- gcc-4.6.3/gcc/testsuite/gcc.c-torture/compile/pr54552-1.c.~1~	1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.6.3/gcc/testsuite/gcc.c-torture/compile/pr54552-1.c	2012-09-15 14:29:05.000000000 +0200
@@ -0,0 +1,8 @@
+void
+f (void)
+{
+  unsigned n = 10;
+
+  typedef double T[n];
+  (double (*)[n])((unsigned char (*)[sizeof (T)]){ 0 });
+}
