From patchwork Fri May 9 07:27:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 347307 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E8BF41400CB for ; Fri, 9 May 2014 17:27:47 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=xtEm14CXpIwmudSQWlKRluBJttzzCYZYIU4hzJC8tudlrD6Dos a3BtuGuasrR3ipxaxfWZwqFSMd13FQ0wskt8BeSp6KKKXip6RgQtj3ZIyPxuyPP/ c0f1TzXvYVcRNTT75cpc1ScBkz/QeeUFiBuEvJQXXtA5JGCO7EpSiFJYg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=tJqwyCNoTDuHsGB+LBoWFNiIBrg=; b=fwegEJCyj9B695bmtpB2 9PpIrdbFCxk1/Q0RNeeh3a+BZ2qFKhEOZM2gXgiLkT6d7fJ6ZhNzMcWdRPCNPtfG MpxqcRiQq2wi0Jj8/Ixfdb0FQFw60QMHR4ZyP3vg4q1ZvPmAEuxyKseX73NqvgLd SpoOJxyYpfDxvUeIOVzW8P8= Received: (qmail 27912 invoked by alias); 9 May 2014 07:27:40 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 27898 invoked by uid 89); 9 May 2014 07:27:39 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 09 May 2014 07:27:35 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s497RWsX011933 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 9 May 2014 03:27:32 -0400 Received: from redhat.com (ovpn-116-53.ams2.redhat.com [10.36.116.53]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s497RSND015195 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Fri, 9 May 2014 03:27:30 -0400 Date: Fri, 9 May 2014 09:27:27 +0200 From: Marek Polacek To: GCC Patches Cc: "Joseph S. Myers" Subject: [C PATCH] Add location to error_init (PR c/61096) Message-ID: <20140509072727.GF11802@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Another piece of puzzle. error_init didn't have a location parameter, so initialization errors had wrong column info. This patch adds location parameter to error_init and to a few of other functions. The testcases show what has better column info now. Note what I wrote in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61096#c3 -- three error_init calls seem to be unreachable, bonus points for anyone who can construct a testcase that triggers them ;). And neither testsuite nor bootstrap exercises them I think. Many pedwarn_init calls still use input_location; I'm going to address that later when I find some time. Regtested/bootstrapped on x86_64-linux, ok for trunk? 2014-05-09 Marek Polacek PR c/61096 * c-parser.c (c_parser_braced_init): Pass brace_loc to push_init_level. (c_parser_initelt): Pass location to set_init_label. Pass array index location to set_init_index. * c-tree.h (push_init_level): Update declaration. (pop_init_level): Likewise. (set_init_index): Likewise. (set_init_label): Likewise. * c-typeck.c (error_init): Add location parameter. Call error_at instead of error. (digest_init): Pass init_loc to error_init. (really_start_incremental_init): (push_init_level): Add location parameter. Pass loc to pop_init_level and error_init. (pop_init_level): Likewise. (set_designator): Add location parameter. Pass loc to pop_init_level, push_init_level, and error_init. (set_init_index): Add location parameter. Pass loc to error_init and set_designator. (set_init_label): Likewise. (output_init_element): Pass loc to error_init. (process_init_element): Pass loc to error_init, pop_init_level, pedwarn_init, and push_init_level. * gcc.dg/pr61096-1.c: New test. * gcc.dg/pr61096-2.c: New test. Marek diff --git gcc/c/c-parser.c gcc/c/c-parser.c index 6e8f33b..459240f 100644 --- gcc/c/c-parser.c +++ gcc/c/c-parser.c @@ -4138,7 +4138,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); c_parser_consume_token (parser); if (nested_p) - push_init_level (0, &braced_init_obstack); + push_init_level (brace_loc, 0, &braced_init_obstack); else really_start_incremental_init (type); if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) @@ -4168,12 +4168,12 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) ret.original_code = ERROR_MARK; ret.original_type = NULL; c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>"); - pop_init_level (0, &braced_init_obstack); + pop_init_level (brace_loc, 0, &braced_init_obstack); obstack_free (&braced_init_obstack, NULL); return ret; } c_parser_consume_token (parser); - ret = pop_init_level (0, &braced_init_obstack); + ret = pop_init_level (brace_loc, 0, &braced_init_obstack); obstack_free (&braced_init_obstack, NULL); return ret; } @@ -4190,7 +4190,8 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) && c_parser_peek_2nd_token (parser)->type == CPP_COLON) { /* Old-style structure member designator. */ - set_init_label (c_parser_peek_token (parser)->value, + set_init_label (c_parser_peek_token (parser)->location, + c_parser_peek_token (parser)->value, braced_init_obstack); /* Use the colon as the error location. */ pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic, @@ -4219,7 +4220,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) c_parser_consume_token (parser); if (c_parser_next_token_is (parser, CPP_NAME)) { - set_init_label (c_parser_peek_token (parser)->value, + set_init_label (des_loc, c_parser_peek_token (parser)->value, braced_init_obstack); c_parser_consume_token (parser); } @@ -4240,6 +4241,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) { tree first, second; location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */ + location_t array_index_loc = UNKNOWN_LOCATION; /* ??? Following the old parser, [ objc-receiver objc-message-args ] is accepted as an initializer, being distinguished from a designator by what follows @@ -4317,6 +4319,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) return; } c_parser_consume_token (parser); + array_index_loc = c_parser_peek_token (parser)->location; first = c_parser_expr_no_commas (parser, NULL).value; mark_exp_read (first); array_desig_after_first: @@ -4332,7 +4335,8 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) { c_parser_consume_token (parser); - set_init_index (first, second, braced_init_obstack); + set_init_index (array_index_loc, first, second, + braced_init_obstack); if (second) pedwarn (ellipsis_loc, OPT_Wpedantic, "ISO C forbids specifying range of elements to initialize"); diff --git gcc/c/c-tree.h gcc/c/c-tree.h index a6e7327..ae932fa 100644 --- gcc/c/c-tree.h +++ gcc/c/c-tree.h @@ -606,10 +606,10 @@ 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, struct obstack *); -extern struct c_expr pop_init_level (int, struct obstack *); -extern void set_init_index (tree, tree, struct obstack *); -extern void set_init_label (tree, struct obstack *); +extern void push_init_level (location_t, int, struct obstack *); +extern struct c_expr pop_init_level (location_t, int, struct obstack *); +extern void set_init_index (location_t, tree, tree, struct obstack *); +extern void set_init_label (location_t, tree, struct obstack *); extern void process_init_element (location_t, struct c_expr, bool, struct obstack *); extern tree build_compound_literal (location_t, tree, tree, bool); diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c index 7d2df6b..6798801 100644 --- gcc/c/c-typeck.c +++ gcc/c/c-typeck.c @@ -106,7 +106,7 @@ static tree digest_init (location_t, tree, tree, tree, bool, bool, int); static void output_init_element (location_t, tree, tree, bool, tree, tree, int, bool, struct obstack *); static void output_pending_init_elements (int, struct obstack *); -static int set_designator (int, struct obstack *); +static int set_designator (location_t, int, struct obstack *); static void push_range_stack (tree, struct obstack *); static void add_pending_init (location_t, tree, tree, tree, bool, struct obstack *); @@ -5545,15 +5545,15 @@ convert_to_anonymous_field (location_t location, tree type, tree rhs) The component name is taken from the spelling stack. */ static void -error_init (const char *gmsgid) +error_init (location_t loc, const char *gmsgid) { char *ofwhat; /* The gmsgid may be a format string with %< and %>. */ - error (gmsgid); + error_at (loc, gmsgid); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat) - error ("(near initialization for %qs)", ofwhat); + error_at (loc, "(near initialization for %qs)", ofwhat); } /* Issue a pedantic warning for a bad initializer component. OPT is @@ -6555,7 +6555,8 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, { if (typ2 != char_type_node) { - error_init ("char-array initialized from wide string"); + error_init (init_loc, "char-array initialized from wide " + "string"); return error_mark_node; } } @@ -6563,14 +6564,14 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, { if (typ2 == char_type_node) { - error_init ("wide character array initialized from non-wide " - "string"); + error_init (init_loc, "wide character array initialized " + "from non-wide string"); return error_mark_node; } else if (!comptypes(typ1, typ2)) { - error_init ("wide character array initialized from " - "incompatible wide string"); + error_init (init_loc, "wide character array initialized " + "from incompatible wide string"); return error_mark_node; } } @@ -6603,7 +6604,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, } else if (INTEGRAL_TYPE_P (typ1)) { - error_init ("array of inappropriate type initialized " + error_init (init_loc, "array of inappropriate type initialized " "from string constant"); return error_mark_node; } @@ -6671,7 +6672,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, (init_loc, inside_init); else { - error_init ("invalid use of non-lvalue array"); + error_init (init_loc, "invalid use of non-lvalue array"); return error_mark_node; } } @@ -6697,7 +6698,8 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST && TREE_CODE (inside_init) != CONSTRUCTOR) { - error_init ("array initialized from non-constant array expression"); + error_init (init_loc, "array initialized from non-constant array " + "expression"); return error_mark_node; } @@ -6711,7 +6713,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, = valid_compound_expr_initializer (inside_init, TREE_TYPE (inside_init)); if (inside_init == error_mark_node) - error_init ("initializer element is not constant"); + error_init (init_loc, "initializer element is not constant"); else pedwarn_init (init_loc, OPT_Wpedantic, "initializer element is not constant"); @@ -6722,7 +6724,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, && !initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init))) { - error_init ("initializer element is not constant"); + error_init (init_loc, "initializer element is not constant"); inside_init = error_mark_node; } else if (require_constant && !maybe_const) @@ -6762,14 +6764,15 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, ; else if (require_constant && !TREE_CONSTANT (inside_init)) { - error_init ("initializer element is not constant"); + error_init (init_loc, "initializer element is not constant"); inside_init = error_mark_node; } else if (require_constant && !initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init))) { - error_init ("initializer element is not computable at load time"); + error_init (init_loc, "initializer element is not computable at " + "load time"); inside_init = error_mark_node; } else if (require_constant && !maybe_const) @@ -6783,11 +6786,11 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, if (COMPLETE_TYPE_P (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) { - error_init ("variable-sized object may not be initialized"); + error_init (init_loc, "variable-sized object may not be initialized"); return error_mark_node; } - error_init ("invalid initializer"); + error_init (init_loc, "invalid initializer"); return error_mark_node; } @@ -7165,7 +7168,8 @@ really_start_incremental_init (tree type) IMPLICIT is 1 (or 2 if the push is because of designator list). */ void -push_init_level (int implicit, struct obstack * braced_init_obstack) +push_init_level (location_t loc, int implicit, + struct obstack *braced_init_obstack) { struct constructor_stack *p; tree value = NULL_TREE; @@ -7184,14 +7188,14 @@ push_init_level (int implicit, struct obstack * braced_init_obstack) || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) process_init_element (input_location, - pop_init_level (1, braced_init_obstack), + pop_init_level (loc, 1, braced_init_obstack), true, braced_init_obstack); else if (TREE_CODE (constructor_type) == ARRAY_TYPE && constructor_max_index && tree_int_cst_lt (constructor_max_index, constructor_index)) process_init_element (input_location, - pop_init_level (1, braced_init_obstack), + pop_init_level (loc, 1, braced_init_obstack), true, braced_init_obstack); else break; @@ -7281,7 +7285,7 @@ push_init_level (int implicit, struct obstack * braced_init_obstack) if (constructor_type == 0) { - error_init ("extra brace group at end of initializer"); + error_init (loc, "extra brace group at end of initializer"); constructor_fields = 0; constructor_unfilled_fields = 0; return; @@ -7382,7 +7386,8 @@ push_init_level (int implicit, struct obstack * braced_init_obstack) Otherwise, return a CONSTRUCTOR expression as the value. */ struct c_expr -pop_init_level (int implicit, struct obstack * braced_init_obstack) +pop_init_level (location_t loc, int implicit, + struct obstack *braced_init_obstack) { struct constructor_stack *p; struct c_expr ret; @@ -7396,7 +7401,7 @@ pop_init_level (int implicit, struct obstack * braced_init_obstack) pop any inner levels that didn't have explicit braces. */ while (constructor_stack->implicit) process_init_element (input_location, - pop_init_level (1, braced_init_obstack), + pop_init_level (loc, 1, braced_init_obstack), true, braced_init_obstack); gcc_assert (!constructor_range_stack); } @@ -7423,7 +7428,7 @@ pop_init_level (int implicit, struct obstack * braced_init_obstack) gcc_assert (!TYPE_SIZE (constructor_type)); if (constructor_depth > 2) - error_init ("initialization of flexible array member in a nested context"); + error_init (loc, "initialization of flexible array member in a nested context"); else pedwarn_init (input_location, OPT_Wpedantic, "initialization of a flexible array member"); @@ -7485,12 +7490,12 @@ pop_init_level (int implicit, struct obstack * braced_init_obstack) if (vec_safe_is_empty (constructor_elements)) { if (!constructor_erroneous) - error_init ("empty scalar initializer"); + error_init (loc, "empty scalar initializer"); ret.value = error_mark_node; } else if (vec_safe_length (constructor_elements) != 1) { - error_init ("extra elements in scalar initializer"); + error_init (loc, "extra elements in scalar initializer"); ret.value = (*constructor_elements)[0].value; } else @@ -7553,7 +7558,8 @@ pop_init_level (int implicit, struct obstack * braced_init_obstack) ARRAY argument is nonzero for array ranges. Returns zero for success. */ static int -set_designator (int array, struct obstack * braced_init_obstack) +set_designator (location_t loc, int array, + struct obstack *braced_init_obstack) { tree subtype; enum tree_code subcode; @@ -7576,7 +7582,7 @@ set_designator (int array, struct obstack * braced_init_obstack) braces. */ while (constructor_stack->implicit) process_init_element (input_location, - pop_init_level (1, braced_init_obstack), + pop_init_level (loc, 1, braced_init_obstack), true, braced_init_obstack); constructor_designated = 1; return 0; @@ -7600,17 +7606,17 @@ set_designator (int array, struct obstack * braced_init_obstack) subcode = TREE_CODE (subtype); if (array && subcode != ARRAY_TYPE) { - error_init ("array index in non-array initializer"); + error_init (loc, "array index in non-array initializer"); return 1; } else if (!array && subcode != RECORD_TYPE && subcode != UNION_TYPE) { - error_init ("field name not in record or union initializer"); + error_init (loc, "field name not in record or union initializer"); return 1; } constructor_designated = 1; - push_init_level (2, braced_init_obstack); + push_init_level (loc, 2, braced_init_obstack); return 0; } @@ -7643,10 +7649,10 @@ push_range_stack (tree range_end, struct obstack * braced_init_obstack) of indices, running from FIRST through LAST. */ void -set_init_index (tree first, tree last, +set_init_index (location_t loc, tree first, tree last, struct obstack * braced_init_obstack) { - if (set_designator (1, braced_init_obstack)) + if (set_designator (loc, 1, braced_init_obstack)) return; designator_erroneous = 1; @@ -7654,7 +7660,7 @@ set_init_index (tree first, tree last, if (!INTEGRAL_TYPE_P (TREE_TYPE (first)) || (last && !INTEGRAL_TYPE_P (TREE_TYPE (last)))) { - error_init ("array index in initializer not of integer type"); + error_init (loc, "array index in initializer not of integer type"); return; } @@ -7677,16 +7683,16 @@ set_init_index (tree first, tree last, } if (TREE_CODE (first) != INTEGER_CST) - error_init ("nonconstant array index in initializer"); + error_init (loc, "nonconstant array index in initializer"); else if (last != 0 && TREE_CODE (last) != INTEGER_CST) - error_init ("nonconstant array index in initializer"); + error_init (loc, "nonconstant array index in initializer"); else if (TREE_CODE (constructor_type) != ARRAY_TYPE) - error_init ("array index in non-array initializer"); + error_init (loc, "array index in non-array initializer"); else if (tree_int_cst_sgn (first) == -1) - error_init ("array index in initializer exceeds array bounds"); + error_init (loc, "array index in initializer exceeds array bounds"); else if (constructor_max_index && tree_int_cst_lt (constructor_max_index, first)) - error_init ("array index in initializer exceeds array bounds"); + error_init (loc, "array index in initializer exceeds array bounds"); else { constant_expression_warning (first); @@ -7705,7 +7711,7 @@ set_init_index (tree first, tree last, last = 0; else if (tree_int_cst_lt (last, first)) { - error_init ("empty index range in initializer"); + error_init (loc, "empty index range in initializer"); last = 0; } else @@ -7714,7 +7720,8 @@ set_init_index (tree first, tree last, if (constructor_max_index != 0 && tree_int_cst_lt (constructor_max_index, last)) { - error_init ("array index range in initializer exceeds array bounds"); + error_init (loc, "array index range in initializer exceeds " + "array bounds"); last = 0; } } @@ -7730,11 +7737,12 @@ set_init_index (tree first, tree last, /* Within a struct initializer, specify the next field to be initialized. */ void -set_init_label (tree fieldname, struct obstack * braced_init_obstack) +set_init_label (location_t loc, tree fieldname, + struct obstack *braced_init_obstack) { tree field; - if (set_designator (0, braced_init_obstack)) + if (set_designator (loc, 0, braced_init_obstack)) return; designator_erroneous = 1; @@ -7742,7 +7750,7 @@ set_init_label (tree fieldname, struct obstack * braced_init_obstack) if (TREE_CODE (constructor_type) != RECORD_TYPE && TREE_CODE (constructor_type) != UNION_TYPE) { - error_init ("field name not in record or union initializer"); + error_init (loc, "field name not in record or union initializer"); return; } @@ -7761,7 +7769,7 @@ set_init_label (tree fieldname, struct obstack * braced_init_obstack) field = TREE_CHAIN (field); if (field) { - if (set_designator (0, braced_init_obstack)) + if (set_designator (loc, 0, braced_init_obstack)) return; } } @@ -8261,7 +8269,7 @@ output_init_element (location_t loc, tree value, tree origtype, { if (require_constant_value) { - error_init ("initializer element is not constant"); + error_init (loc, "initializer element is not constant"); value = error_mark_node; } else if (require_constant_elements) @@ -8582,14 +8590,14 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, && integer_zerop (constructor_unfilled_index)) { if (constructor_stack->replacement_value.value) - error_init ("excess elements in char array initializer"); + error_init (loc, "excess elements in char array initializer"); constructor_stack->replacement_value = value; return; } if (constructor_stack->replacement_value.value != 0) { - error_init ("excess elements in struct initializer"); + error_init (loc, "excess elements in struct initializer"); return; } @@ -8605,14 +8613,16 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) - process_init_element (loc, pop_init_level (1, braced_init_obstack), + process_init_element (loc, + pop_init_level (loc, 1, braced_init_obstack), true, braced_init_obstack); else if ((TREE_CODE (constructor_type) == ARRAY_TYPE || TREE_CODE (constructor_type) == VECTOR_TYPE) && constructor_max_index && tree_int_cst_lt (constructor_max_index, constructor_index)) - process_init_element (loc, pop_init_level (1, braced_init_obstack), + process_init_element (loc, + pop_init_level (loc, 1, braced_init_obstack), true, braced_init_obstack); else break; @@ -8649,8 +8659,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, if (constructor_fields == 0) { - pedwarn_init (input_location, 0, - "excess elements in struct initializer"); + pedwarn_init (loc, 0, "excess elements in struct initializer"); break; } @@ -8665,7 +8674,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, && TYPE_SIZE (fieldtype) == NULL_TREE && DECL_CHAIN (constructor_fields) == NULL_TREE) { - error_init ("non-static initialization of a flexible array member"); + error_init (loc, "non-static initialization of a flexible " + "array member"); break; } @@ -8683,7 +8693,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE)) { - push_init_level (1, braced_init_obstack); + push_init_level (loc, 1, braced_init_obstack); continue; } @@ -8775,7 +8785,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE)) { - push_init_level (1, braced_init_obstack); + push_init_level (loc, 1, braced_init_obstack); continue; } @@ -8817,7 +8827,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE || eltcode == UNION_TYPE || eltcode == VECTOR_TYPE)) { - push_init_level (1, braced_init_obstack); + push_init_level (loc, 1, braced_init_obstack); continue; } @@ -8918,7 +8928,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, { gcc_assert (constructor_stack->implicit); process_init_element (loc, - pop_init_level (1, braced_init_obstack), + pop_init_level (loc, 1, + braced_init_obstack), true, braced_init_obstack); } for (p = range_stack; @@ -8927,7 +8938,8 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, { gcc_assert (constructor_stack->implicit); process_init_element (loc, - pop_init_level (1, braced_init_obstack), + pop_init_level (loc, 1, + braced_init_obstack), true, braced_init_obstack); } @@ -8948,7 +8960,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, p = p->next; if (!p) break; - push_init_level (2, braced_init_obstack); + push_init_level (loc, 2, braced_init_obstack); p->stack = constructor_stack; if (p->range_end && tree_int_cst_equal (p->index, p->range_end)) p->index = p->range_start; diff --git gcc/testsuite/gcc.dg/pr61096-1.c gcc/testsuite/gcc.dg/pr61096-1.c index e69de29..3f7d60c 100644 --- gcc/testsuite/gcc.dg/pr61096-1.c +++ gcc/testsuite/gcc.dg/pr61096-1.c @@ -0,0 +1,61 @@ +/* PR c/61077 */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -fshort-enums -fshort-wchar -Wpedantic" } */ +/* { dg-prune-output ".*near initialization for.*" } */ + +typedef enum { A } schar; +extern int e; +struct S +{ + int a[3]; +}; +struct f +{ + int w; + int x[]; +}; +struct g +{ + struct f f; /* { dg-warning "invalid use of structure with flexible array member" } */ +}; + +char w1[] = L"foo"; /* { dg-error "13:char-array initialized from wide string" } */ +__WCHAR_TYPE__ w2[] = "foo"; /* { dg-error "23:wide character array initialized from non-wide string" } */ +__WCHAR_TYPE__ w3[] = U"foo"; /* { dg-error "23:wide character array initialized from incompatible wide string" } */ +schar a1[] = "foo"; /* { dg-error "14:array of inappropriate type initialized from string constant" } */ +int a2[] = (int[]) { 1 }; /* { dg-error "12:array initialized from non-constant array expression" } */ + +int a3 = e; /* { dg-error "10:initializer element is not constant" } */ +int a4 = (e, 1); /* { dg-error "10:initializer element is not constant" } */ +int a5 = a1[0]; /* { dg-error "10:initializer element is not constant" } */ +int a6 = &a3 - &a4; /* { dg-error "10:initializer element is not" } */ +int a7[] = a7; /* { dg-error "12:invalid initializer" } */ + +struct S s = { { 1 }, { 3 } }; /* { dg-error "23:extra brace group at end of initializer" } */ +/* { dg-warning "23:excess elements in struct initializer" "" { target *-*-* } 34 } */ +struct g g1 = { {0, { 1 } } }; /* { dg-error "21:initialization of flexible array member in a nested context" } */ +struct g g2 = { .f[0] = 1 }; /* { dg-error "20:array index in non-array initializer" } */ + +__extension__ int a8 = { }; /* { dg-error "24:empty scalar initializer" } */ +int a9[10] = {[1.2] = 2 }; /* { dg-error "16:array index in initializer not of integer type" } */ +int a10[10] = {[e] = 2 }; /* { dg-error "17:nonconstant array index in initializer" } */ +__extension__ int a11[10] = {[1 ... e] = 1 }; /* { dg-error "31:nonconstant array index in initializer" } */ +int a12 = {[1] = 2 }; /* { dg-error "13:array index in non-array initializer" } */ +int a13[2] = {[-1] = 4 }; /* { dg-error "16:array index in initializer exceeds array bounds" } */ +int a14[2] = {[64] = 4 }; /* { dg-error "16:array index in initializer exceeds array bounds" } */ +__extension__ int a15[10] = {[2 ... 1] = 4 }; /* { dg-error "31:empty index range in initializer" } */ +__extension__ int a16[10] = {[2 ... 100] = 4 }; /* { dg-error "31:array index range in initializer exceeds array bounds" } */ +int a17[] = { .B = 1 }; /* { dg-error "15:field name not in record or union initializer" } */ +int a18[] = { e }; /* { dg-error "15:initializer element is not constant" } */ +char a19[1] = { "x", "x" }; /* { dg-error "22:excess elements in char array initializer" } */ + +void +bar (void) +{ + struct f f = { 2, "c" }; /* { dg-error "21:non-static initialization of a flexible array member" } */ +} + +struct +{ + char *v; +} sx[] = { .v = 0 }; /* { dg-error "12:field name not in record or union initializer" } */ diff --git gcc/testsuite/gcc.dg/pr61096-2.c gcc/testsuite/gcc.dg/pr61096-2.c index e69de29..fbea4d9 100644 --- gcc/testsuite/gcc.dg/pr61096-2.c +++ gcc/testsuite/gcc.dg/pr61096-2.c @@ -0,0 +1,10 @@ +/* PR c/61077 */ +/* { dg-do compile } */ + +struct s { char c[1]; }; +extern struct s foo (void); +void +bar (void) +{ + char *t = (foo ()).c; /* { dg-error "13:invalid use of non-lvalue array" } */ +}