[patch] for PR 24996

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Thu Feb 2 17:56:00 GMT 2006


Hello,

this PR is caused by the fact that gimplification does not handle
TARGET_EXPR cleanups coming from structured statements (other than
conditionals).  The code we get in this PR looks like

cleanup_point
  {
    TARGET_EXPR <D.2069, __cxa_allocate_exception (1)>;
    try
      {
        *(struct logic_error *) D.2069 = exp;
      }
    catch
      {
        __cxa_free_exception (D.2069);
      };
    __cxa_throw (D.2069, (void *) &_ZTI11logic_error, 0B);
  }

where exp contains the TARGET_EXPR with cleanup.  Unless there is
a way to avoid producing a code like that, gimplification needs
to be improved to handle this case.

This patch is a very conservative attempt to do this.  Before, for

stmts1;
target_expr (something, cleanup);
stmts2;

we produced

stmts1
try
 {
   something;
   stmts2;
 }
finally
 {
   cleanup;
 }

With the patch, we produce code like

bool flag = false;
try
 {
   stmts1;
   flag = true;
   something;
   stmts2;
 }
finally
 {
   if (flag)
     cleanup;
 }

This is a bit less efficient (although the flag manipulation will
usually be removed later by optimizers, anyway), however it works
even if the target_expr is nested within a structured statement
(the current solution produces a similar code for target_exprs within
a conditional context).

Bootstrapped & regtested on i686.

Zdenek

	* gimplify.c (struct cleanup): New.
	(struct gimplify_ctx): Removed conditional_cleanups and conditions
	fields.  Added cleanups field.
	(gimple_conditional_context, gimple_push_condition,
	gimple_pop_condition): Removed.
	(gimplify_cond_expr): Do not record conditional context.
	(gimplify_cleanup_point_expr): Use gimplify_ctxp->cleanups
	instead of cleanup_exprs to find cleanups.
	(gimple_push_cleanup): Record cleanups to gimplify_ctxp->cleanups.
	* tree-pretty-print.c (print_call_name, do_niy): Obey indentation.
	(dump_generic_node): Improve indentation.

Index: gimplify.c
===================================================================
*** gimplify.c	(revision 110257)
--- gimplify.c	(working copy)
*************** struct gimplify_omp_ctx
*** 75,87 ****
    bool is_parallel;
  };
  
  struct gimplify_ctx
  {
    struct gimplify_ctx *prev_context;
  
    tree current_bind_expr;
    tree temps;
!   tree conditional_cleanups;
    tree exit_label;
    tree return_temp;
    
--- 75,105 ----
    bool is_parallel;
  };
  
+ /* Records a scheduled cleanup.  */
+ 
+ struct cleanup
+ {
+   /* True if the cleanup should be run only on exception, not on normal
+      exit.  */
+   bool eh_only;
+ 
+   /* The variable used to guard the cleanup.  */
+   tree guard;
+ 
+   /* The cleanup.  */
+   tree cleanup;
+ 
+   /* Next cleanup in the list.  */
+   struct cleanup *next;
+ };
+ 
  struct gimplify_ctx
  {
    struct gimplify_ctx *prev_context;
  
    tree current_bind_expr;
    tree temps;
!   struct cleanup *cleanups;
    tree exit_label;
    tree return_temp;
    
*************** struct gimplify_ctx
*** 89,95 ****
    /* The formal temporary table.  Should this be persistent?  */
    htab_t temp_htab;
  
-   int conditions;
    bool save_stack;
    bool into_ssa;
  };
--- 107,112 ----
*************** gimple_current_bind_expr (void)
*** 208,250 ****
    return gimplify_ctxp->current_bind_expr;
  }
  
