Bug 77767 - [5 Regression] Side-effect from VLA array parameters lost
Summary: [5 Regression] Side-effect from VLA array parameters lost
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 7.0
: P2 normal
Target Milestone: 5.5
Assignee: Jakub Jelinek
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2016-09-27 21:43 UTC by Joseph S. Myers
Modified: 2017-05-30 09:19 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-09-29 00:00:00


Attachments
gcc7-pr77767.patch (663 bytes, patch)
2016-12-20 11:13 UTC, Jakub Jelinek
Details | Diff
gcc7-pr77767-2.patch (896 bytes, patch)
2016-12-20 11:19 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph S. Myers 2016-09-27 21:43:51 UTC
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.
Comment 1 Joseph S. Myers 2016-09-27 21:52:30 UTC
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 .
Comment 2 Marek Polacek 2016-09-29 12:15:37 UTC
Confirmed.
Comment 3 Marek Polacek 2016-09-29 12:16:27 UTC
Mine.
Comment 4 Jakub Jelinek 2016-12-20 11:13:52 UTC
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?
Comment 5 Jakub Jelinek 2016-12-20 11:19:48 UTC
Created attachment 40378 [details]
gcc7-pr77767-2.patch

Version with append_to_statement_list.
Comment 6 jsm-csl@polyomino.org.uk 2016-12-20 17:10:06 UTC
I think the append_to_statement_list version should be preferred.
Comment 7 Jakub Jelinek 2016-12-20 18:55:47 UTC
Unfortunately that version breaks the pr49120.c testcase, because mark_exp_read doesn't deal with STATEMENT_LISTs.  I'll test the other patch.
Comment 8 Jakub Jelinek 2016-12-21 00:08:21 UTC
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
Comment 9 Jakub Jelinek 2016-12-21 12:52:37 UTC
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
Comment 10 Jakub Jelinek 2017-01-02 14:57:34 UTC
Fixed for 6.4+ so far.
Comment 11 Jakub Jelinek 2017-05-30 07:52:29 UTC
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
Comment 12 Jakub Jelinek 2017-05-30 09:19:03 UTC
Fixed.