From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) by sourceware.org (Postfix) with ESMTPS id 5A0C93858D32 for ; Tue, 11 Apr 2023 19:01:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5A0C93858D32 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pg1-x529.google.com with SMTP id 185so18527717pgc.10 for ; Tue, 11 Apr 2023 12:01:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1681239682; x=1683831682; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=mjs7JbmEI2UXJ5t4vMfmd/OTIT46Qsu8WHPxJk7VRBQ=; b=MHaiyB2hEXRM7SSHUCe2EdS/kU6kYvnbJ5OylAK60we5VqaCt1GPGtsd8NkKUQMdhf OqcD56i05klc6VbOI0u5L9u97ZPkgpDqqVNk09KnlYU8OOAc+1eSDLbiTmvTrGI/GYY1 4xnq/7oBJY0txIh95Nct1uSfSwknI3SnIXJ/oRqV23zPARo4GXSzU6s8F59AJi+goz/y /v5YbzehxyhKIU9xurVSdM8hUJR8Uqyx7xdKuvVOQ8rivWNSCrbZLL7xSmXFHTu7Rvf3 1Kwi5y6Rn/KCGOqLowXdZB7w3SJsl27NZgvq2Y8HGJn7FIz4kS38f6oU6Oe0ec2EZTw9 sexQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681239682; x=1683831682; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mjs7JbmEI2UXJ5t4vMfmd/OTIT46Qsu8WHPxJk7VRBQ=; b=wGtyvtfIEGFhNj3op2umUWaDPTzBcmSEBEF/9lgqP1D58LJHnatt1g88A83G7pwnbW cxa3loxVgLrOvobHciWSxZ9DEdURHLdveeJH8VM/mcVVJirSFni1u7EakN2UHrZpnBwX YJvdcap96sFW1zlp+IFAllpmyuxZcIqXRPAusF/tQ9LBF7cJOrDIofo3zEJWq4A4yhKP 43fMrsJAs+3BjaV5iJ18Z9epnxrt6MOmOX5A8U2PwooVZS4+mBv06lahl/t/YBWviRuL KVxM1sMkLdoHLOL77gPdPLP/GLi+r1e3cnIWLDcmwwX9quwO6NDqPMAjpsO0DXs2HYjU 2AXw== X-Gm-Message-State: AAQBX9fIANqKEr48qX4mlBxLXzuOfVwRp+u+qtiUWRQLnears3YsHp1M mPxvg02pCU89Anaf4bYMkV6TzLbSZbbOp14wtsb6n+hB6V0= X-Google-Smtp-Source: AKy350YxGOtVZLsrZfjmoQyEamq59qY+bOFuszai8Yl8Z2nrkyHCKnrvd08Hofj97U7AWGuxSMxhbmVAvn85LpCtTx4= X-Received: by 2002:a65:6093:0:b0:4f1:cd3a:3e83 with SMTP id t19-20020a656093000000b004f1cd3a3e83mr71038pgu.3.1681239681785; Tue, 11 Apr 2023 12:01:21 -0700 (PDT) MIME-Version: 1.0 References: <82efe5297d61e4937eae0b1aca8eae5a97da04e3.camel@gmail.com> In-Reply-To: <82efe5297d61e4937eae0b1aca8eae5a97da04e3.camel@gmail.com> From: Andrew Pinski Date: Tue, 11 Apr 2023 12:01:09 -0700 Message-ID: Subject: Re: Fix ICEs related to VM types in C [PR106465, PR107557, PR108424, PR109450] To: Martin Uecker Cc: gcc-patches@gcc.gnu.org, richard.guenther@gmail.com, joseph@codesourcery.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Tue, Apr 11, 2023 at 11:47=E2=80=AFAM Martin Uecker via Gcc-patches wrote: > > > > Ok, here is another attempt on fixing issues with size expression. > Not all are regressions, but it does not make sense to try to split > it up. They might be regressions still from pre gimple (3.4 and before), though I wonder how much value considering something which didn't work in GCC 4.0+ these days as a regression. Also splitting them up if possible is always welcomed to be able to review each thing separately. Thanks, Andrew > > Martin > > > > Fix ICEs related to VM types in C [PR106465, PR107557, PR108424, = PR109450] > > Size expressions were sometimes lost and not gimplified correctly= , leading to > ICEs and incorrect evaluation order. Fix this by 1) not recursin= g into > pointers when gimplifying parameters in the middle-end (the code = is merged with > gimplify_type_sizes), which is incorrect because it might access = variables > declared later for incomplete structs, and 2) tracking size expre= ssions for > struct/union members correctly, 3) emitting code to evaluate size= expressions > for missing cases (nested functions, empty declarations, and stru= cts/unions). > > PR c/106465 > PR c/107557 > PR c/108423 > PR c/109450 > > gcc/ > * c/c-decl.cc (start_decl): Make sure size expression are > evaluated only in correct context. > (grokdeclarator): Size expression in fields may need a bind > expression, make sure DECL_EXPR is always created. > (grokfield, declspecs_add_type): Pass along size expressions. > (finish_struct): Remove unneeded DECL_EXPR. > (start_function): Evaluate size expressions for nested functions. > * c/c-parser.cc (c_parser_struct_declarations, > c_parser_struct_or_union_specifier): Pass along size expressions. > (c_parser_declaration_or_fndef): Evaluate size expression. > (c_parser_objc_at_property_declaration, > c_parser_objc_class_instance_variables): Adapt. > * function.cc (gimplify_parm_type): Remove function. > (gimplify_parameters): Call gimplify_parm_sizes. > * gimplify.cc (gimplify_type_sizes): Make function static. > (gimplify_parm_sizes): New function. > > gcc/testsuite/ > * gcc.dg/nested-vla-1.c: New test. > * gcc.dg/nested-vla-2.c: New test. > * gcc.dg/nested-vla-3.c: New test. > * gcc.dg/pr106465.c: New test. > * gcc.dg/pr107557-1.c: New test. > * gcc.dg/pr107557-2.c: New test. > * gcc.dg/pr108423-1.c: New test. > * gcc.dg/pr108423-2.c: New test. > * gcc.dg/pr108423-3.c: New test. > * gcc.dg/pr108423-4.c: New test. > * gcc.dg/pr108423-5.c: New test. > * gcc.dg/pr108423-6.c: New test. > * gcc.dg/pr109450-1.c: New test. > * gcc.dg/pr109450-2.c: New test. > * gcc.dg/typename-vla-2.c: New test. > * gcc.dg/typename-vla-3.c: New test. > * gcc.dg/typename-vla-4.c: New test. > * gcc.misc-tests/gcov-pr85350.c: Adapt. > > diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc > index e537d33f398..c76cbb3115f 100644 > --- a/gcc/c/c-decl.cc > +++ b/gcc/c/c-decl.cc > @@ -5371,7 +5371,8 @@ start_decl (struct c_declarator *declarator, struct= c_declspecs *declspecs, > if (lastdecl !=3D error_mark_node) > *lastloc =3D DECL_SOURCE_LOCATION (lastdecl); > > - if (expr) > + /* Make sure the size expression is evaluated at this point. */ > + if (expr && !current_scope->parm_flag) > add_stmt (fold_convert (void_type_node, expr)); > > if (TREE_CODE (decl) !=3D FUNCTION_DECL && MAIN_NAME_P (DECL_NAME (dec= l)) > @@ -7500,7 +7501,8 @@ grokdeclarator (const struct c_declarator *declarat= or, > && c_type_variably_modified_p (type)) > { > tree bind =3D NULL_TREE; > - if (decl_context =3D=3D TYPENAME || decl_context =3D=3D P= ARM) > + if (decl_context =3D=3D TYPENAME || decl_context =3D=3D P= ARM > + || decl_context =3D=3D FIELD) > { > bind =3D build3 (BIND_EXPR, void_type_node, NULL_TREE= , > NULL_TREE, NULL_TREE); > @@ -7509,10 +7511,9 @@ grokdeclarator (const struct c_declarator *declara= tor, > push_scope (); > } > tree decl =3D build_decl (loc, TYPE_DECL, NULL_TREE, type= ); > - DECL_ARTIFICIAL (decl) =3D 1; > - pushdecl (decl); > - finish_decl (decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); > + add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_E= XPR, decl)); > TYPE_NAME (type) =3D decl; > + > if (bind) > { > pop_scope (); > @@ -8711,7 +8712,7 @@ start_struct (location_t loc, enum tree_code code, = tree name, > tree > grokfield (location_t loc, > struct c_declarator *declarator, struct c_declspecs *declspecs= , > - tree width, tree *decl_attrs) > + tree width, tree *decl_attrs, tree *expr) > { > tree value; > > @@ -8768,7 +8769,7 @@ grokfield (location_t loc, > } > > value =3D grokdeclarator (declarator, declspecs, FIELD, false, > - width ? &width : NULL, decl_attrs, NULL, NULL, > + width ? &width : NULL, decl_attrs, expr, NULL, > DEPRECATED_NORMAL); > > finish_decl (value, loc, NULL_TREE, NULL_TREE, NULL_TREE); > @@ -9426,13 +9427,6 @@ finish_struct (location_t loc, tree t, tree fieldl= ist, tree attributes, > > finish_incomplete_vars (incomplete_vars, toplevel); > > - /* If we're inside a function proper, i.e. not file-scope and not stil= l > - parsing parameters, then arrange for the size of a variable sized t= ype > - to be bound now. */ > - if (building_stmt_list_p () && c_type_variably_modified_p(t)) > - add_stmt (build_stmt (loc, > - DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)= )); > - > if (warn_cxx_compat) > warn_cxx_compat_finish_struct (fieldlist, TREE_CODE (t), loc); > > @@ -10058,6 +10052,7 @@ start_function (struct c_declspecs *declspecs, st= ruct c_declarator *declarator, > tree restype, resdecl; > location_t loc; > location_t result_loc; > + tree expr =3D NULL; > > current_function_returns_value =3D 0; /* Assume, until we see it does= . */ > current_function_returns_null =3D 0; > @@ -10069,7 +10064,7 @@ start_function (struct c_declspecs *declspecs, st= ruct c_declarator *declarator, > in_statement =3D 0; > > decl1 =3D grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL, > - &attributes, NULL, NULL, DEPRECATED_NORMAL); > + &attributes, &expr, NULL, DEPRECATED_NORMAL); > invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1); > > /* If the declarator is not suitable for a function definition, > @@ -10078,6 +10073,11 @@ start_function (struct c_declspecs *declspecs, s= truct c_declarator *declarator, > || TREE_CODE (decl1) !=3D FUNCTION_DECL) > return false; > > + /* Nested functions may have variably modified (return) type. > + Make sure the size expression is evaluated at this point. */ > + if (expr && !current_scope->parm_flag) > + add_stmt (fold_convert (void_type_node, expr)); > + > loc =3D DECL_SOURCE_LOCATION (decl1); > > /* A nested function is not global. */ > @@ -12282,10 +12282,13 @@ declspecs_add_type (location_t loc, struct c_de= clspecs *specs, > } > else > { > - if (TREE_CODE (type) !=3D ERROR_MARK && spec.kind =3D=3D ctsk_type= of) > + if (TREE_CODE (type) !=3D ERROR_MARK) > { > - specs->typedef_p =3D true; > - specs->locations[cdw_typedef] =3D loc; > + if (spec.kind =3D=3D ctsk_typeof) > + { > + specs->typedef_p =3D true; > + specs->locations[cdw_typedef] =3D loc; > + } > if (spec.expr) > { > if (specs->expr) > diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc > index 21bc3167ce2..6008ca78c07 100644 > --- a/gcc/c/c-parser.cc > +++ b/gcc/c/c-parser.cc > @@ -1541,7 +1541,7 @@ static void c_parser_static_assert_declaration_no_s= emi (c_parser *); > static void c_parser_static_assert_declaration (c_parser *); > static struct c_typespec c_parser_enum_specifier (c_parser *); > static struct c_typespec c_parser_struct_or_union_specifier (c_parser *)= ; > -static tree c_parser_struct_declaration (c_parser *); > +static tree c_parser_struct_declaration (c_parser *, tree *); > static struct c_typespec c_parser_typeof_specifier (c_parser *); > static tree c_parser_alignas_specifier (c_parser *); > static struct c_declarator *c_parser_direct_declarator (c_parser *, bool= , > @@ -2263,6 +2263,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bo= ol fndef_ok, > if (!handled_assume) > pedwarn (here, 0, "empty declaration"); > } > + /* we still have to evaluate size expressions */ > + if (specs->expr) > + add_stmt (fold_convert (void_type_node, specs->expr)); > c_parser_consume_token (parser); > if (oacc_routine_data) > c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false); > @@ -3782,6 +3785,7 @@ c_parser_struct_or_union_specifier (c_parser *parse= r) > so we'll be minimizing the number of node traversals required > by chainon. */ > tree contents; > + tree expr =3D NULL; > timevar_push (TV_PARSE_STRUCT); > contents =3D NULL_TREE; > c_parser_consume_token (parser); > @@ -3843,7 +3847,7 @@ c_parser_struct_or_union_specifier (c_parser *parse= r) > } > /* Parse some comma-separated declarations, but not the > trailing semicolon if any. */ > - decls =3D c_parser_struct_declaration (parser); > + decls =3D c_parser_struct_declaration (parser, &expr); > contents =3D chainon (decls, contents); > /* If no semicolon follows, either we have a parse error or > are at the end of the struct or union and should > @@ -3874,7 +3878,7 @@ c_parser_struct_or_union_specifier (c_parser *parse= r) > chainon (attrs, postfix_attrs)), > struct_info); > ret.kind =3D ctsk_tagdef; > - ret.expr =3D NULL_TREE; > + ret.expr =3D expr; > ret.expr_const_operands =3D true; > ret.has_enum_type_specifier =3D false; > timevar_pop (TV_PARSE_STRUCT); > @@ -3936,7 +3940,7 @@ c_parser_struct_or_union_specifier (c_parser *parse= r) > expressions will be diagnosed as non-constant. */ > > static tree > -c_parser_struct_declaration (c_parser *parser) > +c_parser_struct_declaration (c_parser *parser, tree *expr) > { > struct c_declspecs *specs; > tree prefix_attrs; > @@ -3949,7 +3953,7 @@ c_parser_struct_declaration (c_parser *parser) > tree decl; > ext =3D disable_extension_diagnostics (); > c_parser_consume_token (parser); > - decl =3D c_parser_struct_declaration (parser); > + decl =3D c_parser_struct_declaration (parser, expr); > restore_extension_diagnostics (ext); > return decl; > } > @@ -3995,7 +3999,7 @@ c_parser_struct_declaration (c_parser *parser) > > ret =3D grokfield (c_parser_peek_token (parser)->location, > build_id_declarator (NULL_TREE), specs, > - NULL_TREE, &attrs); > + NULL_TREE, &attrs, expr); > if (ret) > decl_attributes (&ret, attrs, 0); > } > @@ -4056,7 +4060,7 @@ c_parser_struct_declaration (c_parser *parser) > if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) > postfix_attrs =3D c_parser_gnu_attributes (parser); > d =3D grokfield (c_parser_peek_token (parser)->location, > - declarator, specs, width, &all_prefix_attrs); > + declarator, specs, width, &all_prefix_attrs, exp= r); > decl_attributes (&d, chainon (postfix_attrs, > all_prefix_attrs), 0); > DECL_CHAIN (d) =3D decls; > @@ -11729,7 +11733,7 @@ c_parser_objc_class_instance_variables (c_parser = *parser) > } > > /* Parse some comma-separated declarations. */ > - decls =3D c_parser_struct_declaration (parser); > + decls =3D c_parser_struct_declaration (parser, NULL); > if (decls =3D=3D NULL) > { > /* There is a syntax error. We want to skip the offending > @@ -12868,7 +12872,7 @@ c_parser_objc_at_property_declaration (c_parser *= parser) > /* 'properties' is the list of properties that we read. Usually a > single one, but maybe more (eg, in "@property int a, b, c;" there > are three). */ > - tree properties =3D c_parser_struct_declaration (parser); > + tree properties =3D c_parser_struct_declaration (parser, NULL); > > if (properties =3D=3D error_mark_node) > c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); > diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h > index e6b6fe9a40e..7c5234e80fd 100644 > --- a/gcc/c/c-tree.h > +++ b/gcc/c/c-tree.h > @@ -656,7 +656,7 @@ extern tree c_simulate_record_decl (location_t, const= char *, > extern struct c_arg_info *build_arg_info (void); > extern struct c_arg_info *get_parm_info (bool, tree); > extern tree grokfield (location_t, struct c_declarator *, > - struct c_declspecs *, tree, tree *); > + struct c_declspecs *, tree, tree *, tree *); > extern tree groktypename (struct c_type_name *, tree *, bool *); > extern tree grokparm (const struct c_parm *, tree *); > extern tree implicitly_declare (location_t, tree); > diff --git a/gcc/function.cc b/gcc/function.cc > index edf0b2ec6cf..e50d9601509 100644 > --- a/gcc/function.cc > +++ b/gcc/function.cc > @@ -3873,30 +3873,6 @@ assign_parms (tree fndecl) > } > } > > -/* A subroutine of gimplify_parameters, invoked via walk_tree. > - For all seen types, gimplify their sizes. */ > - > -static tree > -gimplify_parm_type (tree *tp, int *walk_subtrees, void *data) > -{ > - tree t =3D *tp; > - > - *walk_subtrees =3D 0; > - if (TYPE_P (t)) > - { > - if (POINTER_TYPE_P (t)) > - *walk_subtrees =3D 1; > - else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t)) > - && !TYPE_SIZES_GIMPLIFIED (t)) > - { > - gimplify_type_sizes (t, (gimple_seq *) data); > - *walk_subtrees =3D 1; > - } > - } > - > - return NULL; > -} > - > /* Gimplify the parameter list for current_function_decl. This involves > evaluating SAVE_EXPRs of variable sized parameters and generating cod= e > to implement callee-copies reference parameters. Returns a sequence = of > @@ -3932,14 +3908,7 @@ gimplify_parameters (gimple_seq *cleanup) > SAVE_EXPRs (amongst others) onto a pending sizes list. This > turned out to be less than manageable in the gimple world. > Now we have to hunt them down ourselves. */ > - walk_tree_without_duplicates (&data.arg.type, > - gimplify_parm_type, &stmts); > - > - if (TREE_CODE (DECL_SIZE_UNIT (parm)) !=3D INTEGER_CST) > - { > - gimplify_one_sizepos (&DECL_SIZE (parm), &stmts); > - gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), &stmts); > - } > + gimplify_parm_sizes (parm, &stmts); > > if (data.arg.pass_by_reference) > { > diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc > index ade6e335da7..a220886d973 100644 > --- a/gcc/gimplify.cc > +++ b/gcc/gimplify.cc > @@ -242,6 +242,7 @@ static struct gimplify_omp_ctx *gimplify_omp_ctxp; > static bool in_omp_construct; > > /* Forward declaration. */ > +static void gimplify_type_sizes (tree type, gimple_seq *list_p); > static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *= , bool); > static hash_map *oacc_declare_returns; > static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_= seq *, > @@ -17448,7 +17449,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, g= imple_seq *post_p, > /* Look through TYPE for variable-sized objects and gimplify each such > size that we find. Add to LIST_P any statements generated. */ > > -void > +static void > gimplify_type_sizes (tree type, gimple_seq *list_p) > { > if (type =3D=3D NULL || type =3D=3D error_mark_node) > @@ -17556,6 +17557,21 @@ gimplify_type_sizes (tree type, gimple_seq *list= _p) > } > } > > +/* Gimplify sizes in parameter declarations. */ > + > +void > +gimplify_parm_sizes (tree parm, gimple_seq *list_p) > +{ > + gimplify_type_sizes (TREE_TYPE (parm), list_p); > + > + if (TREE_CODE (DECL_SIZE_UNIT (parm)) !=3D INTEGER_CST) > + { > + gimplify_one_sizepos (&DECL_SIZE (parm), list_p); > + gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), list_p); > + } > +} > + > + > /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P, > a size or position, has had all of its SAVE_EXPRs evaluated. > We add any required statements to *STMT_P. */ > diff --git a/gcc/gimplify.h b/gcc/gimplify.h > index f4a3eea2606..17ea0580647 100644 > --- a/gcc/gimplify.h > +++ b/gcc/gimplify.h > @@ -78,7 +78,7 @@ extern enum gimplify_status gimplify_expr (tree *, gimp= le_seq *, gimple_seq *, > > int omp_construct_selector_matches (enum tree_code *, int, int *); > > -extern void gimplify_type_sizes (tree, gimple_seq *); > +extern void gimplify_parm_sizes (tree, gimple_seq *); > extern void gimplify_one_sizepos (tree *, gimple_seq *); > extern gbind *gimplify_body (tree, bool); > extern enum gimplify_status gimplify_arg (tree *, gimple_seq *, location= _t, > diff --git a/gcc/testsuite/gcc.dg/nested-vla-1.c b/gcc/testsuite/gcc.dg/n= ested-vla-1.c > new file mode 100644 > index 00000000000..408a68524d8 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/nested-vla-1.c > @@ -0,0 +1,37 @@ > +/* { dg-do run } */ > +/* { dg-options "-std=3Dgnu99" } */ > + > + > +int main() > +{ > + int n =3D 1; > + > + struct foo { char x[++n]; } bar(void) { } > + > + if (2 !=3D n) > + __builtin_abort(); > + > + if (2 !=3D sizeof(bar())) > + __builtin_abort(); > + > + n =3D 1; > + > + struct bar { char x[++n]; } (*bar2)(void) =3D bar; /* { dg= -warning "incompatible pointer type" } */ > + > + if (2 !=3D n) > + __builtin_abort(); > + > + if (2 !=3D sizeof((*bar2)())) > + __builtin_abort(); > + > + n =3D 1; > + > + struct { char x[++n]; } *bar3(void) { } > + > + if (2 !=3D n) > + __builtin_abort(); > + > + if (2 !=3D sizeof(*bar3())) > + __builtin_abort(); > +} > + > diff --git a/gcc/testsuite/gcc.dg/nested-vla-2.c b/gcc/testsuite/gcc.dg/n= ested-vla-2.c > new file mode 100644 > index 00000000000..504eec48c80 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/nested-vla-2.c > @@ -0,0 +1,33 @@ > +/* { dg-do run } */ > +/* { dg-options "-std=3Dgnu99" } */ > + > + > +int main() > +{ > + int n =3D 1; > + > + typeof(char (*)[++n]) bar(void) { } > + > + if (2 !=3D n) > + __builtin_abort(); > + > + if (2 !=3D sizeof(*bar())) > + __builtin_abort(); > + > + if (2 !=3D n) > + __builtin_abort(); > + > + n =3D 1; > + > + typeof(char (*)[++n]) (*bar2)(void) =3D bar; > + > + if (2 !=3D n) > + __builtin_abort(); > + > + if (2 !=3D sizeof(*(*bar2)())) > + __builtin_abort(); > + > + if (2 !=3D n) > + __builtin_abort(); > +} > + > diff --git a/gcc/testsuite/gcc.dg/nested-vla-3.c b/gcc/testsuite/gcc.dg/n= ested-vla-3.c > new file mode 100644 > index 00000000000..e0e70b651ca > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/nested-vla-3.c > @@ -0,0 +1,28 @@ > +/* { dg-do run } */ > +/* { dg-options "-std=3Dgnu99" } */ > + > + > +int main() > +{ > + int n =3D 1; > + > + char (*bar(void))[++n] { } > + > + if (2 !=3D n) > + __builtin_abort(); > + > + if (2 !=3D sizeof(*bar())) > + __builtin_abort(); > + > + n =3D 1; > + > + char (*(*bar2)(void))[++n] =3D bar; > + > + if (2 !=3D n) > + __builtin_abort(); > + > + if (2 !=3D sizeof(*(*bar2)())) > + __builtin_abort(); > + > +} > + > diff --git a/gcc/testsuite/gcc.dg/pr106465.c b/gcc/testsuite/gcc.dg/pr106= 465.c > new file mode 100644 > index 00000000000..b03e2442f12 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr106465.c > @@ -0,0 +1,86 @@ > +/* PR c/106465 > + * { dg-do run } > + * { dg-options "-std=3Dgnu99" } > + * */ > + > +int main() > +{ > + int n =3D 3; > + > + void g1(int m, struct { char p[++m]; }* b) /* { dg-warning "= anonymous struct" } */ > + { > + if (3 !=3D m) > + __builtin_abort(); > + > + if (3 !=3D sizeof(b->p)) > + __builtin_abort(); > + } > + > + void g2(struct { char p[++n]; }* b) /* { dg-warning "anonymou= s struct" } */ > + { > + if (4 !=3D n) > + __builtin_abort(); > + > + if (4 !=3D sizeof(b->p)) > + __builtin_abort(); > + } > + > + void g2b(struct { char (*p)[++n]; }* b) /* { dg-warning "anonymou= s struct" } */ > + { > + if (5 !=3D n) > + __builtin_abort(); > + > + if (5 !=3D sizeof(*b->p)) > + __builtin_abort(); > + } > + > + if (3 !=3D n) > + __builtin_abort(); > + > + g1(2, (void*)0); > + g2((void*)0); > + g2b((void*)0); > + n--; > + > + if (4 !=3D n) > + __builtin_abort(); > + > + struct foo { char (*p)[++n]; } x; > + > + if (5 !=3D n) > + __builtin_abort(); > + > + struct bar { char (*p)[++n]; }; > + > + if (6 !=3D n) > + __builtin_abort(); > + > + auto struct z { char (*p)[++n]; } g3(void); > + > + if (7 !=3D n) > + __builtin_abort(); > + > + struct z g3(void) { }; > + > + if (7 !=3D n) > + __builtin_abort(); > + > + struct { char (*p)[++n]; } g4(void) { }; > + > + if (8 !=3D n) > + __builtin_abort(); > + > + __auto_type u =3D g3(); > + > + if (8 !=3D n) > + __builtin_abort(); > + > + if (5 !=3D sizeof *x.p) > + __builtin_abort(); > + > + if (7 !=3D sizeof *u.p) > + __builtin_abort(); > + > + return 0; > +} > + > diff --git a/gcc/testsuite/gcc.dg/pr107557-1.c b/gcc/testsuite/gcc.dg/pr1= 07557-1.c > new file mode 100644 > index 00000000000..88c248b6564 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr107557-1.c > @@ -0,0 +1,24 @@ > +/* PR107557 > + * { dg-do compile } > + * { dg-options "-flto -fsanitize=3Dundefined -fexceptions -Wno-incompat= ible-pointer-types" } > + */ > + > + > +int c[1][3*2]; > +int f(int * const m, int (**v)[*m * 2]) > +{ > + return &(c[0][*m]) =3D=3D &((*v)[0][*m]); > +} > +int test(int n, int (*(*fn)(void))[n]) > +{ > + return (*fn())[0]; > +} > +int main() > +{ > + int m =3D 3; > + int (*d)[3*2] =3D c; > + int (*fn[m])(void); > + return f(&m, &d) + test(m, &fn); > +} > + > + > diff --git a/gcc/testsuite/gcc.dg/pr107557-2.c b/gcc/testsuite/gcc.dg/pr1= 07557-2.c > new file mode 100644 > index 00000000000..2d26bb0b16a > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr107557-2.c > @@ -0,0 +1,23 @@ > +/* PR107557 > + * { dg-do compile } > + * { dg-options "-flto -fsanitize=3Dundefined -fexceptions -Wno-incompat= ible-pointer-types" } > + */ > + > + > +int c[1][3*2]; > +int f(int * const m, int (**(*v))[*m * 2]) > +{ > + return &(c[0][*m]) =3D=3D &((*v)[0][*m]); /* { dg-warning "lack= s a cast" } */ > +} > +int test(int n, int (*(*(*fn))(void))[n]) > +{ > + return (*(*fn)())[0]; > +} > +int main() > +{ > + int m =3D 3; > + int (*d)[3*2] =3D c; > + int (*fn[m])(void); > + return f(&m, &d) + test(m, &fn); > +} > + > diff --git a/gcc/testsuite/gcc.dg/pr108423-1.c b/gcc/testsuite/gcc.dg/pr1= 08423-1.c > new file mode 100644 > index 00000000000..0c98d1d46b9 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr108423-1.c > @@ -0,0 +1,16 @@ > +/* PR108423 > + * { dg-do compile } > + * { dg-options "-O2 -Wno-int-conversion -Wno-incompatible-pointer-types= " } > + */ > +int f (int n, int (**(*a)(void))[n]) > +{ > + return (*a())[0]; > +} > +int g () > +{ > + int m =3D 3; > + int (*a[m])(void); > + return f(m, &a); > +} > + > + > diff --git a/gcc/testsuite/gcc.dg/pr108423-2.c b/gcc/testsuite/gcc.dg/pr1= 08423-2.c > new file mode 100644 > index 00000000000..006e45a9629 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr108423-2.c > @@ -0,0 +1,16 @@ > +/* PR108423 > + * { dg-do compile } > + * { dg-options "-O2" } > + */ > + > +void f(int n, int (*a(void))[n]) > +{ > + (a())[0]; > +} > + > +void g(void) > +{ > + int (*a(void))[1]; > + f(1, a); > +} > + > diff --git a/gcc/testsuite/gcc.dg/pr108423-3.c b/gcc/testsuite/gcc.dg/pr1= 08423-3.c > new file mode 100644 > index 00000000000..c1987c42b40 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr108423-3.c > @@ -0,0 +1,17 @@ > +/* PR108423 > + * { dg-do compile } > + * { dg-options "-O2" } > + */ > + > +void f(int n, int (*(*b)(void))[n]) > +{ > + sizeof (*(*b)()); > +} > + > +int (*a(void))[1]; > + > +void g(void) > +{ > + f(1, &a); > +} > + > diff --git a/gcc/testsuite/gcc.dg/pr108423-4.c b/gcc/testsuite/gcc.dg/pr1= 08423-4.c > new file mode 100644 > index 00000000000..91336f3f283 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr108423-4.c > @@ -0,0 +1,17 @@ > +/* PR108423 > + * { dg-do compile } > + * { dg-options "-O2" } > + */ > + > +void f(int n, int (*a(void))[n]) > +{ > + sizeof (*a()); > +} > + > +int (*a(void))[1]; > + > +void g(void) > +{ > + f(1, a); > +} > + > diff --git a/gcc/testsuite/gcc.dg/pr108423-5.c b/gcc/testsuite/gcc.dg/pr1= 08423-5.c > new file mode 100644 > index 00000000000..7e4fffb2870 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr108423-5.c > @@ -0,0 +1,17 @@ > +/* PR108423 > + * { dg-do compile } > + * { dg-options "-O2" } > + */ > + > +void f(int n, int (*(*a)(void))[n]) > +{ > + sizeof ((*a)()); > +} > + > +int (*a(void))[1]; > + > +void g(void) > +{ > + f(1, a); > +} > + > diff --git a/gcc/testsuite/gcc.dg/pr108423-6.c b/gcc/testsuite/gcc.dg/pr1= 08423-6.c > new file mode 100644 > index 00000000000..c36e45aaf45 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr108423-6.c > @@ -0,0 +1,16 @@ > +/* PR108423 > + * { dg-do compile } > + * { dg-options "-O2" } > + */ > + > +void f(int n, int (*a())[n]) > +{ > + (a())[0]; > +} > + > +void g(void) > +{ > + int (*a())[1]; > + f(1, a); > +} > + > diff --git a/gcc/testsuite/gcc.dg/pr109450-1.c b/gcc/testsuite/gcc.dg/pr1= 09450-1.c > new file mode 100644 > index 00000000000..aec127f2afc > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr109450-1.c > @@ -0,0 +1,21 @@ > +/* PR c/109450 > + * { dg-do run } > + * { dg-options "-std=3Dgnu99" } > + * */ > + > +int bar(int n, struct foo* x) /* { dg-warning "not be visible" } */ > +{ > + int a =3D n; > + struct foo { char buf[n++]; }* p =3D x; > + return a; > +} > + > +int main() > +{ > + if (1 !=3D bar(1, 0)) > + __builtin_abort(); > +} > + > + > + > + > diff --git a/gcc/testsuite/gcc.dg/pr109450-2.c b/gcc/testsuite/gcc.dg/pr1= 09450-2.c > new file mode 100644 > index 00000000000..06799f6df23 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr109450-2.c > @@ -0,0 +1,18 @@ > +/* PR c/109450 > + * { dg-do run } > + * { dg-options "-std=3Dgnu99" } > + * */ > + > +int bar(int n, struct foo *x) /* { dg-warning "not be visible" } */ > +{ > + int a =3D n; > + struct foo { char buf[a++]; }* p =3D x; > + return n =3D=3D a; > +} > + > +int main() > +{ > + if (bar(1, 0)) > + __builtin_abort(); > +} > + > diff --git a/gcc/testsuite/gcc.dg/typename-vla-2.c b/gcc/testsuite/gcc.dg= /typename-vla-2.c > new file mode 100644 > index 00000000000..9cdd9467544 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/typename-vla-2.c > @@ -0,0 +1,16 @@ > +/* { dg-do run } > + * { dg-options "-std=3Dc99" } > + * */ > + > +static int f(int n, char (*x)[sizeof (*(++n, (char (*)[n])0))]) > +{ > + return sizeof *x; > +} > + > +int main (void) > +{ > + if (2 !=3D f(1, 0)) > + __builtin_abort (); > + return 0; > +} > + > diff --git a/gcc/testsuite/gcc.dg/typename-vla-3.c b/gcc/testsuite/gcc.dg= /typename-vla-3.c > new file mode 100644 > index 00000000000..4c7c56bff8e > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/typename-vla-3.c > @@ -0,0 +1,16 @@ > +/* { dg-do run } > + * { dg-options "-std=3Dc99" } > + * */ > + > +static int f(int n, char (*x)[sizeof *(++n, (struct { char (*x)[n]; }){ = 0 }).x]) /* { dg-warning "anonymous struct" } */ > +{ > + return sizeof *x; > +} > + > +int main (void) > +{ > + if (2 !=3D f(1, 0)) > + __builtin_abort (); > + return 0; > +} > + > diff --git a/gcc/testsuite/gcc.dg/typename-vla-4.c b/gcc/testsuite/gcc.dg= /typename-vla-4.c > new file mode 100644 > index 00000000000..a05c782b555 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/typename-vla-4.c > @@ -0,0 +1,23 @@ > +/* { dg-do run } > + * { dg-options "-std=3Dgnu99" } > + * */ > + > +int main() > +{ > + int n =3D 1; > + sizeof(int[n++]); > + typeof(int[n++]); /* { dg-warning "empty de= claration" } */ > + struct { int x[n++]; }; /* { dg-warning "no insta= nce" } */ > + struct foo { int x[n++]; }; > + struct { int x[n++]; } x; > + struct bar { int x[n++]; } y; > + (int(*)[n++])0; > + (typeof(int(*)[n++]))0; > + (struct { int x[n++]; }*)0; > + (struct q { int x[n++]; }*)0; > + typeof(struct { int x[n++]; }); /* { dg-warning "empty de= claration" } */ > + typeof(struct r { int x[n++]; }); /* { dg-warning "empty de= claration" } */ > + > + if (13 !=3D n) > + __builtin_abort(); > +} > diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c b/gcc/testsuite/= gcc.misc-tests/gcov-pr85350.c > index 0383b81fdfb..a42bf1282b2 100644 > --- a/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c > +++ b/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c > @@ -4,7 +4,7 @@ > int main (void) > { > const int t =3D 2; /* count(1) */ > - struct s1 { /* count(1) */ > + struct s1 { /* count(-) */ > int x; > int g[t]; > }; > > > >