- /* Returns true iff there is a COND_EXPR between us and the innermost
-    CLEANUP_POINT_EXPR.  This info is used by gimple_push_cleanup.  */
- 
- static bool
- gimple_conditional_context (void)
- {
-   return gimplify_ctxp->conditions > 0;
- }
- 
- /* Note that we've entered a COND_EXPR.  */
- 
- static void
- gimple_push_condition (void)
- {
- #ifdef ENABLE_CHECKING
-   if (gimplify_ctxp->conditions == 0)
-     gcc_assert (!gimplify_ctxp->conditional_cleanups);
- #endif
-   ++(gimplify_ctxp->conditions);
- }
- 
- /* Note that we've left a COND_EXPR.  If we're back at unconditional scope
-    now, add any conditional cleanups we've seen to the prequeue.  */
- 
- static void
- gimple_pop_condition (tree *pre_p)
- {
-   int conds = --(gimplify_ctxp->conditions);
- 
-   gcc_assert (conds >= 0);
-   if (conds == 0)
-     {
-       append_to_statement_list (gimplify_ctxp->conditional_cleanups, pre_p);
-       gimplify_ctxp->conditional_cleanups = NULL_TREE;
-     }
- }
- 
  /* A stable comparison routine for use with splay trees and DECLs.  */
  
  static int
--- 225,230 ----
*************** gimplify_cond_expr (tree *expr_p, tree *
*** 2430,2444 ****
        if (expr != *expr_p)
  	{
  	  *expr_p = expr;
- 
- 	  /* We can't rely on gimplify_expr to re-gimplify the expanded
- 	     form properly, as cleanups might cause the target labels to be
- 	     wrapped in a TRY_FINALLY_EXPR.  To prevent that, we need to
- 	     set up a conditional context.  */
- 	  gimple_push_condition ();
  	  gimplify_stmt (expr_p);
- 	  gimple_pop_condition (pre_p);
- 
  	  return GS_ALL_DONE;
  	}
      }
--- 2410,2416 ----
*************** gimplify_cond_expr (tree *expr_p, tree *
*** 2447,2460 ****
    ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
  		       is_gimple_condexpr, fb_rvalue);
  
-   gimple_push_condition ();
- 
    gimplify_to_stmt_list (&TREE_OPERAND (expr, 1));
    gimplify_to_stmt_list (&TREE_OPERAND (expr, 2));
    recalculate_side_effects (expr);
  
-   gimple_pop_condition (pre_p);
- 
    if (ret == GS_ERROR)
      ;
    else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
--- 2419,2428 ----
*************** gimplify_asm_expr (tree *expr_p, tree *p
*** 3895,3971 ****
    return ret;
  }
  
