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 further cleanup of default_function_array_conversion


Continuing the series of patches towards eliminating NON_LVALUE_EXPR
(or at least eliminating the C front end's dependence on it, but if
the C++ front end is changed to call fold later it might be possible
to make it a C++-specific code as an interim stage to getting rid of
it altogether), this patch splits up default_function_array_conversion
into array_to_pointer_conversion and function_to_pointer_conversion,
and changes default_function_array_conversion to take a c_expr
structure.  Next would be making other functions caring about
lvalueness also take c_expr structures, before lvalueness can become
flags in the c_expr structure.

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-06-29  Joseph S. Myers  <joseph@codesourcery.com>

	* c-tree.h (default_function_array_conversion): Take and return
	struct c_expr.
	* c-typeck.c (default_function_array_conversion): Split into
	array_to_pointer_conversion and function_to_pointer_conversion.
	Take and return struct c_expr.
	(array_to_pointer_conversion): Do not handle type qualifiers or
	COMPOUND_EXPRs specially.
	(build_function_call): Call function_to_pointer_conversion for
	function designators.
	(build_unary_op): Call array_to_pointer_conversion, not
	default_function_array_conversion.
	(digest_init, output_init_element): Likewise.
	* c-parser.c: All callers of default_function_array_conversion
	changed.

diff -rupN GCC.orig/gcc/c-parser.c GCC/gcc/c-parser.c
--- GCC.orig/gcc/c-parser.c	2005-06-25 09:53:52.000000000 +0000
+++ GCC/gcc/c-parser.c	2005-06-29 19:53:19.000000000 +0000
@@ -2880,7 +2880,7 @@ c_parser_initializer (c_parser *parser)
       ret = c_parser_expr_no_commas (parser, NULL);
       if (TREE_CODE (ret.value) != STRING_CST
 	  && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
-	ret.value = default_function_array_conversion (ret.value);
+	ret = default_function_array_conversion (ret);
       return ret;
     }
 }
@@ -3036,11 +3036,11 @@ c_parser_initelt (c_parser *parser)
 		  rec = first;
 		  while (c_parser_next_token_is (parser, CPP_COMMA))
 		    {
-		      tree next;
+		      struct c_expr next;
 		      c_parser_consume_token (parser);
-		      next = c_parser_expr_no_commas (parser, NULL).value;
+		      next = c_parser_expr_no_commas (parser, NULL);
 		      next = default_function_array_conversion (next);
-		      rec = build_compound_expr (rec, next);
+		      rec = build_compound_expr (rec, next.value);
 		    }
 		parse_message_args:
 		  /* Now parse the objc-message-args.  */
@@ -3130,7 +3130,7 @@ c_parser_initval (c_parser *parser, stru
       if (init.value != NULL_TREE
 	  && TREE_CODE (init.value) != STRING_CST
 	  && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
-	init.value = default_function_array_conversion (init.value);
+	init = default_function_array_conversion (init);
     }
   process_init_element (init);
 }
