aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-08-17 08:48:58 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-08-17 08:48:58 +0000
commit36a072b429a9501946cb1fafdc9b1af7c574594d (patch)
tree40d0364573f5c9199c9b1b3c41447cf007c38188 /gcc/tree-inline.c
parentbbcbd744b80c2cd40d7ef41d32dbd6ee7400701f (diff)
downloadgcc-36a072b429a9501946cb1fafdc9b1af7c574594d.zip
gcc-36a072b429a9501946cb1fafdc9b1af7c574594d.tar.gz
gcc-36a072b429a9501946cb1fafdc9b1af7c574594d.tar.bz2
re PR middle-end/86505 (__builtin_va_arg_pack_len() computes the number of arguments wrongly)
2018-08-17 Richard Biener <rguenther@suse.de> PR middle-end/86505 * tree-inline.c (copy_bb): When inlining __builtin_va_arg_pack_len () across a va-arg-pack using call adjust its return value accordingly. * gcc.dg/torture/pr86505.c: New testcase. From-SVN: r263613
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 6a16ce5..21464d6 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1940,8 +1940,7 @@ copy_bb (copy_body_data *id, basic_block bb,
&& id->call_stmt
&& (decl = gimple_call_fndecl (stmt))
&& DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN
- && ! gimple_call_va_arg_pack_p (id->call_stmt))
+ && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN)
{
/* __builtin_va_arg_pack_len () should be replaced by
the number of anonymous arguments. */
@@ -1952,10 +1951,22 @@ copy_bb (copy_body_data *id, basic_block bb,
for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
nargs--;
- count = build_int_cst (integer_type_node, nargs);
- new_stmt = gimple_build_assign (gimple_call_lhs (stmt), count);
- gsi_replace (&copy_gsi, new_stmt, false);
- stmt = new_stmt;
+ if (!gimple_call_va_arg_pack_p (id->call_stmt))
+ {
+ count = build_int_cst (integer_type_node, nargs);
+ new_stmt = gimple_build_assign (gimple_call_lhs (stmt), count);
+ gsi_replace (&copy_gsi, new_stmt, false);
+ stmt = new_stmt;
+ }
+ else if (nargs != 0)
+ {
+ tree newlhs = create_tmp_reg_or_ssa_name (integer_type_node);
+ count = build_int_cst (integer_type_node, nargs);
+ new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
+ PLUS_EXPR, newlhs, count);
+ gimple_call_set_lhs (stmt, newlhs);
+ gsi_insert_after (&copy_gsi, new_stmt, GSI_NEW_STMT);
+ }
}
else if (call_stmt
&& id->call_stmt