From da2ce5f993367610a67df1367665dda8a0abc354 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 21 Mar 2017 11:42:22 +0000 Subject: [PATCH] re PR tree-optimization/80122 (__builtin_va_arg_pack() and __builtin_va_arg_pack_len() does not work correctly) 2017-03-21 Richard Biener PR tree-optimization/80122 * tree-inline.c (copy_bb): Do not expans va-arg packs or va_arg_pack_len when the inlined call stmt requires pack expansion itself. * tree-inline.h (struct copy_body_data): Make call_stmt a gcall *. * gcc.dg/torture/pr80122.c: New testcase. From-SVN: r246313 --- gcc/ChangeLog | 8 ++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/torture/pr80122.c | 52 ++++++++++++++++++++++++++ gcc/tree-inline.c | 8 ++-- gcc/tree-inline.h | 2 +- 5 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr80122.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 62c63c46a08..f48f6d39aac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2017-03-21 Richard Biener + + PR tree-optimization/80122 + * tree-inline.c (copy_bb): Do not expans va-arg packs or + va_arg_pack_len when the inlined call stmt requires pack + expansion itself. + * tree-inline.h (struct copy_body_data): Make call_stmt a gcall *. + 2017-03-21 Jakub Jelinek PR sanitizer/78158 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index eaf6331dabb..68705a7de06 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-21 Richard Biener + + PR tree-optimization/80122 + * gcc.dg/torture/pr80122.c: New testcase. + 2017-03-21 Toma Tabacu * gcc.dg/pic-2.c: Skip for MIPS. diff --git a/gcc/testsuite/gcc.dg/torture/pr80122.c b/gcc/testsuite/gcc.dg/torture/pr80122.c new file mode 100644 index 00000000000..a76d756c32e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr80122.c @@ -0,0 +1,52 @@ +/* { dg-do run } */ + +#define __GNU_ALWAYS_INLINE inline __attribute__(( __always_inline__)) + +#define DEVT_ALL 0 + +#define CMD_ABI_DEVICES 100 + +static __GNU_ALWAYS_INLINE int +send_msg_to_gm_w_dev_t(int msg_type, unsigned int dev_msg_type, + int devt, ...) +{ + char s[256]; + int nArgs = __builtin_va_arg_pack_len(); + if (nArgs != 2) + __builtin_abort (); + __builtin_sprintf (s, "%d", __builtin_va_arg_pack ()); + if (__builtin_strcmp (s, "99") != 0) + __builtin_abort (); + /* do something with nArgs and ... */ + return 0; +} + +static __GNU_ALWAYS_INLINE int +send_msg_to_gm(int msg_type, unsigned int dev_msg_type, + ...) +{ + int nArgs = __builtin_va_arg_pack_len(); + if (nArgs != 2) + __builtin_abort (); + return send_msg_to_gm_w_dev_t(msg_type, dev_msg_type, + DEVT_ALL, __builtin_va_arg_pack()); +} + +static __GNU_ALWAYS_INLINE int +send_enable(unsigned int dev_msg_type, ...) +{ + int nArgs = __builtin_va_arg_pack_len(); + if (nArgs != 2) + __builtin_abort (); + return send_msg_to_gm(CMD_ABI_DEVICES, dev_msg_type, __builtin_va_arg_pack()); +} + +int +main(void) +{ + int mode = 99; + + send_enable(1, mode, sizeof(mode)); + + return 0; +} diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index bd4b48e8623..6b6d489f6ca 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1860,7 +1860,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, call_stmt = dyn_cast (stmt); if (call_stmt && gimple_call_va_arg_pack_p (call_stmt) - && id->call_stmt) + && id->call_stmt + && ! gimple_call_va_arg_pack_p (id->call_stmt)) { /* __builtin_va_arg_pack () should be replaced by all arguments corresponding to ... in the caller. */ @@ -1940,7 +1941,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, && 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) + && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN + && ! gimple_call_va_arg_pack_p (id->call_stmt)) { /* __builtin_va_arg_pack_len () should be replaced by the number of anonymous arguments. */ @@ -4584,7 +4586,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) /* Record the function we are about to inline. */ id->src_fn = fn; id->src_cfun = DECL_STRUCT_FUNCTION (fn); - id->call_stmt = stmt; + id->call_stmt = call_stmt; /* If the src function contains an IFN_VA_ARG, then so will the dst function after inlining. Likewise for IFN_GOMP_USE_SIMT. */ diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h index 41402a315ec..88b32863745 100644 --- a/gcc/tree-inline.h +++ b/gcc/tree-inline.h @@ -81,7 +81,7 @@ struct copy_body_data /* GIMPLE_CALL if va arg parameter packs should be expanded or NULL is not. */ - gimple *call_stmt; + gcall *call_stmt; /* Exception landing pad the inlined call lies in. */ int eh_lp_nr; -- 2.30.2