From 916c59199cfbe12788cef6ad2b7cb8ffdc59af71 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 22 Jul 2004 00:46:20 +0100 Subject: [PATCH] re PR c/11250 (-pedantic accepts `char a[] = ("x");') 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. From-SVN: r85022 --- gcc/ChangeLog | 21 ++++ gcc/c-parse.in | 21 ++-- gcc/c-tree.h | 10 +- gcc/c-typeck.c | 180 +++++++++++++++++---------- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.dg/init-string-1.c | 59 +++++++++ 6 files changed, 216 insertions(+), 80 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/init-string-1.c 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 + + 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 * 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 offsetof_member_designator %type scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_volatile -%type initdecls notype_initdecls initdcl notype_initdcl init +%type initdecls notype_initdecls initdcl notype_initdcl +%type init %type simple_asm_expr maybeasm asm_stmt asm_argument %type asm_operands nonnull_asm_operands asm_operand asm_clobbers %type 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 ($5, $6, $2); } + maybe_warn_string_init (TREE_TYPE ($5), $6); + finish_decl ($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 ($5, $6, $2); } + maybe_warn_string_init (TREE_TYPE ($5), $6); + finish_decl ($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 + + PR c/11250 + * gcc.dg/init-string-1.c: New test. + 2004-07-21 Jakub Jelinek 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 */ +/* { dg-do compile } */ +/* { dg-options "-std=c99 -pedantic-errors" } */ + +#include + +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 } */ -- 2.30.2