! /* Gimplify a CLEANUP_POINT_EXPR.  Currently this works by adding
!    WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
!    gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
!    return to this function.
! 
!    FIXME should we complexify the prequeue handling instead?  Or use flags
!    for all the cleanups and let the optimizer tighten them up?  The current
!    code seems pretty fragile; it will break on a cleanup within any
!    non-conditional nesting.  But any such nesting would be broken, anyway;
!    we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
!    and continues out of it.  We can do that at the RTL level, though, so
!    having an optimizer to tighten up try/finally regions would be a Good
!    Thing.  */
  
  static enum gimplify_status
  gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
  {
-   tree_stmt_iterator iter;
    tree body;
- 
    tree temp = voidify_wrapper_expr (*expr_p, NULL);
  
!   /* We only care about the number of conditions between the innermost
!      CLEANUP_POINT_EXPR and the cleanup.  So save and reset the count and
!      any cleanups collected outside the CLEANUP_POINT_EXPR.  */
!   int old_conds = gimplify_ctxp->conditions;
!   tree old_cleanups = gimplify_ctxp->conditional_cleanups;
!   gimplify_ctxp->conditions = 0;
!   gimplify_ctxp->conditional_cleanups = NULL_TREE;
  
    body = TREE_OPERAND (*expr_p, 0);
    gimplify_to_stmt_list (&body);
  
!   gimplify_ctxp->conditions = old_conds;
!   gimplify_ctxp->conditional_cleanups = old_cleanups;
! 
!   for (iter = tsi_start (body); !tsi_end_p (iter); )
      {
!       tree *wce_p = tsi_stmt_ptr (iter);
!       tree wce = *wce_p;
  
!       if (TREE_CODE (wce) == WITH_CLEANUP_EXPR)
! 	{
! 	  if (tsi_one_before_end_p (iter))
! 	    {
! 	      tsi_link_before (&iter, TREE_OPERAND (wce, 0), TSI_SAME_STMT);
! 	      tsi_delink (&iter);
! 	      break;
! 	    }
! 	  else
! 	    {
! 	      tree sl, tfe;
! 	      enum tree_code code;
  
! 	      if (CLEANUP_EH_ONLY (wce))
! 		code = TRY_CATCH_EXPR;
! 	      else
! 		code = TRY_FINALLY_EXPR;
  
! 	      sl = tsi_split_statement_list_after (&iter);
! 	      tfe = build2 (code, void_type_node, sl, NULL_TREE);
! 	      append_to_statement_list (TREE_OPERAND (wce, 0),
! 				        &TREE_OPERAND (tfe, 1));
! 	      *wce_p = tfe;
! 	      iter = tsi_start (sl);
! 	    }
! 	}
!       else
! 	tsi_next (&iter);
      }
  
    if (temp)
      {
        *expr_p = temp;
--- 3863,3908 ----
    return ret;
  }
  
! /* Gimplify a CLEANUP_POINT_EXPR.  */
  
  static enum gimplify_status
  gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
  {
    tree body;
    tree temp = voidify_wrapper_expr (*expr_p, NULL);
+   struct cleanup *old_cleanups = gimplify_ctxp->cleanups;
+   struct cleanup *ac, *next;
  
!   gimplify_ctxp->cleanups = NULL;
  
    body = TREE_OPERAND (*expr_p, 0);
    gimplify_to_stmt_list (&body);
  
!   /* Execute the cleanups in the reverse order.  */
!   for (ac = gimplify_ctxp->cleanups; ac; ac = next)
      {
!       tree cleanups = NULL_TREE;
!       tree cond;
!       tree nbody = NULL_TREE;
  
!       next = ac->next;
  
!       cond = build3 (COND_EXPR, void_type_node,
! 		     ac->guard, ac->cleanup, alloc_stmt_list ());
!       append_to_statement_list (cond, &cleanups);
  
!       append_to_statement_list (build2 (MODIFY_EXPR, void_type_node,
! 					ac->guard, boolean_false_node),
! 				&nbody);
!       append_to_statement_list (body, &nbody);
! 
!       body = build2 (ac->eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR,
! 		     void_type_node, nbody, cleanups);
!       free (ac);
      }
  
+   gimplify_ctxp->cleanups = old_cleanups;
+ 
    if (temp)
      {
        *expr_p = temp;
*************** gimplify_cleanup_point_expr (tree *expr_
*** 3985,4044 ****
  static void
  gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
  {
!   tree wce;
  
    /* Errors can result in improperly nested cleanups.  Which results in
       confusion when trying to resolve the WITH_CLEANUP_EXPR.  */
    if (errorcount || sorrycount)
      return;
  
!   if (gimple_conditional_context ())
!     {
!       /* If we're in a conditional context, this is more complex.  We only
! 	 want to run the cleanup if we actually ran the initialization that
! 	 necessitates it, but we want to run it after the end of the
! 	 conditional context.  So we wrap the try/finally around the
! 	 condition and use a flag to determine whether or not to actually
! 	 run the destructor.  Thus
! 
! 	   test ? f(A()) : 0
! 
! 	 becomes (approximately)
! 
! 	   flag = 0;
! 	   try {
! 	     if (test) { A::A(temp); flag = 1; val = f(temp); }
! 	     else { val = 0; }
! 	   } finally {
! 	     if (flag) A::~A(temp);
! 	   }
! 	   val
!       */
! 
!       tree flag = create_tmp_var (boolean_type_node, "cleanup");
!       tree ffalse = build2 (MODIFY_EXPR, void_type_node, flag,
! 			    boolean_false_node);
!       tree ftrue = build2 (MODIFY_EXPR, void_type_node, flag,
! 			   boolean_true_node);
!       cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
!       wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
!       append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups);
!       append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups);
!       append_to_statement_list (ftrue, pre_p);
! 
!       /* Because of this manipulation, and the EH edges that jump
! 	 threading cannot redirect, the temporary (VAR) will appear
! 	 to be used uninitialized.  Don't warn.  */
!       TREE_NO_WARNING (var) = 1;
!     }
!   else
!     {
!       wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
!       CLEANUP_EH_ONLY (wce) = eh_only;
!       append_to_statement_list (wce, pre_p);
!     }
  
!   gimplify_stmt (&TREE_OPERAND (wce, 0));
  }
  
  /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR.  */
--- 3922,3951 ----
  static void
  gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
  {
!   struct cleanup *ac;
  
    /* Errors can result in improperly nested cleanups.  Which results in
       confusion when trying to resolve the WITH_CLEANUP_EXPR.  */
    if (errorcount || sorrycount)
      return;
  
!   gimplify_to_stmt_list (&cleanup);
! 
!   ac = xmalloc (sizeof (struct cleanup));
!   ac->eh_only = eh_only;
!   ac->cleanup = cleanup;
!   ac->guard = create_tmp_var (boolean_type_node, "cleanup");
!   ac->next = gimplify_ctxp->cleanups;
!   gimplify_ctxp->cleanups = ac;
! 
!   /* Because of the guards, and the EH edges that jump threading cannot
!      redirect, the temporary (VAR) may appear to be used uninitialized
!      in the cleanup.  Don't warn.  */
!   TREE_NO_WARNING (var) = 1;
  
!   append_to_statement_list (build2 (MODIFY_EXPR, void_type_node,
! 				    ac->guard, boolean_true_node),
! 			    pre_p);
  }
  
  /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR.  */
Index: tree-pretty-print.c
===================================================================
*** tree-pretty-print.c	(revision 110257)
--- tree-pretty-print.c	(working copy)
*************** static int op_prio (tree);
*** 39,57 ****
  static const char *op_symbol_1 (enum tree_code);
  static const char *op_symbol (tree);
  static void pretty_print_string (pretty_printer *, const char*);
! static void print_call_name (pretty_printer *, tree);
  static void newline_and_indent (pretty_printer *, int);
  static void maybe_init_pretty_print (FILE *);
  static void print_declaration (pretty_printer *, tree, int, int);
  static void print_struct_decl (pretty_printer *, tree, int, int);
! static void do_niy (pretty_printer *, tree);
  static void dump_vops (pretty_printer *, tree, int, int);
  static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
  
  #define INDENT(SPACE) do { \
    int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
  
! #define NIY do_niy(buffer,node)
  
  #define PRINT_FUNCTION_NAME(NODE)  pp_printf             \
    (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ?              \
--- 39,57 ----
  static const char *op_symbol_1 (enum tree_code);
  static const char *op_symbol (tree);
  static void pretty_print_string (pretty_printer *, const char*);
! static void print_call_name (pretty_printer *, tree, int);
  static void newline_and_indent (pretty_printer *, int);
  static void maybe_init_pretty_print (FILE *);
  static void print_declaration (pretty_printer *, tree, int, int);
  static void print_struct_decl (pretty_printer *, tree, int, int);
! static void do_niy (pretty_printer *, tree, int);
  static void dump_vops (pretty_printer *, tree, int, int);
  static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
  
  #define INDENT(SPACE) do { \
    int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
  
! #define NIY do_niy(buffer, node, spc)
  
  #define PRINT_FUNCTION_NAME(NODE)  pp_printf             \
    (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ?              \
*************** static int initialized = 0;
*** 64,70 ****
  /* Try to print something for an unknown tree code.  */
  
  static void
! do_niy (pretty_printer *buffer, tree node)
  {
    int i, len;
  
--- 64,70 ----
  /* Try to print something for an unknown tree code.  */
  
  static void
! do_niy (pretty_printer *buffer, tree node, int spc)
  {
    int i, len;
  
*************** do_niy (pretty_printer *buffer, tree nod
*** 76,83 ****
        len = TREE_CODE_LENGTH (TREE_CODE (node));
        for (i = 0; i < len; ++i)
  	{
! 	  newline_and_indent (buffer, 2);
! 	  dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0, false);
  	}
      }
  
--- 76,83 ----
        len = TREE_CODE_LENGTH (TREE_CODE (node));
        for (i = 0; i < len; ++i)
  	{
! 	  newline_and_indent (buffer, spc + 2);
! 	  dump_generic_node (buffer, TREE_OPERAND (node, i), spc + 2, 0, true);
  	}
      }
  
*************** dump_generic_node (pretty_printer *buffe
*** 980,987 ****
  	  }
  
  	dump_generic_node (buffer, TREE_OPERAND (node, 0),
! 			   spc, flags, !(flags & TDF_SLIM));
! 	if (flags & TDF_SLIM)
  	  newline_and_indent (buffer, spc);
  	else
  	  {
--- 980,987 ----
  	  }
  
  	dump_generic_node (buffer, TREE_OPERAND (node, 0),
! 			   spc, flags, is_stmt);
! 	if (is_stmt)
  	  newline_and_indent (buffer, spc);
  	else
  	  {
*************** dump_generic_node (pretty_printer *buffe
*** 994,1001 ****
  	     tp = &TREE_OPERAND (*tp, 1))
  	  {
  	    dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
! 			       spc, flags, !(flags & TDF_SLIM));
! 	    if (flags & TDF_SLIM)
  	      newline_and_indent (buffer, spc);
  	    else
  	      {
--- 994,1001 ----
  	     tp = &TREE_OPERAND (*tp, 1))
  	  {
  	    dump_generic_node (buffer, TREE_OPERAND (*tp, 0),
! 			       spc, flags, is_stmt);
! 	    if (is_stmt)
  	      newline_and_indent (buffer, spc);
  	    else
  	      {
*************** dump_generic_node (pretty_printer *buffe
*** 1004,1010 ****
  	      }
  	  }
  
! 	dump_generic_node (buffer, *tp, spc, flags, !(flags & TDF_SLIM));
        }
        break;
  
--- 1004,1010 ----
  	      }
  	  }
  
! 	dump_generic_node (buffer, *tp, spc, flags, is_stmt);
        }
        break;
  
*************** dump_generic_node (pretty_printer *buffe
*** 1042,1050 ****
      case TARGET_EXPR:
        pp_string (buffer, "TARGET_EXPR <");
        dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
!       pp_character (buffer, ',');
!       pp_space (buffer);
!       dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
        pp_character (buffer, '>');
        break;
  
--- 1042,1057 ----
      case TARGET_EXPR:
        pp_string (buffer, "TARGET_EXPR <");
        dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
!       newline_and_indent (buffer, spc+2);
!       pp_string (buffer, "init: ");
!       dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc + 8, flags, true);
!       if (TARGET_EXPR_CLEANUP (node))
! 	{
! 	  newline_and_indent (buffer, spc+2);
! 	  pp_string (buffer, "clean: ");
! 	  dump_generic_node (buffer, TARGET_EXPR_CLEANUP (node), spc + 9, flags, true);
! 	}
!       newline_and_indent (buffer, spc+2);
        pp_character (buffer, '>');
        break;
  
*************** dump_generic_node (pretty_printer *buffe
*** 1140,1146 ****
        break;
  
      case CALL_EXPR:
!       print_call_name (buffer, node);
  
        /* Print parameters.  */
        pp_space (buffer);
--- 1147,1153 ----
        break;
  
      case CALL_EXPR:
!       print_call_name (buffer, node, spc);
  
        /* Print parameters.  */
        pp_space (buffer);
*************** dump_generic_node (pretty_printer *buffe
*** 1169,1176 ****
        break;
  
      case CLEANUP_POINT_EXPR:
!       pp_string (buffer, "<<cleanup_point ");
!       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
        pp_string (buffer, ">>");
        break;
  
--- 1176,1186 ----
        break;
  
      case CLEANUP_POINT_EXPR:
!       pp_string (buffer, "<<cleanup_point");
!       newline_and_indent (buffer, spc + 2);
!       dump_generic_node (buffer, TREE_OPERAND (node, 0),
! 			 spc + 2, flags, true);
!       newline_and_indent (buffer, spc + 2);
        pp_string (buffer, ">>");
        break;
  
*************** dump_generic_node (pretty_printer *buffe
*** 1414,1421 ****
        newline_and_indent (buffer, spc+2);
        pp_string (buffer, "}");
        newline_and_indent (buffer, spc);
!       pp_string (buffer,
! 			 (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
        newline_and_indent (buffer, spc+2);
        pp_string (buffer, "{");
        newline_and_indent (buffer, spc+4);
--- 1424,1430 ----
        newline_and_indent (buffer, spc+2);
        pp_string (buffer, "}");
        newline_and_indent (buffer, spc);
!       pp_string (buffer, (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
        newline_and_indent (buffer, spc+2);
        pp_string (buffer, "{");
        newline_and_indent (buffer, spc+4);
*************** op_symbol (tree op)
*** 2402,2408 ****
  /* Prints the name of a CALL_EXPR.  */
  
  static void
! print_call_name (pretty_printer *buffer, tree node)
  {
    tree op0;
  
--- 2411,2417 ----
  /* Prints the name of a CALL_EXPR.  */
  
  static void
! print_call_name (pretty_printer *buffer, tree node, int spc)
  {
    tree op0;
  
*************** print_call_name (pretty_printer *buffer,
*** 2423,2438 ****
      case ADDR_EXPR:
      case INDIRECT_REF:
      case NOP_EXPR:
!       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
        break;
  
      case COND_EXPR:
        pp_string (buffer, "(");
!       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
        pp_string (buffer, ") ? ");
!       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0, false);
        pp_string (buffer, " : ");
!       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0, false);
        break;
  
      case COMPONENT_REF:
--- 2432,2447 ----
      case ADDR_EXPR:
      case INDIRECT_REF:
      case NOP_EXPR:
!       dump_generic_node (buffer, TREE_OPERAND (op0, 0), spc, 0, false);
        break;
  
      case COND_EXPR:
        pp_string (buffer, "(");
!       dump_generic_node (buffer, TREE_OPERAND (op0, 0), spc, 0, false);
        pp_string (buffer, ") ? ");
!       dump_generic_node (buffer, TREE_OPERAND (op0, 1), spc, 0, false);
        pp_string (buffer, " : ");
!       dump_generic_node (buffer, TREE_OPERAND (op0, 2), spc, 0, false);
        break;
  
      case COMPONENT_REF:
*************** print_call_name (pretty_printer *buffer,
*** 2441,2447 ****
  	  TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
  	dump_function_name (buffer, TREE_OPERAND (op0, 1));
        else
! 	dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
        /* else
  	 We can have several levels of structures and a function
  	 pointer inside.  This is not implemented yet...  */
--- 2450,2456 ----
  	  TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
  	dump_function_name (buffer, TREE_OPERAND (op0, 1));
        else
! 	dump_generic_node (buffer, TREE_OPERAND (op0, 0), spc, 0, false);
        /* else
  	 We can have several levels of structures and a function
  	 pointer inside.  This is not implemented yet...  */
*************** print_call_name (pretty_printer *buffer,
*** 2452,2463 ****
        if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
  	dump_function_name (buffer, TREE_OPERAND (op0, 0));
        else
! 	dump_generic_node (buffer, op0, 0, 0, false);
        break;
  
      case SSA_NAME:
      case OBJ_TYPE_REF:
!       dump_generic_node (buffer, op0, 0, 0, false);
        break;
  
      default:
--- 2461,2472 ----
        if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
  	dump_function_name (buffer, TREE_OPERAND (op0, 0));
        else
! 	dump_generic_node (buffer, op0, spc, 0, false);
        break;
  
      case SSA_NAME:
      case OBJ_TYPE_REF:
!       dump_generic_node (buffer, op0, spc, 0, false);
        break;
  
      default:



More information about the Gcc-patches mailing list