The program #include <stdio.h> int f (int a, int b[a++], int c, int d[c++]) { printf ("%d %d\n", a, c); } int main (void) { int dummy[10]; f (1, dummy, 1, dummy); return 0; } outputs "1 2". It should output "2 2". Side-effects from size expressions for array parameters are handled through the pending_sizes member of struct c_arg_info. c_parser_parms_list_declarator may call push_parm_decl any number of times, and push_parm_decl calls grokdeclarator, and each grokdeclarator call overwrites the previous value of expr storing expressions to evaluate on function entry, when what is required is to update it instead. Either push_parm_decl (or something further up the call chain) needs to deal with merging with an existing value, or grokdeclarator could be made to do so but then all callers wanting the existing overwriting would need to be updated to pass a pointer to a variable with a NULL_TREE value, rather than an old value that should be overwritten or an uninitialized variable.
This appears to be a regression in 4.7 and later, probably caused by r173422 - https://gcc.gnu.org/ml/gcc-patches/2011-05/msg00319.html .
Confirmed.
Mine.
Created attachment 40377 [details] gcc7-pr77767.patch I went through all the grokdeclarator (indirect) callers, and those callers (of e.g. groktypename, grokparm, push_parm_decl and c_parser_objc_method_decl) that are called with non-NULL expr actually ensure it is initialized with NULL_TREE first and want to append to it. Here is thus an untested patch. Optionally, the building of COMPOUND_EXPR could be in both spots (this one and the one in the if (this_size_varies) handling later on) replaced with append_to_statement_list (whatever, expr); Any preferences here?
Created attachment 40378 [details] gcc7-pr77767-2.patch Version with append_to_statement_list.
I think the append_to_statement_list version should be preferred.
Unfortunately that version breaks the pr49120.c testcase, because mark_exp_read doesn't deal with STATEMENT_LISTs. I'll test the other patch.
Author: jakub Date: Wed Dec 21 00:07:49 2016 New Revision: 243832 URL: https://gcc.gnu.org/viewcvs?rev=243832&root=gcc&view=rev Log: PR c/77767 * c-decl.c (grokdeclarator): If *expr is non-NULL, append expression to *expr instead of overwriting it. * gcc.c-torture/execute/pr77767.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/execute/pr77767.c Modified: trunk/gcc/c/ChangeLog trunk/gcc/c/c-decl.c trunk/gcc/testsuite/ChangeLog
Author: jakub Date: Wed Dec 21 12:52:06 2016 New Revision: 243851 URL: https://gcc.gnu.org/viewcvs?rev=243851&root=gcc&view=rev Log: PR c/77767 * c-decl.c (grokdeclarator): If *expr is non-NULL, append expression to *expr instead of overwriting it. * gcc.c-torture/execute/pr77767.c: New test. Added: branches/gcc-6-branch/gcc/testsuite/gcc.c-torture/execute/pr77767.c Modified: branches/gcc-6-branch/gcc/c/ChangeLog branches/gcc-6-branch/gcc/c/c-decl.c branches/gcc-6-branch/gcc/testsuite/ChangeLog
Fixed for 6.4+ so far.
Author: jakub Date: Tue May 30 07:51:58 2017 New Revision: 248635 URL: https://gcc.gnu.org/viewcvs?rev=248635&root=gcc&view=rev Log: Backported from mainline 2016-12-21 Jakub Jelinek <jakub@redhat.com> PR c/77767 * c-decl.c (grokdeclarator): If *expr is non-NULL, append expression to *expr instead of overwriting it. * gcc.c-torture/execute/pr77767.c: New test. Added: branches/gcc-5-branch/gcc/testsuite/gcc.c-torture/execute/pr77767.c Modified: branches/gcc-5-branch/gcc/c/ChangeLog branches/gcc-5-branch/gcc/c/c-decl.c branches/gcc-5-branch/gcc/testsuite/ChangeLog
Fixed.