Message ID | 20210606174444.GE7746@tucnak |
---|---|
State | New |
Headers | show |
Series | tree-inline: Fix up __builtin_va_arg_pack handling [PR100898] | expand |
On Sun, 6 Jun 2021, Jakub Jelinek wrote: > Hi! > > The following testcase ICEs, because gimple_call_arg_ptr (..., 0) > asserts that there is at least one argument, while we were using > it even if we didn't copy anything just to get a pointer from/to which > the zero arguments should be copied. > > Fixed by guarding the memcpy calls. Also, the code was calling > gimple_call_num_args too many times - 5 times instead of 2, so the patch > adds two temporaries for those. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK. Richard. > 2021-06-06 Jakub Jelinek <jakub@redhat.com> > > PR middle-end/100898 > * tree-inline.c (copy_bb): Only use gimple_call_arg_ptr if memcpy > should copy any arguments. Don't call gimple_call_num_args > on id->call_stmt or call_stmt more than once. > > * g++.dg/ext/va-arg-pack-3.C: New test. > > --- gcc/tree-inline.c.jj 2021-06-04 11:15:26.000000000 +0200 > +++ gcc/tree-inline.c 2021-06-04 15:15:07.358413674 +0200 > @@ -2090,27 +2090,29 @@ copy_bb (copy_body_data *id, basic_block > tree p; > gcall *new_call; > vec<tree> argarray; > - size_t nargs = gimple_call_num_args (id->call_stmt); > - size_t n; > + size_t nargs_caller = gimple_call_num_args (id->call_stmt); > + size_t nargs = nargs_caller; > > for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p)) > nargs--; > > /* Create the new array of arguments. */ > - n = nargs + gimple_call_num_args (call_stmt); > + size_t nargs_callee = gimple_call_num_args (call_stmt); > + size_t n = nargs + nargs_callee; > argarray.create (n); > argarray.safe_grow_cleared (n, true); > > /* Copy all the arguments before '...' */ > - memcpy (argarray.address (), > - gimple_call_arg_ptr (call_stmt, 0), > - gimple_call_num_args (call_stmt) * sizeof (tree)); > + if (nargs_callee) > + memcpy (argarray.address (), > + gimple_call_arg_ptr (call_stmt, 0), > + nargs_callee * sizeof (tree)); > > /* Append the arguments passed in '...' */ > - memcpy (argarray.address () + gimple_call_num_args (call_stmt), > - gimple_call_arg_ptr (id->call_stmt, 0) > - + (gimple_call_num_args (id->call_stmt) - nargs), > - nargs * sizeof (tree)); > + if (nargs) > + memcpy (argarray.address () + nargs_callee, > + gimple_call_arg_ptr (id->call_stmt, 0) > + + (nargs_caller - nargs), nargs * sizeof (tree)); > > new_call = gimple_build_call_vec (gimple_call_fn (call_stmt), > argarray); > --- gcc/testsuite/g++.dg/ext/va-arg-pack-3.C.jj 2021-06-04 15:32:28.213079130 +0200 > +++ gcc/testsuite/g++.dg/ext/va-arg-pack-3.C 2021-06-04 15:31:29.777883575 +0200 > @@ -0,0 +1,18 @@ > +// PR middle-end/100898 > + > +int a; > +int bar (int, ...); > + > +static inline __attribute__((always_inline)) int > +foo (...) > +{ > + while (a) > + return bar (0, __builtin_va_arg_pack ()); > + return 0; > +} > + > +void > +baz (void) > +{ > + foo (); > +} > > Jakub > >
--- gcc/tree-inline.c.jj 2021-06-04 11:15:26.000000000 +0200 +++ gcc/tree-inline.c 2021-06-04 15:15:07.358413674 +0200 @@ -2090,27 +2090,29 @@ copy_bb (copy_body_data *id, basic_block tree p; gcall *new_call; vec<tree> argarray; - size_t nargs = gimple_call_num_args (id->call_stmt); - size_t n; + size_t nargs_caller = gimple_call_num_args (id->call_stmt); + size_t nargs = nargs_caller; for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p)) nargs--; /* Create the new array of arguments. */ - n = nargs + gimple_call_num_args (call_stmt); + size_t nargs_callee = gimple_call_num_args (call_stmt); + size_t n = nargs + nargs_callee; argarray.create (n); argarray.safe_grow_cleared (n, true); /* Copy all the arguments before '...' */ - memcpy (argarray.address (), - gimple_call_arg_ptr (call_stmt, 0), - gimple_call_num_args (call_stmt) * sizeof (tree)); + if (nargs_callee) + memcpy (argarray.address (), + gimple_call_arg_ptr (call_stmt, 0), + nargs_callee * sizeof (tree)); /* Append the arguments passed in '...' */ - memcpy (argarray.address () + gimple_call_num_args (call_stmt), - gimple_call_arg_ptr (id->call_stmt, 0) - + (gimple_call_num_args (id->call_stmt) - nargs), - nargs * sizeof (tree)); + if (nargs) + memcpy (argarray.address () + nargs_callee, + gimple_call_arg_ptr (id->call_stmt, 0) + + (nargs_caller - nargs), nargs * sizeof (tree)); new_call = gimple_build_call_vec (gimple_call_fn (call_stmt), argarray); --- gcc/testsuite/g++.dg/ext/va-arg-pack-3.C.jj 2021-06-04 15:32:28.213079130 +0200 +++ gcc/testsuite/g++.dg/ext/va-arg-pack-3.C 2021-06-04 15:31:29.777883575 +0200 @@ -0,0 +1,18 @@ +// PR middle-end/100898 + +int a; +int bar (int, ...); + +static inline __attribute__((always_inline)) int +foo (...) +{ + while (a) + return bar (0, __builtin_va_arg_pack ()); + return 0; +} + +void +baz (void) +{ + foo (); +}