From 4c4328646a2e6b7f87140d28086793b873bc5039 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 15 May 2014 15:40:02 -0400
Subject: [PATCH 26/29] Use gcatch

This corresponds to:
  "[PATCH 25/89] Introduce gimple_catch"
    https://gcc.gnu.org/ml/gcc-patches/2014-04/msg01178.html
from v1 of the patch series.

An additional change beyond the standard porting to the v4 approach is
the renaming of the local within:

	* tree-eh.c (lower_catch): Convert local from gimple to gcatch and
	rename from "gcatch" to "catch_stmt" to avoid clashing with the
	name of the type, since that prevents the as_a <gcatch *> from
	working.

gcc/
	* coretypes.h (gcatch): Add forward declaration.

	* gimple-low.c (lower_try_catch): Add checked cast to gcatch.
	(gimple_try_catch_may_fallthru): Likewise.

	* gimple-pretty-print.c (dump_gimple_catch): Require a gcatch
	rather than a plain gimple.
	(pp_gimple_stmt_1): Add checked cast to gcatch within
	GIMPLE_CATCH case of switch statement.

	* gimple-walk.c (walk_gimple_op): Likewise.
	(walk_gimple_stmt): Likewise.

	* gimple.c (gimple_build_catch): Return a gcatch rather than
	a plain gimple.
	(gimple_copy): Add checked casts to gcatch within
	GIMPLE_CATCH case of switch statement, introducing new locals.

	* gimple.h (gimple_build_catch): Return a gcatch rather than a
	plain gimple.
	(gimple_catch_types_ptr): Require a gcatch rather than a
	plain gimple.
	(gimple_catch_handler_ptr): Likewise.
	(gimple_catch_handler): Likewise.
	(gimple_catch_set_types): Likewise.
	(gimple_catch_set_handler): Likewise.

	* omp-low.c (lower_omp_1): Add checked cast to gcatch within
	GIMPLE_CATCH case of switch statement.

	* tree-cfg.c (verify_gimple_in_seq_2): Likewise.
	(do_warn_unused_result): Likewise.

	* tree-eh.c (collect_finally_tree): Likewise.
	(replace_goto_queue_1): Likewise.
	(lower_catch): Convert local from gimple to gcatch and
	rename from "gcatch" to "catch_stmt" to avoid clashing with the
	name of the type, since that prevents the as_a <gcatch *> from
	working.
	(refactor_eh_r): Add checked cast to gcatch within
	GIMPLE_CATCH case of switch statement.

	* tree-inline.c (remap_gimple_stmt): Likewise.
	(estimate_num_insns): Add checked cast to gcatch within
	GIMPLE_CATCH case of switch statement, introducing new local.

	* doc/gimple.texi: Update for above changes.
---
 gcc/coretypes.h           |  1 +
 gcc/doc/gimple.texi       | 10 +++++-----
 gcc/gimple-low.c          |  7 +++++--
 gcc/gimple-pretty-print.c |  4 ++--
 gcc/gimple-walk.c         |  9 +++++----
 gcc/gimple.c              | 16 ++++++++++------
 gcc/gimple.h              | 28 ++++++++++++----------------
 gcc/omp-low.c             |  2 +-
 gcc/tree-cfg.c            |  5 +++--
 gcc/tree-eh.c             | 18 +++++++++++-------
 gcc/tree-inline.c         | 11 ++++++++---
 11 files changed, 63 insertions(+), 48 deletions(-)

diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 46de13f..ec633b5 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -81,6 +81,7 @@ class gcall;
 class gtransaction;
 class greturn;
 class gbind;
+class gcatch;
 class gphi;
 
 union section;
diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
index 4339606..7cd18ae 100644
--- a/gcc/doc/gimple.texi
+++ b/gcc/doc/gimple.texi
@@ -1445,7 +1445,7 @@ in the positions marked by the set @code{ARGS_TO_SKIP}.
 @subsection @code{GIMPLE_CATCH}
 @cindex @code{GIMPLE_CATCH}
 
-@deftypefn {GIMPLE function} gimple *gimple_build_catch (tree types, @
+@deftypefn {GIMPLE function} gcatch *gimple_build_catch (tree types, @
 gimple_seq handler)
 Build a @code{GIMPLE_CATCH} statement.  @code{TYPES} are the tree types this
 catch handles.  @code{HANDLER} is a sequence of statements with the code
@@ -1456,22 +1456,22 @@ for the handler.
 Return the types handled by @code{GIMPLE_CATCH} statement @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} {tree *} gimple_catch_types_ptr (gimple *g)
