diff options
| author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-21 23:46:20 +0000 | 
|---|---|---|
| committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-21 23:46:20 +0000 | 
| commit | 3ad5f027d89dd828eff822371e1791f520d83c41 (patch) | |
| tree | 3445b1b5b70b8f6f28f797b70463fa6e393fa8e1 /gcc | |
| parent | e2e173ac79124b41dd69b8f1323782aee89ac789 (diff) | |
| download | ppe42-gcc-3ad5f027d89dd828eff822371e1791f520d83c41.tar.gz ppe42-gcc-3ad5f027d89dd828eff822371e1791f520d83c41.zip | |
	PR c/11250
	* c-parse.in (init): Change to exprtype.
	(primary): Set original_code for STRING to STRING_CST.
	Call maybe_warn_string_init for compound literals.
	(initdcl, notype_initdcl): Call maybe_warn_string_init.
	(initval): Update.
	* c-tree.h (maybe_warn_string_init): New.
	(pop_init_level, process_init_element): Use struct c_expr.
	(struct c_expr): Update comment.
	* c-typeck.c (maybe_warn_string_init): New function.
	(digest_init): Call it.  Additional parameter strict_string.  All
	callers changed.
	(output_init_element): Likewise.
	(struct constructor_stack): Use struct c_expr for
	replacement_value.
	(really_start_incremental_init, push_init_level): Update.
	(pop_init_level): Update.  Return struct c_expr.
	(process_init_level): Update.  Take struct c_expr argument.
testsuite:
	* gcc.dg/init-string-1.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85022 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/ChangeLog | 21 | ||||
