From cd123354c511316c020bf7ff7e4527989b440223 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@gcc.gnu.org>
Date: Tue, 3 Jan 2017 08:20:04 +0100
Subject: [PATCH] re PR middle-end/78901 (ICE: verify_gimple failed (error:
 statement marked for throw in middle of block))

	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.

From-SVN: r244013
---
 gcc/ChangeLog                      |  4 ++++
 gcc/gimple-ssa-sprintf.c           | 10 +++++++--
 gcc/testsuite/ChangeLog            | 34 +++++++++++++++++-------------
 gcc/testsuite/g++.dg/opt/pr78901.C | 18 ++++++++++++++++
 4 files changed, 49 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/opt/pr78901.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b38e59a54620..7e1b2df89183 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
 2017-01-03  Jakub Jelinek  <jakub@redhat.com>
 
+	PR middle-end/78901
+	* gimple-ssa-sprintf.c (try_substitute_return_value): Don't change
+	possibly throwing calls.
+
 	* genmatch.c (dt_node::gen_kids_1): If generic_exprs include SSA_NAME
 	and exprs_len || fns_len, emit the code for SSA_NAME next to the exprs
 	and fns handling, rather than in a separate case SSA_NAME.
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 907a06479eef..ecd2267ae93f 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -2696,9 +2696,15 @@ try_substitute_return_value (gimple_stmt_iterator *gsi,
      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);
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 560976989b83..bdaa2fe5d687 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,20 +1,24 @@
+2017-01-03  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/78901
+	* g++.dg/opt/pr78901.C: New test.
+
 2017-01-03  Janne Blomqvist  <jb@gcc.gnu.org>
 
-        PR fortran/78534
-        PR fortran/66310
-        * gfortran.dg/dependency_49.f90: Change scan-tree-dump-times
-          due to gfc_trans_string_copy change to avoid
-          -Wstringop-overflow.
-        * gfortran.dg/repeat_4.f90: Use integers of kind C_SIZE_T.
-        * gfortran.dg/repeat_7.f90: New test for PR 66310.
-        * gfortran.dg/scan_2.f90: Handle potential cast in assignment.
-        * gfortran.dg/string_1.f90: Limit to ilp32 targets.
-        * gfortran.dg/string_1_lp64.f90: New test.
-        * gfortran.dg/string_3.f90: Limit to ilp32 targets.
-        * gfortran.dg/string_3_lp64.f90: New test.
-        * gfortran.dg/transfer_intrinsic_1.f90: Change
-          scan-tree-dump-times due to gfc_trans_string_copy change to
-          avoid -Wstringop-overflow.
+	PR fortran/78534
+	PR fortran/66310
+	* gfortran.dg/dependency_49.f90: Change scan-tree-dump-times
+	due to gfc_trans_string_copy change to avoid -Wstringop-overflow.
+	* gfortran.dg/repeat_4.f90: Use integers of kind C_SIZE_T.
+	* gfortran.dg/repeat_7.f90: New test for PR 66310.
+	* gfortran.dg/scan_2.f90: Handle potential cast in assignment.
+	* gfortran.dg/string_1.f90: Limit to ilp32 targets.
+	* gfortran.dg/string_1_lp64.f90: New test.
+	* gfortran.dg/string_3.f90: Limit to ilp32 targets.
+	* gfortran.dg/string_3_lp64.f90: New test.
+	* gfortran.dg/transfer_intrinsic_1.f90: Change
+	scan-tree-dump-times due to gfc_trans_string_copy change to
+	avoid -Wstringop-overflow.
 
 2017-01-02  Uros Bizjak  <ubizjak@gmail.com>
 
diff --git a/gcc/testsuite/g++.dg/opt/pr78901.C b/gcc/testsuite/g++.dg/opt/pr78901.C
new file mode 100644
index 000000000000..932462fd03b4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr78901.C
@@ -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;
+    }
+}
-- 
GitLab