From d6f7829a1fa2577bac1bd8815acd31730affcb92 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 5 Mar 2019 09:43:16 +0100 Subject: [PATCH] re PR tree-optimization/89566 (ICE on compilable C++ code: in gimple_call_arg, at gimple.h:3166) PR tree-optimization/89566 * gimple-ssa-sprintf.c (sprintf_dom_walker::handle_gimple_call): Set info.fncode to BUILT_IN_NONE if gimple_call_builtin_p failed. Punt if get_user_idx_format succeeds, but idx_format argument is not provided or doesn't have pointer type, or if idx_args is above number of provided arguments. * c-c++-common/pr89566.c: New test. From-SVN: r269384 --- gcc/ChangeLog | 9 +++++++++ gcc/gimple-ssa-sprintf.c | 13 +++++++++---- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/c-c++-common/pr89566.c | 15 +++++++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr89566.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 38858fa6b0e..22ce3646ee1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-03-05 Jakub Jelinek + + PR tree-optimization/89566 + * gimple-ssa-sprintf.c (sprintf_dom_walker::handle_gimple_call): + Set info.fncode to BUILT_IN_NONE if gimple_call_builtin_p failed. + Punt if get_user_idx_format succeeds, but idx_format argument is + not provided or doesn't have pointer type, or if idx_args is above + number of provided arguments. + 2019-03-04 Wilco Dijkstra PR tree-optimization/89437 diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 4fe206ad08b..ced1c4c5777 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -3858,16 +3858,21 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi) if (!info.func) return false; - info.fncode = DECL_FUNCTION_CODE (info.func); - /* Format string argument number (valid for all functions). */ unsigned idx_format = UINT_MAX; - if (!gimple_call_builtin_p (info.callstmt, BUILT_IN_NORMAL)) + if (gimple_call_builtin_p (info.callstmt, BUILT_IN_NORMAL)) + info.fncode = DECL_FUNCTION_CODE (info.func); + else { unsigned idx_args; idx_format = get_user_idx_format (info.func, &idx_args); - if (idx_format == UINT_MAX) + if (idx_format == UINT_MAX + || idx_format >= gimple_call_num_args (info.callstmt) + || idx_args > gimple_call_num_args (info.callstmt) + || !POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (info.callstmt, + idx_format)))) return false; + info.fncode = BUILT_IN_NONE; info.argidx = idx_args; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c06d63a17a6..a5e25c3284d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-03-05 Jakub Jelinek + + PR tree-optimization/89566 + * c-c++-common/pr89566.c: New test. + 2019-03-04 Paolo Carlini PR c++/84605 diff --git a/gcc/testsuite/c-c++-common/pr89566.c b/gcc/testsuite/c-c++-common/pr89566.c new file mode 100644 index 00000000000..d9676565359 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr89566.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/89566 */ +/* { dg-do compile } */ + +typedef struct FILE { int i; } FILE; +#ifdef __cplusplus +extern "C" +#endif +int fprintf (FILE *, const char *, ...); + +int +main () +{ + ((void (*)()) fprintf) (); // { dg-warning "function called through a non-compatible type" "" { target c } } + return 0; +}