@@ -3990,7 +3990,8 @@ c_parser_asm_operands (c_parser *parser,
   tree list = NULL_TREE;
   while (true)
     {
-      tree name, str, expr;
+      tree name, str;
+      struct c_expr expr;
       if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
 	{
 	  c_parser_consume_token (parser);
@@ -4021,7 +4022,7 @@ c_parser_asm_operands (c_parser *parser,
 	  c_lex_string_translate = 0;
 	  return NULL_TREE;
 	}
-      expr = c_parser_expression (parser).value;
+      expr = c_parser_expression (parser);
       if (convert_p)
 	expr = default_function_array_conversion (expr);
       c_lex_string_translate = 0;
@@ -4031,7 +4032,7 @@ c_parser_asm_operands (c_parser *parser,
 	  return NULL_TREE;
 	}
       list = chainon (list, build_tree_list (build_tree_list (name, str),
-					     expr));
+					     expr.value));
       if (c_parser_next_token_is (parser, CPP_COMMA))
 	c_parser_consume_token (parser);
       else
@@ -4129,7 +4130,7 @@ c_parser_expr_no_commas (c_parser *parse
     }
   c_parser_consume_token (parser);
   rhs = c_parser_expr_no_commas (parser, NULL);
-  rhs.value = default_function_array_conversion (rhs.value);
+  rhs = default_function_array_conversion (rhs);
   ret.value = build_modify_expr (lhs.value, code, rhs.value);
   if (code == NOP_EXPR)
     ret.original_code = MODIFY_EXPR;
@@ -4163,7 +4164,7 @@ c_parser_conditional_expression (c_parse
   cond = c_parser_binary_expression (parser, after);
   if (c_parser_next_token_is_not (parser, CPP_QUERY))
     return cond;
-  cond.value = default_function_array_conversion (cond.value);
+  cond = default_function_array_conversion (cond);
   c_parser_consume_token (parser);
   if (c_parser_next_token_is (parser, CPP_COLON))
     {
@@ -4192,7 +4193,7 @@ c_parser_conditional_expression (c_parse
       return ret;
     }
   exp2 = c_parser_conditional_expression (parser, NULL);
-  exp2.value = default_function_array_conversion (exp2.value);
+  exp2 = default_function_array_conversion (exp2);
   skip_evaluation -= cond.value == truthvalue_true_node;
   ret.value = build_conditional_expr (cond.value, exp1.value, exp2.value);
   ret.original_code = ERROR_MARK;
@@ -4316,10 +4317,10 @@ c_parser_binary_expression (c_parser *pa
       default:								      \
 	break;								      \
       }									      \
-    stack[sp - 1].expr.value						      \
-      = default_function_array_conversion (stack[sp - 1].expr.value);	      \
-    stack[sp].expr.value						      \
-      = default_function_array_conversion (stack[sp].expr.value);	      \
+    stack[sp - 1].expr							      \
+      = default_function_array_conversion (stack[sp - 1].expr);		      \
+    stack[sp].expr							      \
+      = default_function_array_conversion (stack[sp].expr);		      \
     stack[sp - 1].expr = parser_build_binary_op (stack[sp].op,		      \
 						 stack[sp - 1].expr,	      \
 						 stack[sp].expr);	      \
@@ -4420,15 +4421,15 @@ c_parser_binary_expression (c_parser *pa
       switch (ocode)
 	{
 	case TRUTH_ANDIF_EXPR:
-	  stack[sp].expr.value
-	    = default_function_array_conversion (stack[sp].expr.value);
+	  stack[sp].expr
+	    = default_function_array_conversion (stack[sp].expr);
 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
 	    (default_conversion (stack[sp].expr.value));
 	  skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
 	  break;
 	case TRUTH_ORIF_EXPR:
-	  stack[sp].expr.value
-	    = default_function_array_conversion (stack[sp].expr.value);
+	  stack[sp].expr
+	    = default_function_array_conversion (stack[sp].expr);
 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
 	    (default_conversion (stack[sp].expr.value));
 	  skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
@@ -4472,7 +4473,7 @@ c_parser_cast_expression (c_parser *pars
     {
       struct c_type_name *type_name;
       struct c_expr ret;
-      tree expr;
+      struct c_expr expr;
       c_parser_consume_token (parser);
       type_name = c_parser_type_name (parser);
       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
@@ -4485,9 +4486,9 @@ c_parser_cast_expression (c_parser *pars
       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
 	return c_parser_postfix_expression_after_paren_type (parser,
 							     type_name);
-      expr = c_parser_cast_expression (parser, NULL).value;
+      expr = c_parser_cast_expression (parser, NULL);
       expr = default_function_array_conversion (expr);
-      ret.value = c_cast_expr (type_name, expr);
+      ret.value = c_cast_expr (type_name, expr.value);
       ret.original_code = ERROR_MARK;
       return ret;
     }
@@ -4532,12 +4533,12 @@ c_parser_unary_expression (c_parser *par
     case CPP_PLUS_PLUS:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
-      op.value = default_function_array_conversion (op.value);
+      op = default_function_array_conversion (op);
       return parser_build_unary_op (PREINCREMENT_EXPR, op);
     case CPP_MINUS_MINUS:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
-      op.value = default_function_array_conversion (op.value);
+      op = default_function_array_conversion (op);
       return parser_build_unary_op (PREDECREMENT_EXPR, op);
     case CPP_AND:
       c_parser_consume_token (parser);
@@ -4546,7 +4547,7 @@ c_parser_unary_expression (c_parser *par
     case CPP_MULT:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
-      op.value = default_function_array_conversion (op.value);
+      op = default_function_array_conversion (op);
       ret.value = build_indirect_ref (op.value, "unary *");
       ret.original_code = ERROR_MARK;
       return ret;
@@ -4556,22 +4557,22 @@ c_parser_unary_expression (c_parser *par
 	warning (OPT_Wtraditional,
 		 "traditional C rejects the unary plus operator");
       op = c_parser_cast_expression (parser, NULL);
-      op.value = default_function_array_conversion (op.value);
+      op = default_function_array_conversion (op);
       return parser_build_unary_op (CONVERT_EXPR, op);
     case CPP_MINUS:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
-      op.value = default_function_array_conversion (op.value);
+      op = default_function_array_conversion (op);
       return parser_build_unary_op (NEGATE_EXPR, op);
     case CPP_COMPL:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
-      op.value = default_function_array_conversion (op.value);
+      op = default_function_array_conversion (op);
       return parser_build_unary_op (BIT_NOT_EXPR, op);
     case CPP_NOT:
       c_parser_consume_token (parser);
       op = c_parser_cast_expression (parser, NULL);
-      op.value = default_function_array_conversion (op.value);
+      op = default_function_array_conversion (op);
       return parser_build_unary_op (TRUTH_NOT_EXPR, op);
     case CPP_AND_AND:
       /* Refer to the address of a label as a pointer.  */
@@ -4605,12 +4606,12 @@ c_parser_unary_expression (c_parser *par
 	case RID_REALPART:
 	  c_parser_consume_token (parser);
 	  op = c_parser_cast_expression (parser, NULL);
-	  op.value = default_function_array_conversion (op.value);
+	  op = default_function_array_conversion (op);
 	  return parser_build_unary_op (REALPART_EXPR, op);
 	case RID_IMAGPART:
 	  c_parser_consume_token (parser);
 	  op = c_parser_cast_expression (parser, NULL);
-	  op.value = default_function_array_conversion (op.value);
+	  op = default_function_array_conversion (op);
 	  return parser_build_unary_op (IMAGPART_EXPR, op);
 	default:
 	  return c_parser_postfix_expression (parser);
@@ -5250,7 +5251,7 @@ c_parser_postfix_expression_after_primar
 	case CPP_DOT:
 	  /* Structure element reference.  */
 	  c_parser_consume_token (parser);
-	  expr.value = default_function_array_conversion (expr.value);
+	  expr = default_function_array_conversion (expr);
 	  if (c_parser_next_token_is (parser, CPP_NAME))
 	    ident = c_parser_peek_token (parser)->value;
 	  else
@@ -5267,7 +5268,7 @@ c_parser_postfix_expression_after_primar
 	case CPP_DEREF:
 	  /* Structure element reference.  */
 	  c_parser_consume_token (parser);
-	  expr.value = default_function_array_conversion (expr.value);
+	  expr = default_function_array_conversion (expr);
 	  if (c_parser_next_token_is (parser, CPP_NAME))
 	    ident = c_parser_peek_token (parser)->value;
 	  else
@@ -5285,14 +5286,14 @@ c_parser_postfix_expression_after_primar
 	case CPP_PLUS_PLUS:
 	  /* Postincrement.  */
 	  c_parser_consume_token (parser);
-	  expr.value = default_function_array_conversion (expr.value);
+	  expr = default_function_array_conversion (expr);
 	  expr.value = build_unary_op (POSTINCREMENT_EXPR, expr.value, 0);
 	  expr.original_code = ERROR_MARK;
 	  break;
 	case CPP_MINUS_MINUS:
 	  /* Postdecrement.  */
 	  c_parser_consume_token (parser);
-	  expr.value = default_function_array_conversion (expr.value);
+	  expr = default_function_array_conversion (expr);
 	  expr.value = build_unary_op (POSTDECREMENT_EXPR, expr.value, 0);
 	  expr.original_code = ERROR_MARK;
 	  break;
@@ -5319,7 +5320,7 @@ c_parser_expression (c_parser *parser)
       struct c_expr next;
       c_parser_consume_token (parser);
       next = c_parser_expr_no_commas (parser, NULL);
-      next.value = default_function_array_conversion (next.value);
+      next = default_function_array_conversion (next);
       expr.value = build_compound_expr (expr.value, next.value);
       expr.original_code = COMPOUND_EXPR;
     }
@@ -5334,7 +5335,7 @@ c_parser_expression_conv (c_parser *pars
 {
   struct c_expr expr;
   expr = c_parser_expression (parser);
-  expr.value = default_function_array_conversion (expr.value);
+  expr = default_function_array_conversion (expr);
   return expr;
 }
 
@@ -5353,14 +5354,14 @@ c_parser_expr_list (c_parser *parser, bo
   tree ret, cur;
   expr = c_parser_expr_no_commas (parser, NULL);
   if (convert_p)
-    expr.value = default_function_array_conversion (expr.value);
+    expr = default_function_array_conversion (expr);
   ret = cur = build_tree_list (NULL_TREE, expr.value);
   while (c_parser_next_token_is (parser, CPP_COMMA))
     {
       c_parser_consume_token (parser);
       expr = c_parser_expr_no_commas (parser, NULL);
       if (convert_p)
-	expr.value = default_function_array_conversion (expr.value);
+	expr = default_function_array_conversion (expr);
       cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value);
     }
   return ret;
diff -rupN GCC.orig/gcc/c-tree.h GCC/gcc/c-tree.h
--- GCC.orig/gcc/c-tree.h	2005-06-25 09:53:52.000000000 +0000
+++ GCC/gcc/c-tree.h	2005-06-29 19:47:24.000000000 +0000
@@ -523,7 +523,7 @@ extern bool c_mark_addressable (tree);
 extern void c_incomplete_type_error (tree, tree);
 extern tree c_type_promotes_to (tree);
 extern tree default_conversion (tree);
-extern tree default_function_array_conversion (tree);
+extern struct c_expr default_function_array_conversion (struct c_expr);
 extern tree composite_type (tree, tree);
 extern tree build_component_ref (tree, tree);
 extern tree build_indirect_ref (tree, const char *);
diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2005-06-28 21:48:06.000000000 +0000
+++ GCC/gcc/c-typeck.c	2005-06-29 20:45:45.000000000 +0000
@@ -1259,103 +1259,116 @@ decl_constant_value_for_broken_optimizat
   return ret;
 }
 
-
-/* Perform the default conversion of arrays and functions to pointers.
-   Return the result of converting EXP.  For any other expression, just
-   return EXP after removing NOPs.  */
-
-tree
-default_function_array_conversion (tree exp)
+/* Convert the array expression EXP to a pointer.  */
+static tree
+array_to_pointer_conversion (tree exp)
 {
-  tree orig_exp;
+  tree orig_exp = exp;
   tree type = TREE_TYPE (exp);
-  enum tree_code code = TREE_CODE (type);
-  int not_lvalue = 0;
+  tree adr;
+  tree restype = TREE_TYPE (type);
+  tree ptrtype;
 
-  /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
-     an lvalue.
+  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
 
-     Do not use STRIP_NOPS here!  It will remove conversions from pointer
-     to integer and cause infinite recursion.  */
-  orig_exp = exp;
-  while (TREE_CODE (exp) == NON_LVALUE_EXPR
-	 || (TREE_CODE (exp) == NOP_EXPR
-	     && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))
-    {
-      if (TREE_CODE (exp) == NON_LVALUE_EXPR)
-	not_lvalue = 1;
-      exp = TREE_OPERAND (exp, 0);
-    }
+  STRIP_TYPE_NOPS (exp);
 
   if (TREE_NO_WARNING (orig_exp))
     TREE_NO_WARNING (exp) = 1;
 
-  if (code == FUNCTION_TYPE)
+  ptrtype = build_pointer_type (restype);
+
+  if (TREE_CODE (exp) == INDIRECT_REF)
+    return convert (ptrtype, TREE_OPERAND (exp, 0));
+
+  if (TREE_CODE (exp) == VAR_DECL)
     {
-      return build_unary_op (ADDR_EXPR, exp, 0);
+      /* We are making an ADDR_EXPR of ptrtype.  This is a valid
+	 ADDR_EXPR because it's the best way of representing what
+	 happens in C when we take the address of an array and place
+	 it in a pointer to the element type.  */
+      adr = build1 (ADDR_EXPR, ptrtype, exp);
+      if (!c_mark_addressable (exp))
+	return error_mark_node;
+      TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
+      return adr;
     }
-  if (code == ARRAY_TYPE)
-    {
-      tree adr;
-      tree restype = TREE_TYPE (type);
-      tree ptrtype;
-      int constp = 0;
-      int volatilep = 0;
-      int lvalue_array_p;
 
-      if (REFERENCE_CLASS_P (exp) || DECL_P (exp))
-	{
-	  constp = TREE_READONLY (exp);
-	  volatilep = TREE_THIS_VOLATILE (exp);
-	}
+  /* This way is better for a COMPONENT_REF since it can
+     simplify the offset for a component.  */
+  adr = build_unary_op (ADDR_EXPR, exp, 1);
+  return convert (ptrtype, adr);
+}
 
-      if (TYPE_QUALS (type) || constp || volatilep)
-	restype
-	  = c_build_qualified_type (restype,
-				    TYPE_QUALS (type)
-				    | (constp * TYPE_QUAL_CONST)
-				    | (volatilep * TYPE_QUAL_VOLATILE));
+/* Convert the function expression EXP to a pointer.  */
+static tree
+function_to_pointer_conversion (tree exp)
+{
+  tree orig_exp = exp;
 
-      if (TREE_CODE (exp) == INDIRECT_REF)
-	return convert (build_pointer_type (restype),
-			TREE_OPERAND (exp, 0));
+  gcc_assert (TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE);
 
-      if (TREE_CODE (exp) == COMPOUND_EXPR)
-	{
-	  tree op1 = default_conversion (TREE_OPERAND (exp, 1));
-	  return build2 (COMPOUND_EXPR, TREE_TYPE (op1),
-			 TREE_OPERAND (exp, 0), op1);
-	}
+  STRIP_TYPE_NOPS (exp);
 
-      lvalue_array_p = !not_lvalue && lvalue_p (exp);
-      if (!flag_isoc99 && !lvalue_array_p)
-	{
-	  /* Before C99, non-lvalue arrays do not decay to pointers.
-	     Normally, using such an array would be invalid; but it can
-	     be used correctly inside sizeof or as a statement expression.
-	     Thus, do not give an error here; an error will result later.  */
-	  return exp;
-	}
+  if (TREE_NO_WARNING (orig_exp))
+    TREE_NO_WARNING (exp) = 1;
 
-      ptrtype = build_pointer_type (restype);
+  return build_unary_op (ADDR_EXPR, exp, 0);
+}
 
-      if (TREE_CODE (exp) == VAR_DECL)
-	{
-	  /* We are making an ADDR_EXPR of ptrtype.  This is a valid
-	     ADDR_EXPR because it's the best way of representing what
-	     happens in C when we take the address of an array and place
-	     it in a pointer to the element type.  */
-	  adr = build1 (ADDR_EXPR, ptrtype, exp);
-	  if (!c_mark_addressable (exp))
-	    return error_mark_node;
-	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
-	  return adr;
-	}
-      /* This way is better for a COMPONENT_REF since it can
-	 simplify the offset for a component.  */
-      adr = build_unary_op (ADDR_EXPR, exp, 1);
-      return convert (ptrtype, adr);
+/* Perform the default conversion of arrays and functions to pointers.
+   Return the result of converting EXP.  For any other expression, just
+   return EXP after removing NOPs.  */
+
+struct c_expr
+default_function_array_conversion (struct c_expr exp)
+{
+  tree orig_exp = exp.value;
+  tree type = TREE_TYPE (exp.value);
+  enum tree_code code = TREE_CODE (type);
+
+  switch (code)
+    {
+    case ARRAY_TYPE:
+      {
+	bool not_lvalue = false;
+	bool lvalue_array_p;
+
+	while ((TREE_CODE (exp.value) == NON_LVALUE_EXPR
+		|| TREE_CODE (exp.value) == NOP_EXPR)
+	       && TREE_TYPE (TREE_OPERAND (exp.value, 0)) == type)
+	  {
+	    if (TREE_CODE (exp.value) == NON_LVALUE_EXPR)
+	      not_lvalue = true;
+	    exp.value = TREE_OPERAND (exp.value, 0);
+	  }
+
+	if (TREE_NO_WARNING (orig_exp))
+	  TREE_NO_WARNING (exp.value) = 1;
+
+	lvalue_array_p = !not_lvalue && lvalue_p (exp.value);
+	if (!flag_isoc99 && !lvalue_array_p)
+	  {
+	    /* Before C99, non-lvalue arrays do not decay to pointers.
+	       Normally, using such an array would be invalid; but it can
+	       be used correctly inside sizeof or as a statement expression.
+	       Thus, do not give an error here; an error will result later.  */
+	    return exp;
+	  }
+
+	exp.value = array_to_pointer_conversion (exp.value);
+      }
+      break;
+    case FUNCTION_TYPE:
+      exp.value = function_to_pointer_conversion (exp.value);
+      break;
+    default:
+      STRIP_TYPE_NOPS (exp.value);
+      if (TREE_NO_WARNING (orig_exp))
+	TREE_NO_WARNING (exp.value) = 1;
+      break;
     }
+
   return exp;
 }
 
@@ -1992,7 +2005,8 @@ build_function_call (tree function, tree
       name = DECL_NAME (function);
       fundecl = function;
     }
-  function = default_function_array_conversion (function);
+  if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
+    function = function_to_pointer_conversion (function);
 
   /* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
      expressions, like those used for ObjC messenger dispatches.  */
@@ -2730,11 +2744,13 @@ build_unary_op (enum tree_code code, tre
       /* For &x[y], return x+y */
       if (TREE_CODE (arg) == ARRAY_REF)
 	{
-	  if (!c_mark_addressable (TREE_OPERAND (arg, 0)))
+	  tree op0 = TREE_OPERAND (arg, 0);
+	  if (!c_mark_addressable (op0))
 	    return error_mark_node;
 	  return build_binary_op (PLUS_EXPR,
-				  default_function_array_conversion
-				    (TREE_OPERAND (arg, 0)),
+				  (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE
+				   ? array_to_pointer_conversion (op0)
+				   : op0),
 				  TREE_OPERAND (arg, 1), 1);
 	}
 
@@ -4367,16 +4383,18 @@ digest_init (tree type, tree init, bool 
     {
       if (code == POINTER_TYPE)
 	{
-	  if (TREE_CODE (inside_init) == STRING_CST
-	      || TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
-	    inside_init = default_function_array_conversion (inside_init);
-
 	  if (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE)
 	    {
-	      error_init ("invalid use of non-lvalue array");
-	      return error_mark_node;
+	      if (TREE_CODE (inside_init) == STRING_CST
+		  || TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
+		inside_init = array_to_pointer_conversion (inside_init);
+	      else
+		{
+		  error_init ("invalid use of non-lvalue array");
+		  return error_mark_node;
+		}
 	    }
-	 }
+	}
 
       if (code == VECTOR_TYPE)
 	/* Although the types are compatible, we may require a
@@ -4436,9 +4454,10 @@ digest_init (tree type, tree init, bool 
       || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
       || code == VECTOR_TYPE)
     {
-      if (TREE_CODE (init) == STRING_CST
-	  || TREE_CODE (init) == COMPOUND_LITERAL_EXPR)
-	init = default_function_array_conversion (init);
+      if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE
+	  && (TREE_CODE (init) == STRING_CST
+	      || TREE_CODE (init) == COMPOUND_LITERAL_EXPR))
+	init = array_to_pointer_conversion (init);
       inside_init
 	= convert_for_assignment (type, init, ic_init,
 				  NULL_TREE, NULL_TREE, 0);
@@ -5796,7 +5815,7 @@ output_init_element (tree value, bool st
 	   && INTEGRAL_TYPE_P (TREE_TYPE (type)))
       && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
 		     TYPE_MAIN_VARIANT (type)))
-    value = default_function_array_conversion (value);
+    value = array_to_pointer_conversion (value);
 
   if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
       && require_constant_value && !flag_isoc99 && pending)


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