Hi! As my earlier patch to adjust cfns.gperf for C99/C11 builtins has been committed already, the non-__*_chk builtins (and when using __builtin__*_chk form even those) should be all noexcept, and when using fortification the glibc headers declare those properly throw() and ssp includes just use builtins directly. Therefore I think it is just a waste of time to add code to handle something that will not really happen in real-world code, only when somebody declares those incorrectly by hand.
The following patch therefore just punts on stmt_ends_bb_p (info.callstmt) rather than purging dead edges and scheduling cfg cleanups on replacement of call with constant if the compiler thinks it might throw, or when inserting after the call (also invalid, would need to be inserted on fallthrough edge instead). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-01-02 Jakub Jelinek <ja...@redhat.com> PR middle-end/78901 * gimple-ssa-sprintf.c (try_substitute_return_value): Don't change possibly throwing calls. * g++.dg/opt/pr78901.C: New test. --- gcc/gimple-ssa-sprintf.c.jj 2017-01-02 12:09:29.000000000 +0100 +++ gcc/gimple-ssa-sprintf.c 2017-01-02 13:05:08.400755201 +0100 @@ -2699,9 +2699,15 @@ try_substitute_return_value (gimple_stmt the output overflows the destination object (but leave it enabled when the function is bounded because then the behavior is well- defined). */ - if (lhs && res.bounded && res.under4k + if (lhs + && res.bounded + && res.under4k && (info.bounded || res.number_chars <= info.objsize) - && res.number_chars - 1 <= target_int_max ()) + && res.number_chars - 1 <= target_int_max () + /* Not prepared to handle possibly throwing calls here; they shouldn't + appear in non-artificial testcases, except when the __*_chk routines + are badly declared. */ + && !stmt_ends_bb_p (info.callstmt)) { tree cst = build_int_cst (integer_type_node, res.number_chars - 1); --- gcc/testsuite/g++.dg/opt/pr78901.C.jj 2017-01-02 13:04:24.271329153 +0100 +++ gcc/testsuite/g++.dg/opt/pr78901.C 2017-01-02 13:03:19.000000000 +0100 @@ -0,0 +1,18 @@ +// PR middle-end/78901 +// { dg-do compile } +// { dg-options "-O2 -Wno-stringop-overflow" } + +extern "C" int __snprintf_chk (char *, __SIZE_TYPE__, int, __SIZE_TYPE__, const char *, ...); + +int +foo (char *c) +{ + try + { + return __snprintf_chk (c, 64, 0, 32, "%s", "abcdefghijklmnopq"); + } + catch (...) + { + return -1; + } +} Jakub