+@deftypefn {GIMPLE function} {tree *} gimple_catch_types_ptr (gcatch *g)
 Return a pointer to the types handled by @code{GIMPLE_CATCH} statement
 @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} gimple_seq gimple_catch_handler (gimple *g)
+@deftypefn {GIMPLE function} gimple_seq gimple_catch_handler (gcatch *g)
 Return the GIMPLE sequence representing the body of the handler
 of @code{GIMPLE_CATCH} statement @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} void gimple_catch_set_types (gimple *g, @
+@deftypefn {GIMPLE function} void gimple_catch_set_types (gcatch *g, @
 tree t)
 Set @code{T} to be the set of types handled by @code{GIMPLE_CATCH} @code{G}.
 @end deftypefn
 
-@deftypefn {GIMPLE function} void gimple_catch_set_handler (gimple *g, @
+@deftypefn {GIMPLE function} void gimple_catch_set_handler (gcatch *g, @
 gimple_seq handler)
 Set @code{HANDLER} to be the body of @code{GIMPLE_CATCH} @code{G}.
 @end deftypefn
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 6811abb..fe703d1 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -454,7 +454,9 @@ lower_try_catch (gimple_stmt_iterator *gsi, struct lower_data *data)
       for (; !gsi_end_p (i); gsi_next (&i))
 	{
 	  data->cannot_fallthru = false;
-	  lower_sequence (gimple_catch_handler_ptr (gsi_stmt (i)), data);
+	  lower_sequence (gimple_catch_handler_ptr (
+			    as_a <gcatch *> (gsi_stmt (i))),
+			  data);
 	  if (!data->cannot_fallthru)
 	    cannot_fallthru = false;
 	}
@@ -516,7 +518,8 @@ gimple_try_catch_may_fallthru (gimple *stmt)
 	 through iff any of the catch bodies falls through.  */
       for (; !gsi_end_p (i); gsi_next (&i))
 	{
-	  if (gimple_seq_may_fallthru (gimple_catch_handler (gsi_stmt (i))))
+	  if (gimple_seq_may_fallthru (gimple_catch_handler (
+					 as_a <gcatch *> (gsi_stmt (i)))))
 	    return true;
 	}
       return false;
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index b108b62..4f12df0 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -977,7 +977,7 @@ dump_gimple_try (pretty_printer *buffer, gimple *gs, int spc, int flags)
    dumpfile.h).  */
 
 static void
-dump_gimple_catch (pretty_printer *buffer, gimple *gs, int spc, int flags)
+dump_gimple_catch (pretty_printer *buffer, gcatch *gs, int spc, int flags)
 {
   if (flags & TDF_RAW)
       dump_gimple_fmt (buffer, spc, flags, "%G <%T, %+CATCH <%S>%->", gs,
@@ -2192,7 +2192,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple *gs, int spc, int flags)
       break;
 
     case GIMPLE_CATCH:
-      dump_gimple_catch (buffer, gs, spc, flags);
+      dump_gimple_catch (buffer, as_a <gcatch *> (gs), spc, flags);
       break;
 
     case GIMPLE_EH_FILTER:
diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c
index d488bfe..9df93b4 100644
--- a/gcc/gimple-walk.c
+++ b/gcc/gimple-walk.c
@@ -278,8 +278,8 @@ walk_gimple_op (gimple *stmt, walk_tree_fn callback_op,
       break;
 
     case GIMPLE_CATCH:
-      ret = walk_tree (gimple_catch_types_ptr (stmt), callback_op, wi,
-		       pset);
+      ret = walk_tree (gimple_catch_types_ptr (as_a <gcatch *> (stmt)),
+		       callback_op, wi, pset);
       if (ret)
 	return ret;
       break;
@@ -551,8 +551,9 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
       break;
 
     case GIMPLE_CATCH:
-      ret = walk_gimple_seq_mod (gimple_catch_handler_ptr (stmt), callback_stmt,
-				 callback_op, wi);
+      ret = walk_gimple_seq_mod (gimple_catch_handler_ptr (
+				   as_a <gcatch *> (stmt)),
+				 callback_stmt, callback_op, wi);
       if (ret)
 	return wi->callback_result;
       break;
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 0f5c064..f72af5a 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -611,10 +611,10 @@ gimple_build_asm_vec (const char *string, vec<tree, va_gc> *inputs,
   TYPES are the catch types.
   HANDLER is the exception handler.  */
 
-gimple *
+gcatch *
 gimple_build_catch (tree types, gimple_seq handler)
 {
-  gimple *p = gimple_alloc (GIMPLE_CATCH, 0);
+  gcatch *p = as_a <gcatch *> (gimple_alloc (GIMPLE_CATCH, 0));
   gimple_catch_set_types (p, types);
   if (handler)
     gimple_catch_set_handler (p, handler);
@@ -1644,10 +1644,14 @@ gimple_copy (gimple *stmt)
 	  break;
 
 	case GIMPLE_CATCH:
-	  new_seq = gimple_seq_copy (gimple_catch_handler (stmt));
-	  gimple_catch_set_handler (copy, new_seq);
-	  t = unshare_expr (gimple_catch_types (stmt));
-	  gimple_catch_set_types (copy, t);
+	  {
+	    gcatch *catch_stmt = as_a <gcatch *> (stmt);
+	    gcatch *catch_copy = as_a <gcatch *> (copy);
+	    new_seq = gimple_seq_copy (gimple_catch_handler (catch_stmt));
+	    gimple_catch_set_handler (catch_copy, new_seq);
+	    t = unshare_expr (gimple_catch_types (catch_stmt));
+	    gimple_catch_set_types (catch_copy, t);
+	  }
 	  break;
 
 	case GIMPLE_EH_FILTER:
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 2bb455f..0eecffa 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1315,7 +1315,7 @@ gbind *gimple_build_bind (tree, gimple_seq, tree);
 gasm *gimple_build_asm_vec (const char *, vec<tree, va_gc> *,
 			    vec<tree, va_gc> *, vec<tree, va_gc> *,
 			    vec<tree, va_gc> *);
-gimple *gimple_build_catch (tree, gimple_seq);
+gcatch *gimple_build_catch (tree, gimple_seq);
 gimple *gimple_build_eh_filter (tree, gimple_seq);
 gimple *gimple_build_eh_must_not_throw (tree);
 gimple *gimple_build_eh_else (gimple_seq, gimple_seq);
@@ -3485,53 +3485,49 @@ gimple_catch_types (const gimple *gs)
 }
 
 
-/* Return a pointer to the types handled by GIMPLE_CATCH statement GS.  */
+/* Return a pointer to the types handled by GIMPLE_CATCH statement CATCH_STMT.  */
 
 static inline tree *
-gimple_catch_types_ptr (gimple *gs)
+gimple_catch_types_ptr (gcatch *catch_stmt)
 {
-  gcatch *catch_stmt = as_a <gcatch *> (gs);
   return &catch_stmt->types;
 }
 
 
 /* Return a pointer to the GIMPLE sequence representing the body of
-   the handler of GIMPLE_CATCH statement GS.  */
+   the handler of GIMPLE_CATCH statement CATCH_STMT.  */
 
 static inline gimple_seq *
-gimple_catch_handler_ptr (gimple *gs)
+gimple_catch_handler_ptr (gcatch *catch_stmt)
 {
-  gcatch *catch_stmt = as_a <gcatch *> (gs);
   return &catch_stmt->handler;
 }
 
 
 /* Return the GIMPLE sequence representing the body of the handler of
-   GIMPLE_CATCH statement GS.  */
+   GIMPLE_CATCH statement CATCH_STMT.  */
 
 static inline gimple_seq
-gimple_catch_handler (gimple *gs)
+gimple_catch_handler (gcatch *catch_stmt)
 {
-  return *gimple_catch_handler_ptr (gs);
+  return *gimple_catch_handler_ptr (catch_stmt);
 }
 
 
-/* Set T to be the set of types handled by GIMPLE_CATCH GS.  */
+/* Set T to be the set of types handled by GIMPLE_CATCH CATCH_STMT.  */
 
 static inline void
-gimple_catch_set_types (gimple *gs, tree t)
+gimple_catch_set_types (gcatch *catch_stmt, tree t)
 {
-  gcatch *catch_stmt = as_a <gcatch *> (gs);
   catch_stmt->types = t;
 }
 
 
-/* Set HANDLER to be the body of GIMPLE_CATCH GS.  */
+/* Set HANDLER to be the body of GIMPLE_CATCH CATCH_STMT.  */
 
 static inline void
-gimple_catch_set_handler (gimple *gs, gimple_seq handler)
+gimple_catch_set_handler (gcatch *catch_stmt, gimple_seq handler)
 {
-  gcatch *catch_stmt = as_a <gcatch *> (gs);
   catch_stmt->handler = handler;
 }
 
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 0d8b094..8f9417c 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -10033,7 +10033,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 	gimple_regimplify_operands (stmt, gsi_p);
       break;
     case GIMPLE_CATCH:
-      lower_omp (gimple_catch_handler_ptr (stmt), ctx);
+      lower_omp (gimple_catch_handler_ptr (as_a <gcatch *> (stmt)), ctx);
       break;
     case GIMPLE_EH_FILTER:
       lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 3ac11ab..924ac43 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -4582,7 +4582,8 @@ verify_gimple_in_seq_2 (gimple_seq stmts)
 	  break;
 
 	case GIMPLE_CATCH:
-	  err |= verify_gimple_in_seq_2 (gimple_catch_handler (stmt));
+	  err |= verify_gimple_in_seq_2 (gimple_catch_handler (
+					   as_a <gcatch *> (stmt)));
 	  break;
 
 	case GIMPLE_TRANSACTION:
@@ -8322,7 +8323,7 @@ do_warn_unused_result (gimple_seq seq)
 	  do_warn_unused_result (gimple_try_cleanup (g));
 	  break;
 	case GIMPLE_CATCH:
-	  do_warn_unused_result (gimple_catch_handler (g));
+	  do_warn_unused_result (gimple_catch_handler (as_a <gcatch *> (g)));
 	  break;
 	case GIMPLE_EH_FILTER:
 	  do_warn_unused_result (gimple_eh_filter_failure (g));
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 7a9c414..cf2f7fb 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -285,7 +285,9 @@ collect_finally_tree (gimple *stmt, gimple *region)
       break;
 
     case GIMPLE_CATCH:
-      collect_finally_tree_1 (gimple_catch_handler (stmt), region);
+      collect_finally_tree_1 (gimple_catch_handler (
+				 as_a <gcatch *> (stmt)),
+			      region);
       break;
 
     case GIMPLE_EH_FILTER:
@@ -543,7 +545,9 @@ replace_goto_queue_1 (gimple *stmt, struct leh_tf_state *tf,
       replace_goto_queue_stmt_list (gimple_try_cleanup_ptr (stmt), tf);
       break;
     case GIMPLE_CATCH:
-      replace_goto_queue_stmt_list (gimple_catch_handler_ptr (stmt), tf);
+      replace_goto_queue_stmt_list (gimple_catch_handler_ptr (
+				      as_a <gcatch *> (stmt)),
+				    tf);
       break;
     case GIMPLE_EH_FILTER:
       replace_goto_queue_stmt_list (gimple_eh_filter_failure_ptr (stmt), tf);
@@ -1792,13 +1796,13 @@ lower_catch (struct leh_state *state, gimple *tp)
        gsi_next (&gsi))
     {
       eh_catch c;
-      gimple *gcatch;
+      gcatch *catch_stmt;
       gimple_seq handler;
 
-      gcatch = gsi_stmt (gsi);
-      c = gen_eh_region_catch (try_region, gimple_catch_types (gcatch));
+      catch_stmt = as_a <gcatch *> (gsi_stmt (gsi));
+      c = gen_eh_region_catch (try_region, gimple_catch_types (catch_stmt));
 
-      handler = gimple_catch_handler (gcatch);
+      handler = gimple_catch_handler (catch_stmt);
       lower_eh_constructs_1 (&this_state, &handler);
 
       c->label = create_artificial_label (UNKNOWN_LOCATION);
@@ -3091,7 +3095,7 @@ refactor_eh_r (gimple_seq seq)
 	    refactor_eh_r (gimple_try_cleanup (one));
 	    break;
 	  case GIMPLE_CATCH:
-	    refactor_eh_r (gimple_catch_handler (one));
+	    refactor_eh_r (gimple_catch_handler (as_a <gcatch *> (one)));
 	    break;
 	  case GIMPLE_EH_FILTER:
 	    refactor_eh_r (gimple_eh_filter_failure (one));
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 680d68a..13368c7 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1294,8 +1294,11 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
 	  break;
 
 	case GIMPLE_CATCH:
-	  s1 = remap_gimple_seq (gimple_catch_handler (stmt), id);
-	  copy = gimple_build_catch (gimple_catch_types (stmt), s1);
+	  {
+	    gcatch *catch_stmt = as_a <gcatch *> (stmt);
+	    s1 = remap_gimple_seq (gimple_catch_handler (catch_stmt), id);
+	    copy = gimple_build_catch (gimple_catch_types (catch_stmt), s1);
+	  }
 	  break;
 
 	case GIMPLE_EH_FILTER:
@@ -3939,7 +3942,9 @@ estimate_num_insns (gimple *stmt, eni_weights *weights)
       return estimate_num_insns_seq (gimple_eh_filter_failure (stmt), weights);
 
     case GIMPLE_CATCH:
-      return estimate_num_insns_seq (gimple_catch_handler (stmt), weights);
+      return estimate_num_insns_seq (gimple_catch_handler (
+				       as_a <gcatch *> (stmt)),
+				     weights);
 
     case GIMPLE_TRY:
       return (estimate_num_insns_seq (gimple_try_eval (stmt), weights)
-- 
1.8.5.3

