diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr80122.c | 52 | ||||
-rw-r--r-- | gcc/tree-inline.c | 8 | ||||
-rw-r--r-- | gcc/tree-inline.h | 2 |
5 files changed, 71 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 62c63c4..f48f6d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2017-03-21 Richard Biener <rguenther@suse.de> + + 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 <jakub@redhat.com> PR sanitizer/78158 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index eaf6331..68705a7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-21 Richard Biener <rguenther@suse.de> + + PR tree-optimization/80122 + * gcc.dg/torture/pr80122.c: New testcase. + 2017-03-21 Toma Tabacu <toma.tabacu@imgtec.com> * 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 0000000..a76d756 --- /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 bd4b48e..6b6d489 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 <gcall *> (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 41402a3..88b3286 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; |