| -rw-r--r-- | gcc/c-parse.in | 21 | ||||
| -rw-r--r-- | gcc/c-tree.h | 10 | ||||
| -rw-r--r-- | gcc/c-typeck.c | 180 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/init-string-1.c | 59 | 
6 files changed, 216 insertions, 80 deletions
| diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 40ebced7609..16fa6573ca8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2004-07-22  Joseph S. Myers  <jsm@polyomino.org.uk> + +	PR c/11250 +	* c-parse.in (init): Change to exprtype. +	(primary): Set original_code for STRING to STRING_CST. +	Call maybe_warn_string_init for compound literals. +	(initdcl, notype_initdcl): Call maybe_warn_string_init. +	(initval): Update. +	* c-tree.h (maybe_warn_string_init): New. +	(pop_init_level, process_init_element): Use struct c_expr. +	(struct c_expr): Update comment. +	* c-typeck.c (maybe_warn_string_init): New function. +	(digest_init): Call it.  Additional parameter strict_string.  All +	callers changed. +	(output_init_element): Likewise. +	(struct constructor_stack): Use struct c_expr for +	replacement_value. +	(really_start_incremental_init, push_init_level): Update. +	(pop_init_level): Update.  Return struct c_expr. +	(process_init_level): Update.  Take struct c_expr argument. +  2004-07-21  David S. Miller  <davem@nuts.davemloft.net>  	* config/sparc/sparc.c (sparc_rtx_costs): Fix typo in previous diff --git a/gcc/c-parse.in b/gcc/c-parse.in index b56bfee03ac..4179243f240 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -204,7 +204,8 @@ do {									\  %type <ttype> offsetof_member_designator  %type <ttype> scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_volatile -%type <ttype> initdecls notype_initdecls initdcl notype_initdcl init +%type <ttype> initdecls notype_initdecls initdcl notype_initdcl +%type <exprtype> init  %type <ttype> simple_asm_expr maybeasm asm_stmt asm_argument  %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers  %type <ttype> maybe_attribute attributes attribute attribute_list attrib @@ -631,7 +632,7 @@ primary:  	| CONSTANT  		{ $$.value = $1; $$.original_code = ERROR_MARK; }  	| STRING -		{ $$.value = $1; $$.original_code = ERROR_MARK; } +		{ $$.value = $1; $$.original_code = STRING_CST; }  	| FUNC_NAME  		{ $$.value = fname_decl (C_RID_CODE ($1), $1);  		  $$.original_code = ERROR_MARK; } @@ -640,9 +641,11 @@ primary:  		  $2 = groktypename ($2);  		  really_start_incremental_init ($2); }  	  initlist_maybe_comma '}'  %prec UNARY -		{ tree constructor = pop_init_level (0); +		{ struct c_expr init = pop_init_level (0); +		  tree constructor = init.value;  		  tree type = $2;  		  finish_init (); +		  maybe_warn_string_init (type, init);  		  if (pedantic && ! flag_isoc99)  		    pedwarn ("ISO C90 forbids compound literals"); @@ -1391,7 +1394,8 @@ initdcl:  	  init  /* Note how the declaration of the variable is in effect while its init is parsed! */  		{ finish_init (); -		  finish_decl ($<ttype>5, $6, $2); } +		  maybe_warn_string_init (TREE_TYPE ($<ttype>5), $6); +		  finish_decl ($<ttype>5, $6.value, $2); }  	| declarator maybeasm maybe_attribute  		{ tree d = start_decl ($1, current_declspecs, 0,  				       chainon ($3, all_prefix_attributes)); @@ -1407,7 +1411,8 @@ notype_initdcl:  	  init  /* Note how the declaration of the variable is in effect while its init is parsed! */  		{ finish_init (); -		  finish_decl ($<ttype>5, $6, $2); } +		  maybe_warn_string_init (TREE_TYPE ($<ttype>5), $6); +		  finish_decl ($<ttype>5, $6.value, $2); }  	| notype_declarator maybeasm maybe_attribute  		{ tree d = start_decl ($1, current_declspecs, 0,  				       chainon ($3, all_prefix_attributes)); @@ -1476,13 +1481,13 @@ scspec:  init:  	expr_no_commas -		{ $$ = $1.value; } +		{ $$ = $1; }  	| '{'  		{ really_start_incremental_init (NULL_TREE); }  	  initlist_maybe_comma '}'  		{ $$ = pop_init_level (0); }  	| error -		{ $$ = error_mark_node; } +		{ $$.value = error_mark_node; $$.original_code = ERROR_MARK; }  	;  /* `initlist_maybe_comma' is the guts of an initializer in braces.  */ @@ -1522,7 +1527,7 @@ initval:  	  initlist_maybe_comma '}'  		{ process_init_element (pop_init_level (0)); }  	| expr_no_commas -		{ process_init_element ($1.value); } +		{ process_init_element ($1); }  	| error  	; diff --git a/gcc/c-tree.h b/gcc/c-tree.h index d6cdc97be13..9e249532a5e 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -119,8 +119,9 @@ struct c_expr    /* The value of the expression.  */    tree value;    /* Record the original binary operator of an expression, which may -     have been changed by fold, or ERROR_MARK for other expressions -     (including parenthesized expressions).  */ +     have been changed by fold, STRING_CST for unparenthesised string +     constants, or ERROR_MARK for other expressions (including +     parenthesized expressions).  */    enum tree_code original_code;  }; @@ -244,14 +245,15 @@ extern tree build_modify_expr (tree, enum tree_code, tree);  extern void store_init_value (tree, tree);  extern void error_init (const char *);  extern void pedwarn_init (const char *); +extern void maybe_warn_string_init (tree, struct c_expr);  extern void start_init (tree, tree, int);  extern void finish_init (void);  extern void really_start_incremental_init (tree);  extern void push_init_level (int); -extern tree pop_init_level (int); +extern struct c_expr pop_init_level (int);  extern void set_init_index (tree, tree);  extern void set_init_label (tree); -extern void process_init_element (tree); +extern void process_init_element (struct c_expr);  extern tree build_compound_literal (tree, tree);  extern void pedwarn_c90 (const char *, ...) ATTRIBUTE_PRINTF_1;  extern void pedwarn_c99 (const char *, ...) ATTRIBUTE_PRINTF_1; diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 6e1b9281b63..9c22b8b0cf0 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -72,8 +72,8 @@ static void push_array_bounds (int);  static int spelling_length (void);  static char *print_spelling (char *);  static void warning_init (const char *); -static tree digest_init (tree, tree, int); -static void output_init_element (tree, tree, tree, int); +static tree digest_init (tree, tree, bool, int); +static void output_init_element (tree, bool, tree, tree, int);  static void output_pending_init_elements (int);  static int set_designator (int);  static void push_range_stack (tree); @@ -2960,7 +2960,7 @@ build_c_cast (tree type, tree expr)  	  t = digest_init (type,  			   build_constructor (type,  					      build_tree_list (field, value)), -			   0); +			   true, 0);  	  TREE_CONSTANT (t) = TREE_CONSTANT (value);  	  TREE_INVARIANT (t) = TREE_INVARIANT (value);  	  return t; @@ -3674,7 +3674,7 @@ store_init_value (tree decl, tree init)    /* Digest the specified initializer into an expression.  */ -  value = digest_init (type, init, TREE_STATIC (decl)); +  value = digest_init (type, init, true, TREE_STATIC (decl));    /* Store the expression if valid; else report error.  */ @@ -3884,14 +3884,32 @@ warning_init (const char *msgid)      warning ("(near initialization for `%s')", ofwhat);  } +/* If TYPE is an array type and EXPR is a parenthesized string +   constant, warn if pedantic that EXPR is being used to initialize an +   object of type TYPE.  */ + +void +maybe_warn_string_init (tree type, struct c_expr expr) +{ +  if (pedantic +      && TREE_CODE (type) == ARRAY_TYPE +      && TREE_CODE (expr.value) == STRING_CST +      && expr.original_code != STRING_CST) +    pedwarn_init ("array initialized from parenthesized string constant"); +} +  /* Digest the parser output INIT as an initializer for type TYPE.     Return a C expression of type TYPE to represent the initial value. +   If INIT is a string constant, STRICT_STRING is true if it is +   unparenthesized or we should not warn here for it being parenthesized. +   For other types of INIT, STRICT_STRING is not used. +     REQUIRE_CONSTANT requests an error if non-constant initializers or     elements are seen.  */  static tree -digest_init (tree type, tree init, int require_constant) +digest_init (tree type, tree init, bool strict_string, int require_constant)  {    enum tree_code code = TREE_CODE (type);    tree inside_init = init; @@ -3922,6 +3940,11 @@ digest_init (tree type, tree init, int require_constant)  	   || typ1 == signed_wchar_type_node)  	  && ((inside_init && TREE_CODE (inside_init) == STRING_CST)))  	{ +	  struct c_expr expr; +	  expr.value = inside_init; +	  expr.original_code = (strict_string ? STRING_CST : ERROR_MARK); +	  maybe_warn_string_init (type, expr); +  	  if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),  			 TYPE_MAIN_VARIANT (type)))  	    return inside_init; @@ -4218,9 +4241,9 @@ struct constructor_stack    struct init_node *pending_elts;    int offset;    int depth; -  /* If nonzero, this value should replace the entire +  /* If value nonzero, this value should replace the entire       constructor at this level.  */ -  tree replacement_value; +  struct c_expr replacement_value;    struct constructor_range_stack *range_stack;    char constant;    char simple; @@ -4399,7 +4422,8 @@ really_start_incremental_init (tree type)    p->erroneous = constructor_erroneous;    p->pending_elts = constructor_pending_elts;    p->depth = constructor_depth; -  p->replacement_value = 0; +  p->replacement_value.value = 0; +  p->replacement_value.original_code = ERROR_MARK;    p->implicit = 0;    p->range_stack = 0;    p->outer = 0; @@ -4528,7 +4552,8 @@ push_init_level (int implicit)    p->erroneous = constructor_erroneous;    p->pending_elts = constructor_pending_elts;    p->depth = constructor_depth; -  p->replacement_value = 0; +  p->replacement_value.value = 0; +  p->replacement_value.original_code = ERROR_MARK;    p->implicit = implicit;    p->outer = 0;    p->incremental = constructor_incremental; @@ -4665,18 +4690,23 @@ push_init_level (int implicit)  }  /* At the end of an implicit or explicit brace level, -   finish up that level of constructor. -   If we were outputting the elements as they are read, return 0 +   finish up that level of constructor.  If a single expression +   with redundant braces initialized that level, return the +   c_expr structure for that expression.  Otherwise, the original_code +   element is set to ERROR_MARK. +   If we were outputting the elements as they are read, return 0 as the value     from inner levels (process_init_element ignores that), -   but return error_mark_node from the outermost level +   but return error_mark_node as the value from the outermost level     (that's what we want to put in DECL_INITIAL). -   Otherwise, return a CONSTRUCTOR expression.  */ +   Otherwise, return a CONSTRUCTOR expression as the value.  */ -tree +struct c_expr  pop_init_level (int implicit)  {    struct constructor_stack *p; -  tree constructor = 0; +  struct c_expr ret; +  ret.value = 0; +  ret.original_code = ERROR_MARK;    if (implicit == 0)      { @@ -4748,10 +4778,10 @@ pop_init_level (int implicit)      }    /* Pad out the end of the structure.  */ -  if (p->replacement_value) +  if (p->replacement_value.value)      /* If this closes a superfluous brace pair,         just pass out the element between them.  */ -    constructor = p->replacement_value; +    ret = p->replacement_value;    else if (constructor_type == 0)      ;    else if (TREE_CODE (constructor_type) != RECORD_TYPE @@ -4765,28 +4795,28 @@ pop_init_level (int implicit)  	{  	  if (!constructor_erroneous)  	    error_init ("empty scalar initializer"); -	  constructor = error_mark_node; +	  ret.value = error_mark_node;  	}        else if (TREE_CHAIN (constructor_elements) != 0)  	{  	  error_init ("extra elements in scalar initializer"); -	  constructor = TREE_VALUE (constructor_elements); +	  ret.value = TREE_VALUE (constructor_elements);  	}        else -	constructor = TREE_VALUE (constructor_elements); +	ret.value = TREE_VALUE (constructor_elements);      }    else      {        if (constructor_erroneous) -	constructor = error_mark_node; +	ret.value = error_mark_node;        else  	{ -	  constructor = build_constructor (constructor_type, -					   nreverse (constructor_elements)); +	  ret.value = build_constructor (constructor_type, +					 nreverse (constructor_elements));  	  if (constructor_constant) -	    TREE_CONSTANT (constructor) = TREE_INVARIANT (constructor) = 1; +	    TREE_CONSTANT (ret.value) = TREE_INVARIANT (ret.value) = 1;  	  if (constructor_constant && constructor_simple) -	    TREE_STATIC (constructor) = 1; +	    TREE_STATIC (ret.value) = 1;  	}      } @@ -4812,13 +4842,16 @@ pop_init_level (int implicit)    constructor_stack = p->next;    free (p); -  if (constructor == 0) +  if (ret.value == 0)      {        if (constructor_stack == 0) -	return error_mark_node; -      return NULL_TREE; +	{ +	  ret.value = error_mark_node; +	  return ret; +	} +      return ret;      } -  return constructor; +  return ret;  }  /* Common handling for both array range and field name designators. @@ -5415,13 +5448,17 @@ find_init_member (tree field)     Otherwise, collect it in a list from which we will make a CONSTRUCTOR.     TYPE is the data type that the containing data type wants here.     FIELD is the field (a FIELD_DECL) or the index that this element fills. +   If VALUE is a string constant, STRICT_STRING is true if it is +   unparenthesized or we should not warn here for it being parenthesized. +   For other types of VALUE, STRICT_STRING is not used.     PENDING if non-nil means output pending elements that belong     right after this element.  (PENDING is normally 1;     it is 0 while outputting pending elements, to avoid recursion.)  */  static void -output_init_element (tree value, tree type, tree field, int pending) +output_init_element (tree value, bool strict_string, tree type, tree field, +		     int pending)  {    if (type == error_mark_node)      { @@ -5477,7 +5514,7 @@ output_init_element (tree value, tree type, tree field, int pending)  		  || TREE_CHAIN (field)))))      return; -  value = digest_init (type, value, require_constant_value); +  value = digest_init (type, value, strict_string, require_constant_value);    if (value == error_mark_node)      {        constructor_erroneous = 1; @@ -5597,7 +5634,7 @@ output_pending_init_elements (int all)  	{  	  if (tree_int_cst_equal (elt->purpose,  				  constructor_unfilled_index)) -	    output_init_element (elt->value, +	    output_init_element (elt->value, true,  				 TREE_TYPE (constructor_type),  				 constructor_unfilled_index, 0);  	  else if (tree_int_cst_lt (constructor_unfilled_index, @@ -5651,7 +5688,7 @@ output_pending_init_elements (int all)  	  if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos))  	    {  	      constructor_unfilled_fields = elt->purpose; -	      output_init_element (elt->value, TREE_TYPE (elt->purpose), +	      output_init_element (elt->value, true, TREE_TYPE (elt->purpose),  				   elt->purpose, 0);  	    }  	  else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos)) @@ -5718,10 +5755,11 @@ output_pending_init_elements (int all)     it calls output_init_element.  */  void -process_init_element (tree value) +process_init_element (struct c_expr value)  { -  tree orig_value = value; -  int string_flag = value != 0 && TREE_CODE (value) == STRING_CST; +  tree orig_value = value.value; +  int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST; +  bool strict_string = value.original_code == STRING_CST;    designator_depth = 0;    designator_errorneous = 0; @@ -5734,13 +5772,13 @@ process_init_element (tree value)        && TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE        && integer_zerop (constructor_unfilled_index))      { -      if (constructor_stack->replacement_value) +      if (constructor_stack->replacement_value.value)          error_init ("excess elements in char array initializer");        constructor_stack->replacement_value = value;        return;      } -  if (constructor_stack->replacement_value != 0) +  if (constructor_stack->replacement_value.value != 0)      {        error_init ("excess elements in struct initializer");        return; @@ -5773,10 +5811,10 @@ process_init_element (tree value)      {        /* If value is a compound literal and we'll be just using its  	 content, don't put it into a SAVE_EXPR.  */ -      if (TREE_CODE (value) != COMPOUND_LITERAL_EXPR +      if (TREE_CODE (value.value) != COMPOUND_LITERAL_EXPR  	  || !require_constant_value  	  || flag_isoc99) -	value = save_expr (value); +	value.value = save_expr (value.value);      }    while (1) @@ -5808,16 +5846,16 @@ process_init_element (tree value)  	    }  	  /* Accept a string constant to initialize a subarray.  */ -	  if (value != 0 +	  if (value.value != 0  	      && fieldcode == ARRAY_TYPE  	      && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE  	      && string_flag) -	    value = orig_value; +	    value.value = orig_value;  	  /* Otherwise, if we have come to a subaggregate,  	     and we don't have an element of its type, push into it.  */ -	  else if (value != 0 && !constructor_no_implicit -		   && value != error_mark_node -		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype +	  else if (value.value != 0 && !constructor_no_implicit +		   && value.value != error_mark_node +		   && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype  		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE  		       || fieldcode == UNION_TYPE))  	    { @@ -5825,10 +5863,11 @@ process_init_element (tree value)  	      continue;  	    } -	  if (value) +	  if (value.value)  	    {  	      push_member_name (constructor_fields); -	      output_init_element (value, fieldtype, constructor_fields, 1); +	      output_init_element (value.value, strict_string, +				   fieldtype, constructor_fields, 1);  	      RESTORE_SPELLING_DEPTH (constructor_depth);  	    }  	  else @@ -5890,20 +5929,21 @@ process_init_element (tree value)  	     __STDC__ anyway (and we've already complained about the  	     member-designator already).  */  	  if (warn_traditional && !in_system_header && !constructor_designated -	      && !(value && (integer_zerop (value) || real_zerop (value)))) +	      && !(value.value && (integer_zerop (value.value) +				   || real_zerop (value.value))))  	    warning ("traditional C rejects initialization of unions");  	  /* Accept a string constant to initialize a subarray.  */ -	  if (value != 0 +	  if (value.value != 0  	      && fieldcode == ARRAY_TYPE  	      && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE  	      && string_flag) -	    value = orig_value; +	    value.value = orig_value;  	  /* Otherwise, if we have come to a subaggregate,  	     and we don't have an element of its type, push into it.  */ -	  else if (value != 0 && !constructor_no_implicit -		   && value != error_mark_node -		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype +	  else if (value.value != 0 && !constructor_no_implicit +		   && value.value != error_mark_node +		   && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype  		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE  		       || fieldcode == UNION_TYPE))  	    { @@ -5911,10 +5951,11 @@ process_init_element (tree value)  	      continue;  	    } -	  if (value) +	  if (value.value)  	    {  	      push_member_name (constructor_fields); -	      output_init_element (value, fieldtype, constructor_fields, 1); +	      output_init_element (value.value, strict_string, +				   fieldtype, constructor_fields, 1);  	      RESTORE_SPELLING_DEPTH (constructor_depth);  	    }  	  else @@ -5933,16 +5974,16 @@ process_init_element (tree value)  	  enum tree_code eltcode = TREE_CODE (elttype);  	  /* Accept a string constant to initialize a subarray.  */ -	  if (value != 0 +	  if (value.value != 0  	      && eltcode == ARRAY_TYPE  	      && TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE  	      && string_flag) -	    value = orig_value; +	    value.value = orig_value;  	  /* Otherwise, if we have come to a subaggregate,  	     and we don't have an element of its type, push into it.  */ -	  else if (value != 0 && !constructor_no_implicit -		   && value != error_mark_node -		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype +	  else if (value.value != 0 && !constructor_no_implicit +		   && value.value != error_mark_node +		   && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != elttype  		   && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE  		       || eltcode == UNION_TYPE))  	    { @@ -5959,17 +6000,18 @@ process_init_element (tree value)  	    }  	  /* Now output the actual element.  */ -	  if (value) +	  if (value.value)  	    {  	      push_array_bounds (tree_low_cst (constructor_index, 0)); -	      output_init_element (value, elttype, constructor_index, 1); +	      output_init_element (value.value, strict_string, +				   elttype, constructor_index, 1);  	      RESTORE_SPELLING_DEPTH (constructor_depth);  	    }  	  constructor_index  	    = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node); -	  if (! value) +	  if (!value.value)  	    /* If we are doing the bookkeeping for an element that was  	       directly output as a constructor, we must update  	       constructor_unfilled_index.  */ @@ -5988,13 +6030,14 @@ process_init_element (tree value)  	    }  	  /* Now output the actual element.  */ -	  if (value) -	    output_init_element (value, elttype, constructor_index, 1); +	  if (value.value) +	    output_init_element (value.value, strict_string, +				 elttype, constructor_index, 1);  	  constructor_index  	    = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node); -	  if (! value) +	  if (!value.value)  	    /* If we are doing the bookkeeping for an element that was  	       directly output as a constructor, we must update  	       constructor_unfilled_index.  */ @@ -6010,8 +6053,9 @@ process_init_element (tree value)  	}        else  	{ -	  if (value) -	    output_init_element (value, constructor_type, NULL_TREE, 1); +	  if (value.value) +	    output_init_element (value.value, strict_string, +				 constructor_type, NULL_TREE, 1);  	  constructor_fields = 0;  	} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index be2734c041b..d199ab1228b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-07-22  Joseph S. Myers  <jsm@polyomino.org.uk> + +	PR c/11250 +	* gcc.dg/init-string-1.c: New test. +  2004-07-21  Jakub Jelinek  <jakub@redhat.com>  	PR middle-end/15345 diff --git a/gcc/testsuite/gcc.dg/init-string-1.c b/gcc/testsuite/gcc.dg/init-string-1.c new file mode 100644 index 00000000000..ace3b34562e --- /dev/null +++ b/gcc/testsuite/gcc.dg/init-string-1.c @@ -0,0 +1,59 @@ +/* String initializers for arrays must not be parenthesized.  Bug +   11250 from h.b.furuseth at usit.uio.no.  */ +/* Origin: Joseph Myers <jsm@polyomino.org.uk> */ +/* { dg-do compile } */ +/* { dg-options "-std=c99 -pedantic-errors" } */ + +#include <stddef.h> + +char *a = "a"; +char *b = ("b"); +char *c = (("c")); + +char d[] = "d"; +char e[] = ("e"); /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 14 } */ +char f[] = (("f")); /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 16 } */ + +signed char g[] = { "d" }; +unsigned char h[] = { ("e") }; /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 20 } */ +signed char i[] = { (("f")) }; /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 22 } */ + + +struct s { char a[10]; int b; wchar_t c[10]; }; + +struct s j = { +  "j", +  1, +  (L"j") +}; /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 32 } */ +struct s k = { +  (("k")), /* { dg-bogus "warning" "warning in place of error" } */ +  /* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 35 } */ +  1, +  L"k" +}; + +struct s l = { +  .c = (L"l"), /* { dg-bogus "warning" "warning in place of error" } */ +  /* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 42 } */ +  .a = "l" +}; + +struct s m = { +  .c = L"m", +  .a = ("m") +}; /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 50 } */ + +char *n = (char []){ "n" }; + +char *o = (char []){ ("o") }; /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 55 } */ + +wchar_t *p = (wchar_t [5]){ (L"p") }; /* { dg-bogus "warning" "warning in place of error" } */ +/* { dg-error "parenthesized|near init" "paren array" { target *-*-* } 58 } */ | 

