This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] gimplify-unit-at-a-time (final)


This is the final patch implementing gimplifying unit-at-a-time.
Approval is needed for the C++, C, Ada, Java and Fortran frontend
changes.


This is moving GCC to gimplification unit-at-a-time, the point where
frontends are supposed to hand off to the middle-end and should be
able to cope with all frontend specific data dropped.

Patch originally from Michael Matz, routed through Tom Tromey on the
incremental compiler branch and now with me, adapted to tuples and
massaged to really do gimplification unit-at-a-time also for C++.

Open tasks are emitting associated C++ thunks from cgraph_analyze_function,
not cgraph_expand_function.  Diego will deal with that as part of
the LTO merge.

Now on to the patch - what it does is the following:

 - frontends now hand GENERIC bodies to the cgraph
   (this means that with the state of the patch C++ does cloning in
    GENERIC again, some issues around copying statement lists and
    target exprs have been fixed in this patch)
 - cgraph_finalize_compilation_unit is the switch from FE to middle-end,
   this function drives the further compilation
 - before running early optimizations we go all the way through
   gimplifying, all_lowering_passes, previously we had all (sofar
   queued) bodies gimplified before starting the lowering process.
 - OpenMP structured block error reporting and diagnosing
   warn_unused_result function calls is moved to separate passes after
   gimplification

Memory and compile-time effects of this patch on tramp3d are in the noise.
On CSiBE I see around 4% compile-time improvement, likewise for some
C++ testcases.  This is likely due to two reasons:

 1) We no longer gimplify functions that are not reachable in the cgraph
    (this is also resposible for the g++.dg/warn/unused-result1.C XFAIL)
 2) GC memory locality should be improved, the frontends memory
    allocations no longer interfere with those of the gimple data structures

The patch enables easy integration of the LTO free-lang-specific-data
pass (which, after fixing thunks and debug information issues would be
a general improvement also for non-LTO mode).

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Ok for trunk?

Thanks,
Richard.


	* tree-pass.h (pass_diagnose_omp_blocks): Declare.
	(pass_warn_unused_result): Likewise.
	(TODO_set_props): Remove.
	* omp-low.c (diagnose_omp_structured_block_errors): Change to
	run as a pass.
	(pass_diagnose_omp_blocks): Define.
	* c-decl.c (pop_file_scope): Do not finalize the CU here.
	(c_gimple_diagnostics_recursively): Remove.
	(finish_function): Do not call it.
	(c_write_global_declarations): Continue after errors.
	Finalize the CU here.
	* c-gimplify.c (c_genericize): Do not gimplify here.
	* c-common.c (c_warn_unused_result): Move ...
	* tree-cfg.c (warn_unused_result): ... here.
	(run_warn_unused_result): New function.
	(gate_warn_unused_result): New function.
	(pass_warn_unused_result): New pass.
	* c-common.h (c_warn_unused_result): Remove.
	* flags.h (flag_warn_unused_result): Declare.
	* c-opts.c (c_common_init_options): Enable flag_warn_unused_result.
	* opts.c (flag_warn_unused_result): Initialize to false.

	* toplev.c (compile_file): Add comment.
	* omp-low.c (create_omp_child_function): Do not register
	the function with the frontend.
	(diagnose_omp_structured_block_errors): Prepare to be
	called as optimization pass.
	(gate_diagnose_omp_blocks): New function.
	(pass_diagnose_omp_blocks): New pass.
	* cgraph.h (cgraph_optimize): Remove.
	(cgraph_analyze_function): Likewise.
	* cgraph.c (cgraph_add_new_function): Gimplify C++ thunks.
	* cgraphunit.c (cgraph_lower_function): Lower nested functions
	before their parents here.
	(cgraph_finalize_function): Not here.
	(cgraph_analyze_function): Gimplify functions here.
	(cgraph_finalize_compilation_unit): Continue after errors.
	Optimize the callgraph from here.
	(cgraph_optimize): Make static.
	* langhooks.c (write_global_declarations): Finalize the CU.
	* gimplify.c (gimplify_asm_expr): Do not emit ASMs with errors.
	(gimplify_function_tree): Assert we gimplify only once.
	Set PROP_gimple_any property.
	* tree-nested.c (gimplify_all_functions): New function.
	(lower_nested_functions): Gimplify all nested functions.
	* gimple.h (diagnose_omp_structured_block_errors): Remove.
	* passes.c (init_optimization_passes): Add pass_warn_unused_result
	and pass_diagnose_omp_blocks after gimplification.  Do not
	set TODO_set_props on all_lowering_passes.
	(execute_one_pass): Do not handle TODO_set_props.
	* Makefile.in (cgraphunit.o): Add $(TREE_DUMP_H) dependency.
	(gimplify.o): Add tree-pass.h dependency.
	* tree-inline.c (copy_statement_list): Properly copy STATEMENT_LIST.
	(copy_tree_body_r): Properly handle TARGET_EXPR like SAVE_EXPR.
	Fixup constant parameter types.
	(unsave_r): Likewise.
	* c-omp.c (c_finish_omp_atomic): Set DECL_CONTEXT on the
	temporary variable.

	cp/
	* decl.c (finish_function): Do not emit unused result warnings
	from here.
	* cp-objcp-common.h (LANG_HOOKS_POST_GIMPLIFY_PASS): Use
	c_warn_unused_result_pass.
	* semantics.c (expand_or_defer_fn): Adjust assertion about IL status.
	* optimize.c (clone_body): Clone in GENERIC.
	(maybe_clone_body): Do not clear DECL_SAVED_TREE.
	* decl2.c (cp_write_global_declarations): Fix body test.
	Do not call cgraph_optimize.
	* Make-lang.in (optimize.o): Add tree-iterator.h dependency.
	* method.c (use_thunk): Register thunk with
	cgraph_finalize_function.
	* error.c (function_category): Guard access of DECL_LANG_SPECIFIC.

	java/
	* java-gimplify.c (java_genericize): Do not gimplify here.
	But replace all local references.
	(java_gimplify_expr): Do not replace local references here.
	(java_gimplify_modify_expr): Likewise.
	* jcf-parse.c (java_parse_file): Do not finalize the CU or
	optimize the cgraph here.
	* decl.c (java_replace_references): New function.
	(end_java_method): Clear base_decl_map.
	* java-tree.h (java_replace_references): Declare.

	ada/
	* utils.c (end_subprog_body): Revert to pre-tuples state.
	(gnat_gimplify_function): Do not gimplify here.
	(gnat_write_global_declarations): Also finalize the CU.
	* misc.c (gnat_parse_file): Do not finalize the CU here.
	* trans.c (gigi): Revert to pre-tuples state.

	fortran/
	* f95-lang.c (gfc_be_parse_file): Do not finalize the CU here.
	* trans-decl.c (gfc_gimplify_function): Remove.
	(build_entry_thunks): Do not gimplify here.
	(create_main_function): Likewise.
	(gfc_generate_function_code): Likewise.

	* g++.dg/rtti/crash4.C: New testcase.
	* g++.dg/torture/20090706-1.C: Likewise.

	* gfortran.dg/missing_optional_dummy_5.f90: Adjust pattern.
	* gcc.dg/declspec-9.c: Expect extra error.
	* gcc.dg/declspec-10.c: Likewise.
	* gcc.dg/declspec-11.c: Likewise.
	* gcc.dg/redecl-10.c: Expect extra warnings.
	* gcc.target/i386/pr39082-1.c: Adjust diagnostic location.
	* gcc.target/i386/pr39545-1.c: Likewise.
	* g++.dg/ext/asm3.C: Expect more errors.
	* g++.dg/gomp/block-1.C: Likewise.
	* g++.dg/gomp/block-2.C: Likewise.
	* g++.dg/gomp/block-3.C: Likewise.
	* g++.dg/gomp/block-5.C: Likewise.
	* g++.old-deja/g++.jason/report.C: Expect extra warnings.
	* g++.dg/warn/unused-result1.C: XFAIL.

Index: gcc/java/java-gimplify.c
===================================================================
*** gcc/java/java-gimplify.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/java/java-gimplify.c	2009-07-07 13:25:56.000000000 +0200
*************** static void dump_java_tree (enum tree_du
*** 44,55 ****
  void
  java_genericize (tree fndecl)
  {
    dump_java_tree (TDI_original, fndecl);
- 
-   /* Genericize with the gimplifier.  */
-   gimplify_function_tree (fndecl);
- 
-   dump_function (TDI_generic, fndecl);
  }
  
  /* Gimplify a Java tree.  */
--- 44,51 ----
  void
  java_genericize (tree fndecl)
  {
+   walk_tree (&DECL_SAVED_TREE (fndecl), java_replace_references, NULL, NULL);
    dump_java_tree (TDI_original, fndecl);
  }
  
  /* Gimplify a Java tree.  */
*************** java_gimplify_expr (tree *expr_p, gimple
*** 65,87 ****
        *expr_p = java_gimplify_block (*expr_p);
        break;
  
-     case VAR_DECL:
-       *expr_p = java_replace_reference (*expr_p, /* want_lvalue */ false);
-       return GS_UNHANDLED;
- 
      case MODIFY_EXPR:
        return java_gimplify_modify_expr (expr_p);
  
-     case SAVE_EXPR:
-       /* Note that we can see <save_expr NULL> if the save_expr was
- 	 already handled by gimplify_save_expr.  */
-       if (TREE_OPERAND (*expr_p, 0) != NULL_TREE
- 	  && TREE_CODE (TREE_OPERAND (*expr_p, 0)) == VAR_DECL)
- 	TREE_OPERAND (*expr_p, 0) 
- 	  = java_replace_reference (TREE_OPERAND (*expr_p, 0), 
- 			       /* want_lvalue */ false);
-       return GS_UNHANDLED;
- 
      case POSTINCREMENT_EXPR:
      case POSTDECREMENT_EXPR:
      case PREINCREMENT_EXPR:
--- 61,69 ----
*************** java_gimplify_modify_expr (tree *modify_
*** 110,136 ****
    tree rhs = TREE_OPERAND (modify_expr, 1);
    tree lhs_type = TREE_TYPE (lhs);
  
!   /* This is specific to the bytecode compiler.  If a variable has
!      LOCAL_SLOT_P set, replace an assignment to it with an assignment
!      to the corresponding variable that holds all its aliases.  */
!   if (TREE_CODE (lhs) == VAR_DECL
!       && DECL_LANG_SPECIFIC (lhs)
!       && LOCAL_SLOT_P (lhs)
!       && TREE_CODE (lhs_type) == POINTER_TYPE)
!     {
!       tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true);
!       tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs), rhs);
!       modify_expr = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs),
! 			    new_lhs, new_rhs);
!       modify_expr = build1 (NOP_EXPR, lhs_type, modify_expr);
!     }
!   else if (lhs_type != TREE_TYPE (rhs))
      /* Fix up type mismatches to make legal GIMPLE.  These are
         generated in several places, in particular null pointer
         assignment and subclass assignment.  */
      TREE_OPERAND (modify_expr, 1) = convert (lhs_type, rhs);
  
-   *modify_expr_p = modify_expr;
    return GS_UNHANDLED;
  }
  
--- 92,103 ----
    tree rhs = TREE_OPERAND (modify_expr, 1);
    tree lhs_type = TREE_TYPE (lhs);
  
!   if (lhs_type != TREE_TYPE (rhs))
      /* Fix up type mismatches to make legal GIMPLE.  These are
         generated in several places, in particular null pointer
         assignment and subclass assignment.  */
      TREE_OPERAND (modify_expr, 1) = convert (lhs_type, rhs);
  
    return GS_UNHANDLED;
  }
  
Index: gcc/java/jcf-parse.c
===================================================================
*** gcc/java/jcf-parse.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/java/jcf-parse.c	2009-07-07 13:25:56.000000000 +0200
*************** java_parse_file (int set_yydebug ATTRIBU
*** 1982,1992 ****
    /* Arrange for any necessary initialization to happen.  */
    java_emit_static_constructor ();
    gcc_assert (global_bindings_p ());
- 
-   /* Only finalize the compilation unit after we've told cgraph which
-      functions have their addresses stored.  */
-   cgraph_finalize_compilation_unit ();
-   cgraph_optimize ();
  }
  
  
--- 1982,1987 ----
Index: gcc/tree-pass.h
===================================================================
*** gcc/tree-pass.h.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/tree-pass.h	2009-07-07 13:25:56.000000000 +0200
*************** struct dump_file_info
*** 279,288 ****
     and the memory footprint for VAR_DECLs.  */
  #define TODO_remove_unused_locals	(1 << 15)
  
- /* Internally used for the first in a sequence of passes.  It is set
-    for the passes that are handed to register_dump_files.  */
- #define TODO_set_props			(1 << 16)
- 
  /* Call df_finish at the end of the pass.  This is done after all of
     the dumpers have been allowed to run so that they have access to
     the instance before it is destroyed.  */
--- 279,284 ----
*************** extern struct gimple_opt_pass pass_lower
*** 370,375 ****
--- 366,372 ----
  extern struct gimple_opt_pass pass_lower_vector;
  extern struct gimple_opt_pass pass_lower_vector_ssa;
  extern struct gimple_opt_pass pass_lower_omp;
+ extern struct gimple_opt_pass pass_diagnose_omp_blocks;
  extern struct gimple_opt_pass pass_expand_omp;
  extern struct gimple_opt_pass pass_expand_omp_ssa;
  extern struct gimple_opt_pass pass_object_sizes;
*************** extern struct gimple_opt_pass pass_remov
*** 406,411 ****
--- 403,409 ----
  extern struct gimple_opt_pass pass_build_cgraph_edges;
  extern struct gimple_opt_pass pass_local_pure_const;
  extern struct gimple_opt_pass pass_tracer;
+ extern struct gimple_opt_pass pass_warn_unused_result;
  
  /* IPA Passes */
  extern struct ipa_opt_pass_d pass_ipa_inline;
Index: gcc/omp-low.c
===================================================================
*** gcc/omp-low.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/omp-low.c	2009-07-07 13:25:56.000000000 +0200
*************** create_omp_child_function (omp_context *
*** 1560,1566 ****
  
    decl = build_decl (gimple_location (ctx->stmt),
  		     FUNCTION_DECL, name, type);
-   decl = lang_hooks.decls.pushdecl (decl);
  
    if (!task_copy)
      ctx->cb.dst_fn = decl;
--- 1560,1565 ----
*************** diagnose_sb_2 (gimple_stmt_iterator *gsi
*** 6853,6868 ****
    return NULL_TREE;
  }
  
! void
! diagnose_omp_structured_block_errors (tree fndecl)
  {
-   tree save_current = current_function_decl;
    struct walk_stmt_info wi;
!   struct function *old_cfun = cfun;
!   gimple_seq body = gimple_body (fndecl);
! 
!   current_function_decl = fndecl;
!   set_cfun (DECL_STRUCT_FUNCTION (fndecl));
  
    all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  
--- 6852,6862 ----
    return NULL_TREE;
  }
  
! static unsigned int
! diagnose_omp_structured_block_errors (void)
  {
    struct walk_stmt_info wi;
!   gimple_seq body = gimple_body (current_function_decl);
  
    all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  
*************** diagnose_omp_structured_block_errors (tr
*** 6876,6883 ****
    splay_tree_delete (all_labels);
    all_labels = NULL;
  
!   set_cfun (old_cfun);
!   current_function_decl = save_current;
  }
  
  #include "gt-omp-low.h"
--- 6870,6901 ----
    splay_tree_delete (all_labels);
    all_labels = NULL;
  
!   return 0;
  }
  
+ static bool
+ gate_diagnose_omp_blocks (void)
+ {
+   return flag_openmp != 0;
+ }
+ 
+ struct gimple_opt_pass pass_diagnose_omp_blocks =
+ {
+   {
+     GIMPLE_PASS,
+     "diagnose_omp_blocks",		/* name */
+     gate_diagnose_omp_blocks,		/* gate */
+     diagnose_omp_structured_block_errors,	/* execute */
+     NULL,				/* sub */
+     NULL,				/* next */
+     0,					/* static_pass_number */
+     TV_NONE,				/* tv_id */
+     PROP_gimple_any,			/* properties_required */
+     0,					/* properties_provided */
+     0,					/* properties_destroyed */
+     0,					/* todo_flags_start */
+     0,					/* todo_flags_finish */
+   }
+ };
+ 
  #include "gt-omp-low.h"
Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/toplev.c	2009-07-07 13:25:56.000000000 +0200
*************** compile_file (void)
*** 1034,1039 ****
--- 1034,1041 ----
  
    ggc_protect_identifiers = false;
  
+   /* This must also call cgraph_finalize_compilation_unit and
+      cgraph_optimize.  */
    lang_hooks.decls.final_write_globals ();
  
    if (errorcount || sorrycount)
Index: gcc/cgraphunit.c
===================================================================
*** gcc/cgraphunit.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/cgraphunit.c	2009-07-07 13:25:56.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 132,137 ****
--- 132,138 ----
  #include "gimple.h"
  #include "tree-iterator.h"
  #include "tree-pass.h"
+ #include "tree-dump.h"
  #include "output.h"
  #include "coverage.h"
  
*************** static void cgraph_expand_all_functions
*** 139,144 ****
--- 140,147 ----
  static void cgraph_mark_functions_to_output (void);
  static void cgraph_expand_function (struct cgraph_node *);
  static void cgraph_output_pending_asms (void);
+ static void cgraph_optimize (void);
+ static void cgraph_analyze_function (struct cgraph_node *);
  
  static FILE *cgraph_dump_file;
  
*************** cgraph_lower_function (struct cgraph_nod
*** 489,494 ****
--- 492,502 ----
  {
    if (node->lowered)
      return;
+ 
+   if (node->nested)
+     lower_nested_functions (node->decl);
+   gcc_assert (!node->nested);
+ 
    tree_lowering_passes (node->decl);
    node->lowered = true;
  }
*************** cgraph_finalize_function (tree decl, boo
*** 512,520 ****
    node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
    node->finalized_by_frontend = true;
    record_cdtor_fn (node->decl);
-   if (node->nested)
-     lower_nested_functions (decl);
-   gcc_assert (!node->nested);
  
    if (decide_is_function_needed (node, decl))
      cgraph_mark_needed_node (node);
--- 520,525 ----
*************** cgraph_output_pending_asms (void)
*** 788,805 ****
  }
  
  /* Analyze the function scheduled to be output.  */
! void
  cgraph_analyze_function (struct cgraph_node *node)
  {
    tree decl = node->decl;
  
    current_function_decl = decl;
    push_cfun (DECL_STRUCT_FUNCTION (decl));
    cgraph_lower_function (node);
    node->analyzed = true;
  
    pop_cfun ();
!   current_function_decl = NULL;
  }
  
  /* Look for externally_visible and used attributes and mark cgraph nodes
--- 793,820 ----
  }
  
  /* Analyze the function scheduled to be output.  */
! static void
  cgraph_analyze_function (struct cgraph_node *node)
  {
+   tree save = current_function_decl;
    tree decl = node->decl;
  
    current_function_decl = decl;
    push_cfun (DECL_STRUCT_FUNCTION (decl));
+ 
+   /* Make sure to gimplify bodies only once.  During analyzing a
+      function we lower it, which will require gimplified nested
+      functions, so we can end up here with an already gimplified
+      body.  */
+   if (!gimple_body (decl))
+     gimplify_function_tree (decl);
+   dump_function (TDI_generic, decl);
+ 
    cgraph_lower_function (node);
    node->analyzed = true;
  
    pop_cfun ();
!   current_function_decl = save;
  }
  
  /* Look for externally_visible and used attributes and mark cgraph nodes
*************** cgraph_analyze_functions (void)
*** 934,941 ****
  	}
  
        gcc_assert (!node->analyzed && node->reachable);
-       gcc_assert (gimple_body (decl));
- 
        cgraph_analyze_function (node);
  
        for (edge = node->callees; edge; edge = edge->next_callee)
--- 949,954 ----
*************** cgraph_analyze_functions (void)
*** 1009,1016 ****
  void
  cgraph_finalize_compilation_unit (void)
  {
!   if (errorcount || sorrycount)
!     return;
  
    finalize_size_functions ();
    finish_aliases_1 ();
--- 1022,1029 ----
  void
  cgraph_finalize_compilation_unit (void)
  {
!   /* Do not skip analyzing the functions if there were errors, we
!      miss diagnostics for following functions otherwise.  */
  
    finalize_size_functions ();
    finish_aliases_1 ();
*************** cgraph_finalize_compilation_unit (void)
*** 1024,1029 ****
--- 1037,1044 ----
    timevar_push (TV_CGRAPH);
    cgraph_analyze_functions ();
    timevar_pop (TV_CGRAPH);
+ 
+   cgraph_optimize ();
  }
  
  
*************** ipa_passes (void)
*** 1310,1316 ****
  
  /* Perform simple optimizations based on callgraph.  */
  
! void
  cgraph_optimize (void)
  {
    if (errorcount || sorrycount)
--- 1325,1331 ----
  
  /* Perform simple optimizations based on callgraph.  */
  
! static void
  cgraph_optimize (void)
  {
    if (errorcount || sorrycount)
Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/cp/decl.c	2009-07-07 13:25:56.000000000 +0200
*************** finish_function (int flags)
*** 12412,12420 ****
        f->x_return_value = NULL;
        f->bindings = NULL;
        f->extern_decl_map = NULL;
- 
-       /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
-       c_warn_unused_result (gimple_body (fndecl));
      }
    /* Clear out the bits we don't need.  */
    local_names = NULL;
--- 12412,12417 ----
Index: gcc/cp/semantics.c
===================================================================
*** gcc/cp/semantics.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/cp/semantics.c	2009-07-07 13:25:57.000000000 +0200
*************** expand_or_defer_fn (tree fn)
*** 3226,3232 ****
        return;
      }
  
!   gcc_assert (gimple_body (fn));
  
    /* If this is a constructor or destructor body, we have to clone
       it.  */
--- 3226,3232 ----
        return;
      }
  
!   gcc_assert (DECL_SAVED_TREE (fn));
  
    /* If this is a constructor or destructor body, we have to clone
       it.  */
Index: gcc/ada/gcc-interface/utils.c
===================================================================
*** gcc/ada/gcc-interface/utils.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/ada/gcc-interface/utils.c	2009-07-07 13:25:57.000000000 +0200
*************** gnat_genericize (tree fndecl)
*** 2074,2080 ****
     elaboration routine, to be entirely discarded if empty.  */
  
  void
! end_subprog_body (tree body, bool elab_p)
  {
    tree fndecl = current_function_decl;
  
--- 2074,2080 ----
     elaboration routine, to be entirely discarded if empty.  */
  
  void
! end_subprog_body (tree body, bool elab_p ATTRIBUTE_UNUSED)
  {
    tree fndecl = current_function_decl;
  
*************** end_subprog_body (tree body, bool elab_p
*** 2112,2124 ****
    if (!DECL_CONTEXT (fndecl))
      {
        gnat_gimplify_function (fndecl);
! 
!       /* If this is an empty elaboration proc, just discard the node.
! 	 Otherwise, compile further.  */
!       if (elab_p && empty_body_p (gimple_body (fndecl)))
! 	cgraph_remove_node (cgraph_node (fndecl));
!       else
! 	cgraph_finalize_function (fndecl, false);
      }
    else
      /* Register this function with cgraph just far enough to get it
--- 2112,2118 ----
    if (!DECL_CONTEXT (fndecl))
      {
        gnat_gimplify_function (fndecl);
!       cgraph_finalize_function (fndecl, false);
      }
    else
      /* Register this function with cgraph just far enough to get it
*************** end_subprog_body (tree body, bool elab_p
*** 2126,2132 ****
      (void) cgraph_node (fndecl);
  }
  
! /* Convert FNDECL's code to GIMPLE and handle any nested functions.  */
  
  static void
  gnat_gimplify_function (tree fndecl)
--- 2120,2126 ----
      (void) cgraph_node (fndecl);
  }
  
! /* Dump functions before gimplification.  */
  
  static void
  gnat_gimplify_function (tree fndecl)
*************** gnat_gimplify_function (tree fndecl)
*** 2134,2145 ****
    struct cgraph_node *cgn;
  
    dump_function (TDI_original, fndecl);
-   gimplify_function_tree (fndecl);
-   dump_function (TDI_generic, fndecl);
  
-   /* Convert all nested functions to GIMPLE now.  We do things in this order
-      so that items like VLA sizes are expanded properly in the context of the
-      correct function.  */
    cgn = cgraph_node (fndecl);
    for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
      gnat_gimplify_function (cgn->decl);
--- 2128,2134 ----
*************** gnat_write_global_declarations (void)
*** 4693,4699 ****
  {
    /* Proceed to optimize and emit assembly.
       FIXME: shouldn't be the front end's responsibility to call this.  */
!   cgraph_optimize ();
  
    /* Emit debug info for all global declarations.  */
    emit_debug_global_declarations (VEC_address (tree, global_decls),
--- 4682,4688 ----
  {
    /* Proceed to optimize and emit assembly.
       FIXME: shouldn't be the front end's responsibility to call this.  */
!   cgraph_finalize_compilation_unit ();
  
    /* Emit debug info for all global declarations.  */
    emit_debug_global_declarations (VEC_address (tree, global_decls),
Index: gcc/ada/gcc-interface/misc.c
===================================================================
*** gcc/ada/gcc-interface/misc.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/ada/gcc-interface/misc.c	2009-07-07 13:25:57.000000000 +0200
*************** gnat_parse_file (int set_yydebug ATTRIBU
*** 176,184 ****
  
    /* Call the front end.  */
    _ada_gnat1drv ();
- 
-   /* We always have a single compilation unit in Ada.  */
-   cgraph_finalize_compilation_unit ();
  }
  
  /* Decode all the language specific options that cannot be decoded by GCC.
--- 176,181 ----
Index: gcc/c-decl.c
===================================================================
*** gcc/c-decl.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/c-decl.c	2009-07-07 13:25:57.000000000 +0200
*************** pop_file_scope (void)
*** 1327,1333 ****
    file_scope = 0;
  
    maybe_apply_pending_pragma_weaks ();
-   cgraph_finalize_compilation_unit ();
  }
  
  /* Adjust the bindings for the start of a statement expression.  */
--- 1327,1332 ----
*************** store_parm_decls (void)
*** 7870,7896 ****
    cfun->dont_save_pending_sizes_p = 1;
  }
  
- /* Emit diagnostics that require gimple input for detection.  Operate on
-    FNDECL and all its nested functions.  */
- 
- static void
- c_gimple_diagnostics_recursively (tree fndecl)
- {
-   struct cgraph_node *cgn;
-   gimple_seq body = gimple_body (fndecl);
- 
-   /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
-   c_warn_unused_result (body);
- 
-   /* Notice when OpenMP structured block constraints are violated.  */
-   if (flag_openmp)
-     diagnose_omp_structured_block_errors (fndecl);
- 
-   /* Finalize all nested functions now.  */
-   cgn = cgraph_node (fndecl);
-   for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
-     c_gimple_diagnostics_recursively (cgn->decl);
- }
  
  /* Finish up a function declaration and compile that function
     all the way to assembler language output.  The free the storage
--- 7869,7874 ----
*************** finish_function (void)
*** 7983,7989 ****
        if (!decl_function_context (fndecl))
  	{
  	  c_genericize (fndecl);
- 	  c_gimple_diagnostics_recursively (fndecl);
  
  	  /* ??? Objc emits functions after finalizing the compilation unit.
  	     This should be cleaned up later and this conditional removed.  */
--- 7961,7966 ----
*************** c_write_global_declarations (void)
*** 9382,9390 ****
    if (pch_file)
      return;
  
!   /* Don't waste time on further processing if -fsyntax-only or we've
!      encountered errors.  */
!   if (flag_syntax_only || errorcount || sorrycount)
      return;
  
    /* Close the external scope.  */
--- 9359,9367 ----
    if (pch_file)
      return;
  
!   /* Don't waste time on further processing if -fsyntax-only.
!      Continue for warning and errors issued during lowering though.  */
!   if (flag_syntax_only)
      return;
  
    /* Close the external scope.  */
*************** c_write_global_declarations (void)
*** 9412,9418 ****
  
    /* We're done parsing; proceed to optimize and emit assembly.
       FIXME: shouldn't be the front end's responsibility to call this.  */
!   cgraph_optimize ();
  
    /* After cgraph has had a chance to emit everything that's going to
       be emitted, output debug information for globals.  */
--- 9389,9395 ----
  
    /* We're done parsing; proceed to optimize and emit assembly.
       FIXME: shouldn't be the front end's responsibility to call this.  */
!   cgraph_finalize_compilation_unit ();
  
    /* After cgraph has had a chance to emit everything that's going to
       be emitted, output debug information for globals.  */
Index: gcc/fortran/f95-lang.c
===================================================================
*** gcc/fortran/f95-lang.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/fortran/f95-lang.c	2009-07-07 13:25:57.000000000 +0200
*************** gfc_be_parse_file (int set_yydebug ATTRI
*** 241,249 ****
    gfc_parse_file ();
    gfc_generate_constructors ();
  
-   cgraph_finalize_compilation_unit ();
-   cgraph_optimize ();
- 
    /* Tell the frontend about any errors.  */
    gfc_get_errors (&warnings, &errors);
    errorcount += errors;
--- 241,246 ----
Index: gcc/fortran/trans-decl.c
===================================================================
*** gcc/fortran/trans-decl.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/fortran/trans-decl.c	2009-07-07 13:25:57.000000000 +0200
*************** create_function_arglist (gfc_symbol * sy
*** 1837,1866 ****
    DECL_ARGUMENTS (fndecl) = arglist;
  }
  
- /* Convert FNDECL's code to GIMPLE and handle any nested functions.  */
- 
- static void
- gfc_gimplify_function (tree fndecl)
- {
-   struct cgraph_node *cgn;
- 
-   gimplify_function_tree (fndecl);
-   dump_function (TDI_generic, fndecl);
- 
-   /* Generate errors for structured block violations.  */
-   /* ??? Could be done as part of resolve_labels.  */
-   if (flag_openmp)
-     diagnose_omp_structured_block_errors (fndecl);
- 
-   /* Convert all nested functions to GIMPLE now.  We do things in this order
-      so that items like VLA sizes are expanded properly in the context of the
-      correct function.  */
-   cgn = cgraph_node (fndecl);
-   for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
-     gfc_gimplify_function (cgn->decl);
- }
- 
- 
  /* Do the setup necessary before generating the body of a function.  */
  
  static void
--- 1837,1842 ----
*************** build_entry_thunks (gfc_namespace * ns)
*** 2058,2064 ****
  
        current_function_decl = NULL_TREE;
  
-       gfc_gimplify_function (thunk_fndecl);
        cgraph_finalize_function (thunk_fndecl, false);
  
        /* We share the symbols in the formal argument list with other entry
--- 2034,2039 ----
*************** create_main_function (tree fndecl)
*** 4133,4139 ****
    /* Output the GENERIC tree.  */
    dump_function (TDI_original, ftn_main);
  
-   gfc_gimplify_function (ftn_main);
    cgraph_finalize_function (ftn_main, false);
  
    if (old_context)
--- 4108,4113 ----
*************** gfc_generate_function_code (gfc_namespac
*** 4405,4414 ****
         added to our parent's nested function list.  */
      (void) cgraph_node (fndecl);
    else
!     {
!       gfc_gimplify_function (fndecl);
!       cgraph_finalize_function (fndecl, false);
!     }
  
    gfc_trans_use_stmts (ns);
    gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
--- 4379,4385 ----
         added to our parent's nested function list.  */
      (void) cgraph_node (fndecl);
    else
!     cgraph_finalize_function (fndecl, false);
  
    gfc_trans_use_stmts (ns);
    gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
Index: gcc/langhooks.c
===================================================================
*** gcc/langhooks.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/langhooks.c	2009-07-07 13:25:57.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 37,42 ****
--- 37,43 ----
  #include "langhooks-def.h"
  #include "ggc.h"
  #include "diagnostic.h"
+ #include "cgraph.h"
  
  /* Do nothing; in many cases the default hook.  */
  
*************** lhd_decl_ok_for_sibcall (const_tree decl
*** 305,319 ****
  void
  write_global_declarations (void)
  {
    /* Really define vars that have had only a tentative definition.
       Really output inline functions that must actually be callable
       and have not been output so far.  */
  
!   tree globals = lang_hooks.decls.getdecls ();
!   int len = list_length (globals);
!   tree *vec = XNEWVEC (tree, len);
!   int i;
!   tree decl;
  
    /* Process the decls in reverse order--earliest first.
       Put them into VEC from back to front, then take out from front.  */
--- 306,325 ----
  void
  write_global_declarations (void)
  {
+   tree globals, decl, *vec;
+   int len, i;
+ 
+   /* This lang hook is dual-purposed, and also finalizes the
+      compilation unit.  */
+   cgraph_finalize_compilation_unit ();
+ 
    /* Really define vars that have had only a tentative definition.
       Really output inline functions that must actually be callable
       and have not been output so far.  */
  
!   globals = lang_hooks.decls.getdecls ();
!   len = list_length (globals);
!   vec = XNEWVEC (tree, len);
  
    /* Process the decls in reverse order--earliest first.
       Put them into VEC from back to front, then take out from front.  */
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/gimplify.c	2009-07-07 15:45:35.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 52,57 ****
--- 52,58 ----
  #include "splay-tree.h"
  #include "vec.h"
  #include "gimple.h"
+ #include "tree-pass.h"
  
  
  enum gimplify_omp_var_data
*************** gimplify_asm_expr (tree *expr_p, gimple_
*** 4899,4912 ****
    
    for (link = ASM_CLOBBERS (expr); link; ++i, link = TREE_CHAIN (link))
        VEC_safe_push (tree, gc, clobbers, link);
-     
-   stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
-                                inputs, outputs, clobbers);
  
!   gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr));
!   gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
  
!   gimplify_seq_add_stmt (pre_p, stmt);
  
    return ret;
  }
--- 4900,4917 ----
    
    for (link = ASM_CLOBBERS (expr); link; ++i, link = TREE_CHAIN (link))
        VEC_safe_push (tree, gc, clobbers, link);
  
!   /* Do not add ASMs with errors to the gimple IL stream.  */
!   if (ret != GS_ERROR)
!     {
!       stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
! 				   inputs, outputs, clobbers);
  
!       gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr));
!       gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
! 
!       gimplify_seq_add_stmt (pre_p, stmt);
!     }
  
    return ret;
  }
*************** gimplify_function_tree (tree fndecl)
*** 7467,7472 ****
--- 7472,7479 ----
    gimple_seq seq;
    gimple bind;
  
+   gcc_assert (!gimple_body (fndecl));
+ 
    oldfn = current_function_decl;
    current_function_decl = fndecl;
    if (DECL_STRUCT_FUNCTION (fndecl))
*************** gimplify_function_tree (tree fndecl)
*** 7533,7538 ****
--- 7540,7546 ----
      }
  
    DECL_SAVED_TREE (fndecl) = NULL_TREE;
+   cfun->curr_properties = PROP_gimple_any;
  
    current_function_decl = oldfn;
    pop_cfun ();
Index: gcc/tree-nested.c
===================================================================
*** gcc/tree-nested.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/tree-nested.c	2009-07-07 13:25:57.000000000 +0200
*************** free_nesting_tree (struct nesting_info *
*** 2443,2448 ****
--- 2443,2459 ----
    while (root);
  }
  
+ /* Gimplify a function and all its nested functions.  */
+ static void
+ gimplify_all_functions (struct cgraph_node *root)
+ {
+   struct cgraph_node *iter;
+   if (!gimple_body (root->decl))
+     gimplify_function_tree (root->decl);
+   for (iter = root->nested; iter; iter = iter->next_nested)
+     gimplify_all_functions (iter);
+ }
+ 
  /* Main entry point for this pass.  Process FNDECL and all of its nested
     subroutines and turn them into something less tightly bound.  */
  
*************** lower_nested_functions (tree fndecl)
*** 2457,2462 ****
--- 2468,2475 ----
    if (!cgn->nested)
      return;
  
+   gimplify_all_functions (cgn);
+ 
    bitmap_obstack_initialize (&nesting_info_bitmap_obstack);
    root = create_nesting_tree (cgn);
    walk_all_functions (convert_nonlocal_reference_stmt,
Index: gcc/c-gimplify.c
===================================================================
*** gcc/c-gimplify.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/c-gimplify.c	2009-07-07 13:25:57.000000000 +0200
*************** c_genericize (tree fndecl)
*** 103,116 ****
        dump_end (TDI_original, dump_orig);
      }
  
!   /* Go ahead and gimplify for now.  */
!   gimplify_function_tree (fndecl);
! 
!   dump_function (TDI_generic, fndecl);
! 
!   /* Genericize all nested functions now.  We do things in this order so
!      that items like VLA sizes are expanded properly in the context of
!      the correct function.  */
    cgn = cgraph_node (fndecl);
    for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
      c_genericize (cgn->decl);
--- 103,109 ----
        dump_end (TDI_original, dump_orig);
      }
  
!   /* Dump all nested functions now.  */
    cgn = cgraph_node (fndecl);
    for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
      c_genericize (cgn->decl);
Index: gcc/c-common.h
===================================================================
*** gcc/c-common.h.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/c-common.h	2009-07-07 13:25:57.000000000 +0200
*************** extern void dump_time_statistics (void);
*** 981,988 ****
  
  extern bool c_dump_tree (void *, tree);
  
- extern void c_warn_unused_result (gimple_seq);
- 
  extern void verify_sequence_points (tree);
  
  extern tree fold_offsetof (tree, tree);
--- 981,986 ----
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/gimple.h	2009-07-07 13:25:57.000000000 +0200
*************** extern gimple_predicate rhs_predicate_fo
*** 979,985 ****
  extern tree canonicalize_cond_expr_cond (tree);
  
  /* In omp-low.c.  */
- extern void diagnose_omp_structured_block_errors (tree);
  extern tree omp_reduction_init (tree, tree);
  
  /* In tree-nested.c.  */
--- 979,984 ----
Index: gcc/passes.c
===================================================================
*** gcc/passes.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/passes.c	2009-07-07 13:25:57.000000000 +0200
*************** init_optimization_passes (void)
*** 509,514 ****
--- 509,516 ----
      backend might produce already lowered functions that are not processed
      by these passes.  */
    p = &all_lowering_passes;
+   NEXT_PASS (pass_warn_unused_result);
+   NEXT_PASS (pass_diagnose_omp_blocks);
    NEXT_PASS (pass_remove_useless_stmts);
    NEXT_PASS (pass_mudflap_1);
    NEXT_PASS (pass_lower_omp);
*************** init_optimization_passes (void)
*** 821,827 ****
  
    /* Register the passes with the tree dump code.  */
    register_dump_files (all_lowering_passes, PROP_gimple_any);
-   all_lowering_passes->todo_flags_start |= TODO_set_props;
    register_dump_files (all_ipa_passes, 
  		       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
  		       | PROP_cfg);
--- 823,828 ----
*************** execute_one_pass (struct opt_pass *pass)
*** 1261,1269 ****
    if (!quiet_flag && !cfun)
      fprintf (stderr, " <%s>", pass->name ? pass->name : "");
  
-   if (pass->todo_flags_start & TODO_set_props)
-     cfun->curr_properties = pass->properties_required;
- 
    /* Note that the folders should only create gimple expressions.
       This is a hack until the new folder is ready.  */
    in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0;
--- 1262,1267 ----
Index: gcc/Makefile.in
===================================================================
*** gcc/Makefile.in.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/Makefile.in	2009-07-07 13:25:57.000000000 +0200
*************** gimplify.o : gimplify.c $(CONFIG_H) $(SY
*** 2394,2400 ****
     $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
     coretypes.h $(EXCEPT_H) $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \
     $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) $(TOPLEV_H) $(OPTABS_H) \
!    $(REAL_H) $(SPLAY_TREE_H) vec.h tree-iterator.h
  gimple-iterator.o : gimple-iterator.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) value-prof.h
  gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
--- 2394,2400 ----
     $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
     coretypes.h $(EXCEPT_H) $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \
     $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) $(TOPLEV_H) $(OPTABS_H) \
!    $(REAL_H) $(SPLAY_TREE_H) vec.h tree-iterator.h tree-pass.h
  gimple-iterator.o : gimple-iterator.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) value-prof.h
  gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
*************** cgraphunit.o : cgraphunit.c $(CONFIG_H)
*** 2683,2689 ****
     $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
     $(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \
     $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
!    gt-cgraphunit.h tree-iterator.h $(COVERAGE_H)
  cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
     $(TREE_FLOW_H) $(TREE_PASS_H)
--- 2683,2689 ----
     $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
     $(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \
     $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
!    gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_H)
  cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
     $(TREE_FLOW_H) $(TREE_PASS_H)
Index: gcc/cp/decl2.c
===================================================================
*** gcc/cp/decl2.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/cp/decl2.c	2009-07-07 13:25:57.000000000 +0200
*************** cp_write_global_declarations (void)
*** 3516,3522 ****
  	      reconsider = true;
  	    }
  
! 	  if (!gimple_body (decl))
  	    continue;
  
  	  /* We lie to the back end, pretending that some functions
--- 3516,3522 ----
  	      reconsider = true;
  	    }
  
! 	  if (!DECL_SAVED_TREE (decl))
  	    continue;
  
  	  /* We lie to the back end, pretending that some functions
*************** cp_write_global_declarations (void)
*** 3638,3644 ****
    pop_lang_context ();
  
    cgraph_finalize_compilation_unit ();
-   cgraph_optimize ();
  
    /* Now, issue warnings about static, but not defined, functions,
       etc., and emit debugging information.  */
--- 3638,3643 ----
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c.orig	2009-07-07 13:04:03.000000000 +0200
--- gcc/tree-inline.c	2009-07-07 13:42:32.000000000 +0200
*************** copy_statement_list (tree *tp)
*** 603,609 ****
    *tp = new_tree;
  
    for (; !tsi_end_p (oi); tsi_next (&oi))
!     tsi_link_after (&ni, tsi_stmt (oi), TSI_NEW_STMT);
  }
  
  static void
--- 603,614 ----
    *tp = new_tree;
  
    for (; !tsi_end_p (oi); tsi_next (&oi))
!     {
!       tree stmt = tsi_stmt (oi);
!       if (TREE_CODE (stmt) == STATEMENT_LIST)
! 	copy_statement_list (&stmt);
!       tsi_link_after (&ni, stmt, TSI_CONTINUE_LINKING);
!     }
  }
  
  static void
*************** copy_tree_body_r (tree *tp, int *walk_su
*** 915,926 ****
        gcc_assert (new_decl);
        /* Replace this variable with the copy.  */
        STRIP_TYPE_NOPS (new_decl);
        *tp = new_decl;
        *walk_subtrees = 0;
      }
    else if (TREE_CODE (*tp) == STATEMENT_LIST)
      copy_statement_list (tp);
!   else if (TREE_CODE (*tp) == SAVE_EXPR)
      remap_save_expr (tp, id->decl_map, walk_subtrees);
    else if (TREE_CODE (*tp) == LABEL_DECL
  	   && (! DECL_CONTEXT (*tp)
--- 920,937 ----
        gcc_assert (new_decl);
        /* Replace this variable with the copy.  */
        STRIP_TYPE_NOPS (new_decl);
+       /* ???  From C++ generated thunks we get parms replaced by wrongly
+          typed constants.  */
+       if (TREE_CODE (*tp) == PARM_DECL
+ 	  && TREE_CODE (new_decl) == INTEGER_CST)
+ 	new_decl = fold_convert (TREE_TYPE (*tp), new_decl);
        *tp = new_decl;
        *walk_subtrees = 0;
      }
    else if (TREE_CODE (*tp) == STATEMENT_LIST)
      copy_statement_list (tp);
!   else if (TREE_CODE (*tp) == SAVE_EXPR
! 	   || TREE_CODE (*tp) == TARGET_EXPR)
      remap_save_expr (tp, id->decl_map, walk_subtrees);
    else if (TREE_CODE (*tp) == LABEL_DECL
  	   && (! DECL_CONTEXT (*tp)
*************** unsave_r (tree *tp, int *walk_subtrees,
*** 3917,3923 ****
      gcc_unreachable ();
    else if (TREE_CODE (*tp) == BIND_EXPR)
      copy_bind_expr (tp, walk_subtrees, id);
!   else if (TREE_CODE (*tp) == SAVE_EXPR)
      remap_save_expr (tp, st, walk_subtrees);
    else
      {
--- 3928,3935 ----
      gcc_unreachable ();
    else if (TREE_CODE (*tp) == BIND_EXPR)
      copy_bind_expr (tp, walk_subtrees, id);
!   else if (TREE_CODE (*tp) == SAVE_EXPR
! 	   || TREE_CODE (*tp) == TARGET_EXPR)
      remap_save_expr (tp, st, walk_subtrees);
    else
      {
Index: gcc/ada/gcc-interface/trans.c
===================================================================
*** gcc/ada/gcc-interface/trans.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/ada/gcc-interface/trans.c	2009-07-07 13:25:57.000000000 +0200
*************** gigi (Node_Id gnat_root, int max_gnat_no
*** 627,632 ****
--- 627,633 ----
    for (info = elab_info_list; info; info = info->next)
      {
        tree gnu_body = DECL_SAVED_TREE (info->elab_proc);
+       tree gnu_stmts;
  
        /* Unshare SAVE_EXPRs between subprograms.  These are not unshared by
  	 the gimplifier for obvious reasons, but it turns out that we need to
*************** gigi (Node_Id gnat_root, int max_gnat_no
*** 638,651 ****
  	 an upstream bug for which we would not change the outcome.  */
        walk_tree_without_duplicates (&gnu_body, unshare_save_expr, NULL);
  
-       /* Process the function as others, but for indicating this is an
- 	 elab proc, to be discarded if empty, then propagate the status
- 	 up to the GNAT tree node.  */
-       begin_subprog_body (info->elab_proc);
-       end_subprog_body (gnu_body, true);
  
!       if (empty_body_p (gimple_body (info->elab_proc)))
! 	Set_Has_No_Elaboration_Code (info->gnat_node, 1);
      }
  
    /* We cannot track the location of errors past this point.  */
--- 639,665 ----
  	 an upstream bug for which we would not change the outcome.  */
        walk_tree_without_duplicates (&gnu_body, unshare_save_expr, NULL);
  
  
!       /* We should have a BIND_EXPR, but it may or may not have any statements
! 	 in it.  If it doesn't have any, we have nothing to do.  */
!       gnu_stmts = gnu_body;
!       if (TREE_CODE (gnu_stmts) == BIND_EXPR)
! 	gnu_stmts = BIND_EXPR_BODY (gnu_stmts);
! 
!       /* If there are no statements, there is no elaboration code.  */
!       if (!gnu_stmts || !STATEMENT_LIST_HEAD (gnu_stmts))
! 	{
! 	  Set_Has_No_Elaboration_Code (info->gnat_node, 1);
! 	  /*cgraph_remove_node (cgraph_node (info->elab_proc));*/
! 	}
!       else
! 	{
! 	  /* Process the function as others, but for indicating this is an
! 	     elab proc, to be discarded if empty, then propagate the status
! 	     up to the GNAT tree node.  */
! 	  begin_subprog_body (info->elab_proc);
! 	  end_subprog_body (gnu_body, true);
! 	}
      }
  
    /* We cannot track the location of errors past this point.  */
Index: gcc/java/decl.c
===================================================================
*** gcc/java/decl.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/java/decl.c	2009-07-07 13:25:57.000000000 +0200
*************** java_replace_reference (tree var_decl, b
*** 342,347 ****
--- 342,376 ----
  }
  
  
+ tree
+ java_replace_references (tree *tp, int *walk_subtrees,
+ 			 void *data ATTRIBUTE_UNUSED)
+ {
+   if (TREE_CODE (*tp) == MODIFY_EXPR)
+     {
+       tree lhs = TREE_OPERAND (*tp, 0);
+       if (TREE_CODE (lhs) == VAR_DECL
+ 	  && DECL_LANG_SPECIFIC (lhs)
+ 	  && LOCAL_SLOT_P (lhs)
+ 	  && TREE_CODE (TREE_TYPE (lhs)) == POINTER_TYPE)
+ 	{
+ 	  tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true);
+ 	  tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs),
+ 				 TREE_OPERAND (*tp, 1));
+ 	  *tp = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs),
+ 			new_lhs, new_rhs);
+ 	  *tp = build1 (NOP_EXPR, TREE_TYPE (lhs), *tp);
+ 	}
+     }
+   if (TREE_CODE (*tp) == VAR_DECL)
+     {
+       *tp = java_replace_reference (*tp, /* want_lvalue */ false);
+       *walk_subtrees = 0;
+     }
+ 
+   return NULL_TREE;
+ }
+ 
  /* Same as find_local_index, except that INDEX is a stack index. */
  
  tree
*************** end_java_method (void)
*** 1877,1882 ****
--- 1906,1912 ----
    finish_method (fndecl);
  
    current_function_decl = NULL_TREE;
+   base_decl_map = NULL_TREE;
  }
  
  /* Prepare a method for expansion.  */
Index: gcc/java/java-tree.h
===================================================================
*** gcc/java/java-tree.h.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/java/java-tree.h	2009-07-07 13:25:57.000000000 +0200
*************** extern int find_class_or_string_constant
*** 1120,1125 ****
--- 1120,1126 ----
  extern tree pushdecl_top_level (tree);
  extern tree pushdecl_function_level (tree);
  extern tree java_replace_reference (tree, bool);
+ extern tree java_replace_references (tree *, int *, void *);
  extern int alloc_class_constant (tree);
  extern void init_expr_processing (void);
  extern void push_super_field (tree, tree);
Index: gcc/c-omp.c
===================================================================
*** gcc/c-omp.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/c-omp.c	2009-07-07 13:25:57.000000000 +0200
*************** c_finish_omp_atomic (location_t loc, enu
*** 144,149 ****
--- 144,150 ----
        /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
  	 it even after unsharing function body.  */
        tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
+       DECL_CONTEXT (var) = current_function_decl;
        addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
      }
    lhs = build_indirect_ref (loc, addr, NULL);
Index: gcc/cgraph.h
===================================================================
*** gcc/cgraph.h.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/cgraph.h	2009-07-07 13:25:57.000000000 +0200
*************** struct cgraph_node * cgraph_create_virtu
*** 426,432 ****
  void cgraph_finalize_function (tree, bool);
  void cgraph_mark_if_needed (tree);
  void cgraph_finalize_compilation_unit (void);
- void cgraph_optimize (void);
  void cgraph_mark_needed_node (struct cgraph_node *);
  void cgraph_mark_address_taken_node (struct cgraph_node *);
  void cgraph_mark_reachable_node (struct cgraph_node *);
--- 426,431 ----
*************** struct cgraph_node *cgraph_function_vers
*** 442,448 ****
  						VEC(ipa_replace_map_p,gc)*,
  						bitmap);
  void tree_function_versioning (tree, tree, VEC (ipa_replace_map_p,gc)*, bool, bitmap);
- void cgraph_analyze_function (struct cgraph_node *);
  struct cgraph_node *save_inline_function_body (struct cgraph_node *);
  void record_references_in_initializer (tree);
  bool cgraph_process_new_functions (void);
--- 441,446 ----
Index: gcc/cgraph.c
===================================================================
*** gcc/cgraph.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/cgraph.c	2009-07-07 13:25:57.000000000 +0200
*************** cgraph_add_new_function (tree fndecl, bo
*** 1836,1841 ****
--- 1836,1844 ----
  	    push_cfun (DECL_STRUCT_FUNCTION (fndecl));
  	    current_function_decl = fndecl;
  	    gimple_register_cfg_hooks ();
+ 	    /* C++ Thunks are emitted late via this function, gimplify them.  */
+ 	    if (!gimple_body (fndecl))
+ 	      gimplify_function_tree (fndecl);
  	    tree_lowering_passes (fndecl);
  	    bitmap_obstack_initialize (NULL);
  	    if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
Index: gcc/testsuite/g++.dg/rtti/crash4.C
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/g++.dg/rtti/crash4.C	2009-07-07 13:25:57.000000000 +0200
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O" } */
+ 
+ class ios_base   {
+ public:
+     virtual ~ios_base();
+ };
+ template<typename _CharT>
+ class basic_ostream : virtual public ios_base {
+ public:
+     virtual ~basic_ostream() { }
+ };
+ extern template class basic_ostream<char>;
+ template <typename _CharT>
+ class basic_ostringstream : public basic_ostream<_CharT> { };
+ template class basic_ostringstream<char>;
Index: gcc/c-opts.c
===================================================================
*** gcc/c-opts.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/c-opts.c	2009-07-07 13:25:57.000000000 +0200
*************** c_common_init_options (unsigned int argc
*** 232,237 ****
--- 232,238 ----
    flag_exceptions = c_dialect_cxx ();
    warn_pointer_arith = c_dialect_cxx ();
    warn_write_strings = c_dialect_cxx();
+   flag_warn_unused_result = true;
  
    /* By default, C99-like requirements for complex multiply and divide.  */
    flag_complex_method = 2;
Index: gcc/flags.h
===================================================================
*** gcc/flags.h.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/flags.h	2009-07-07 13:25:57.000000000 +0200
*************** extern bool g_switch_set;
*** 250,255 ****
--- 250,258 ----
  /* Same for selective scheduling.  */
  extern bool sel_sched_switch_set;
  
+ /* Whether to run the warn_unused_result attribute pass.  */
+ extern bool flag_warn_unused_result;
+ 
  /* Values of the -falign-* flags: how much to align labels in code. 
     0 means `use default', 1 means `don't align'.  
     For each variable, there is an _log variant which is the power
Index: gcc/opts.c
===================================================================
*** gcc/opts.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/opts.c	2009-07-07 13:25:57.000000000 +0200
*************** DEF_VEC_ALLOC_P(const_char_p,heap);
*** 362,367 ****
--- 362,370 ----
  
  static VEC(const_char_p,heap) *ignored_options;
  
+ /* Language specific warning pass for unused results.  */
+ bool flag_warn_unused_result = false;
+ 
  /* Input file names.  */
  const char **in_fnames;
  unsigned num_in_fnames;
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/tree-cfg.c	2009-07-07 13:25:57.000000000 +0200
*************** struct gimple_opt_pass pass_warn_functio
*** 7366,7368 ****
--- 7366,7463 ----
    0					/* todo_flags_finish */
   }
  };
+ 
+ 
+ /* Walk a gimplified function and warn for functions whose return value is
+    ignored and attribute((warn_unused_result)) is set.  This is done before
+    inlining, so we don't have to worry about that.  */
+ 
+ static void
+ warn_unused_result (gimple_seq seq)
+ {
+   tree fdecl, ftype;
+   gimple_stmt_iterator i;
+ 
+   for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+     {
+       gimple g = gsi_stmt (i);
+ 
+       switch (gimple_code (g))
+ 	{
+ 	case GIMPLE_BIND:
+ 	  warn_unused_result (gimple_bind_body (g));
+ 	  break;
+ 	case GIMPLE_TRY:
+ 	  warn_unused_result (gimple_try_eval (g));
+ 	  warn_unused_result (gimple_try_cleanup (g));
+ 	  break;
+ 	case GIMPLE_CATCH:
+ 	  warn_unused_result (gimple_catch_handler (g));
+ 	  break;
+ 	case GIMPLE_EH_FILTER:
+ 	  warn_unused_result (gimple_eh_filter_failure (g));
+ 	  break;
+ 
+ 	case GIMPLE_CALL:
+ 	  if (gimple_call_lhs (g))
+ 	    break;
+ 
+ 	  /* This is a naked call, as opposed to a GIMPLE_CALL with an
+ 	     LHS.  All calls whose value is ignored should be
+ 	     represented like this.  Look for the attribute.  */
+ 	  fdecl = gimple_call_fndecl (g);
+ 	  ftype = TREE_TYPE (TREE_TYPE (gimple_call_fn (g)));
+ 
+ 	  if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
+ 	    {
+ 	      location_t loc = gimple_location (g);
+ 
+ 	      if (fdecl)
+ 		warning_at (loc, 0, "ignoring return value of %qD, "
+ 			    "declared with attribute warn_unused_result",
+ 			    fdecl);
+ 	      else
+ 		warning_at (loc, 0, "ignoring return value of function "
+ 			    "declared with attribute warn_unused_result");
+ 	    }
+ 	  break;
+ 
+ 	default:
+ 	  /* Not a container, not a call, or a call whose value is used.  */
+ 	  break;
+ 	}
+     }
+ }
+ 
+ static unsigned int
+ run_warn_unused_result (void)
+ {
+   warn_unused_result (gimple_body (current_function_decl));
+   return 0;
+ }
+ 
+ static bool
+ gate_warn_unused_result (void)
+ {
+   return flag_warn_unused_result;
+ }
+ 
+ struct gimple_opt_pass pass_warn_unused_result =
+ {
+   {
+     GIMPLE_PASS,
+     "warn_unused_result",		/* name */
+     gate_warn_unused_result,		/* gate */
+     run_warn_unused_result,		/* execute */
+     NULL,				/* sub */
+     NULL,				/* next */
+     0,					/* static_pass_number */
+     TV_NONE,				/* tv_id */
+     PROP_gimple_any,			/* properties_required */
+     0,					/* properties_provided */
+     0,					/* properties_destroyed */
+     0,					/* todo_flags_start */
+     0,					/* todo_flags_finish */
+   }
+ };
+ 
Index: gcc/cp/Make-lang.in
===================================================================
*** gcc/cp/Make-lang.in.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/cp/Make-lang.in	2009-07-07 13:25:57.000000000 +0200
*************** cp/semantics.o: cp/semantics.c $(CXX_TRE
*** 289,295 ****
  cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) $(TREE_DUMP_H)
  cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h $(INTEGRATE_H) \
    insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \
!   $(TARGET_H)
  cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h $(REAL_H) \
    gt-cp-mangle.h $(TARGET_H) $(TM_P_H)
  cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) gt-cp-parser.h \
--- 289,295 ----
  cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) $(TREE_DUMP_H)
  cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h $(INTEGRATE_H) \
    insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \
!   $(TARGET_H) tree-iterator.h
  cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h $(REAL_H) \
    gt-cp-mangle.h $(TARGET_H) $(TM_P_H)
  cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) gt-cp-parser.h \
Index: gcc/cp/optimize.c
===================================================================
*** gcc/cp/optimize.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/cp/optimize.c	2009-07-07 13:25:57.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 41,46 ****
--- 41,47 ----
  #include "diagnostic.h"
  #include "tree-dump.h"
  #include "gimple.h"
+ #include "tree-iterator.h"
  
  /* Prototypes.  */
  
*************** static void
*** 81,90 ****
  clone_body (tree clone, tree fn, void *arg_map)
  {
    copy_body_data id;
!   gimple_seq new_body;
! 
!   /* FN must already be in GIMPLE form.  */
!   gcc_assert (gimple_body (fn));
  
    /* Clone the body, as if we were making an inline call.  But, remap
       the parameters in the callee to the parameters of caller.  */
--- 82,88 ----
  clone_body (tree clone, tree fn, void *arg_map)
  {
    copy_body_data id;
!   tree stmts;
  
    /* Clone the body, as if we were making an inline call.  But, remap
       the parameters in the callee to the parameters of caller.  */
*************** clone_body (tree clone, tree fn, void *a
*** 103,111 ****
    /* We're not inside any EH region.  */
    id.eh_region = -1;
  
!   /* Actually copy the body.  */
!   new_body = remap_gimple_seq (gimple_body (fn), &id);
!   gimple_set_body (clone, new_body);
  }
  
  /* FN is a function that has a complete body.  Clone the body as
--- 101,109 ----
    /* We're not inside any EH region.  */
    id.eh_region = -1;
  
!   stmts = DECL_SAVED_TREE (fn);
!   walk_tree (&stmts, copy_tree_body_r, &id, NULL);
!   append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
  }
  
  /* FN is a function that has a complete body.  Clone the body as
*************** maybe_clone_body (tree fn)
*** 237,243 ****
        /* Now, expand this function into RTL, if appropriate.  */
        finish_function (0);
        BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
-       DECL_SAVED_TREE (clone) = NULL;
        expand_or_defer_fn (clone);
        first = false;
      }
--- 235,240 ----
Index: gcc/cp/error.c
===================================================================
*** gcc/cp/error.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/cp/error.c	2009-07-07 13:25:57.000000000 +0200
*************** cp_print_error_function (diagnostic_cont
*** 2646,2652 ****
  static const char *
  function_category (tree fn)
  {
!   if (DECL_FUNCTION_MEMBER_P (fn))
      {
        if (DECL_STATIC_FUNCTION_P (fn))
  	return _("In static member function %qs");
--- 2646,2656 ----
  static const char *
  function_category (tree fn)
  {
!   /* We can get called from the middle-end for diagnostics of function
!      clones.  Make sure we have language specific information before
!      dereferencing it.  */
!   if (DECL_LANG_SPECIFIC (STRIP_TEMPLATE (fn))
!       && DECL_FUNCTION_MEMBER_P (fn))
      {
        if (DECL_STATIC_FUNCTION_P (fn))
  	return _("In static member function %qs");
Index: gcc/testsuite/g++.dg/torture/20090706-1.C
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/g++.dg/torture/20090706-1.C	2009-07-07 13:25:57.000000000 +0200
***************
*** 0 ****
--- 1,41 ----
+ /* { dg-do compile } */
+ 
+ namespace std __attribute__ ((__visibility__ ("default"))) {
+     template<typename _Tp>     class new_allocator     { };
+     template<typename _Tp>     class allocator: public new_allocator<_Tp> { };
+     template<typename _Tp, typename _Alloc>     struct _Vector_base     { };
+     template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
+     class vector : protected _Vector_base<_Tp, _Alloc>     { };
+ };
+ template<int Dim> class Vector { };
+ enum CenteringType { VertexType,  EdgeType,  FaceType,  CellType };
+ enum ContinuityType { XDim = 1,  YDim = XDim << 1,  ZDim = YDim << 1 };
+ template <int Dim> class Centering {
+ public:
+     typedef Vector<Dim> Position;
+     typedef std::vector<Position> Positions;
+     Centering(const Positions &positions);
+     Positions positions_m;
+ };
+ template <int Dim> class CanonicalCentering {
+     CanonicalCentering();
+     template <class T> static T combine(const T &op1, const T &op2);
+     static Centering<Dim>*** centering_table_m;
+ };
+ template <int Dim> CanonicalCentering<Dim>::CanonicalCentering()
+ {
+   typename Centering<Dim>::Positions positions[Dim][2];
+   enum { x = 0, y, z };
+   int cont = 0;
+   if (Dim > 1)
+     {
+       centering_table_m[EdgeType][cont][YDim] =  Centering<Dim>(positions[y][cont]);
+       centering_table_m[EdgeType][cont][XDim|YDim] =  Centering<Dim>(combine(positions[x][cont], positions[y][cont]));
+     }
+   if (Dim > 2)
+     {
+       centering_table_m[EdgeType][cont][ZDim] =  Centering<Dim>(positions[z][cont]);
+       centering_table_m[EdgeType][cont][XDim|ZDim] =  Centering<Dim>(combine(positions[x][cont], positions[z][cont]));
+     }
+ }
+ template class CanonicalCentering<2>;
Index: gcc/c-common.c
===================================================================
*** gcc/c-common.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/c-common.c	2009-07-07 13:25:57.000000000 +0200
*************** c_cpp_error (cpp_reader *pfile ATTRIBUTE
*** 8221,8287 ****
    return ret;
  }
  
- /* Walk a gimplified function and warn for functions whose return value is
-    ignored and attribute((warn_unused_result)) is set.  This is done before
-    inlining, so we don't have to worry about that.  */
- 
- void
- c_warn_unused_result (gimple_seq seq)
- {
-   tree fdecl, ftype;
-   gimple_stmt_iterator i;
- 
-   for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
-     {
-       gimple g = gsi_stmt (i);
- 
-       switch (gimple_code (g))
- 	{
- 	case GIMPLE_BIND:
- 	  c_warn_unused_result (gimple_bind_body (g));
- 	  break;
- 	case GIMPLE_TRY:
- 	  c_warn_unused_result (gimple_try_eval (g));
- 	  c_warn_unused_result (gimple_try_cleanup (g));
- 	  break;
- 	case GIMPLE_CATCH:
- 	  c_warn_unused_result (gimple_catch_handler (g));
- 	  break;
- 	case GIMPLE_EH_FILTER:
- 	  c_warn_unused_result (gimple_eh_filter_failure (g));
- 	  break;
- 
- 	case GIMPLE_CALL:
- 	  if (gimple_call_lhs (g))
- 	    break;
- 
- 	  /* This is a naked call, as opposed to a GIMPLE_CALL with an
- 	     LHS.  All calls whose value is ignored should be
- 	     represented like this.  Look for the attribute.  */
- 	  fdecl = gimple_call_fndecl (g);
- 	  ftype = TREE_TYPE (TREE_TYPE (gimple_call_fn (g)));
- 
- 	  if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
- 	    {
- 	      location_t loc = gimple_location (g);
- 
- 	      if (fdecl)
- 		warning_at (loc, 0, "ignoring return value of %qD, "
- 			    "declared with attribute warn_unused_result",
- 			    fdecl);
- 	      else
- 		warning_at (loc, 0, "ignoring return value of function "
- 			    "declared with attribute warn_unused_result");
- 	    }
- 	  break;
- 
- 	default:
- 	  /* Not a container, not a call, or a call whose value is used.  */
- 	  break;
- 	}
-     }
- }
- 
  /* Convert a character from the host to the target execution character
     set.  cpplib handles this, mostly.  */
  
--- 8221,8226 ----
Index: gcc/testsuite/gcc.dg/declspec-10.c
===================================================================
*** gcc/testsuite/gcc.dg/declspec-10.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/testsuite/gcc.dg/declspec-10.c	2009-07-07 13:25:57.000000000 +0200
*************** void i (void) { auto void y (void) {} }
*** 43,45 ****
--- 43,47 ----
  /* { dg-warning "function definition declared 'auto'" "nested" { target *-*-* } 42 } */
  
  inline int main (void) { return 0; } /* { dg-warning "cannot inline function 'main'" } */
+ 
+ /* { dg-message "error: register name not specified for 'y'" "" { target *-*-* } 19 } */
Index: gcc/testsuite/gcc.dg/declspec-11.c
===================================================================
*** gcc/testsuite/gcc.dg/declspec-11.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/testsuite/gcc.dg/declspec-11.c	2009-07-07 13:25:57.000000000 +0200
*************** void i (void) { auto void y (void) {} }
*** 43,45 ****
--- 43,47 ----
  /* { dg-error "function definition declared 'auto'" "nested" { target *-*-* } 42 } */
  
  inline int main (void) { return 0; } /* { dg-error "cannot inline function 'main'" } */
+ 
+ /* { dg-message "error: register name not specified for 'y'" "" { target *-*-* } 19 } */
Index: gcc/testsuite/gcc.dg/declspec-9.c
===================================================================
*** gcc/testsuite/gcc.dg/declspec-9.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/testsuite/gcc.dg/declspec-9.c	2009-07-07 13:25:57.000000000 +0200
*************** void f6 (static int); /* { dg-error "sto
*** 17,23 ****
  void f7 (typedef int); /* { dg-error "storage class specified for unnamed parameter" } */
  
  auto int x; /* { dg-error "file-scope declaration of 'x' specifies 'auto'" } */
! register int y;
  
  void h (void) { extern void x (void) {} } /* { dg-error "nested function 'x' declared 'extern'" } */
  
--- 17,23 ----
  void f7 (typedef int); /* { dg-error "storage class specified for unnamed parameter" } */
  
  auto int x; /* { dg-error "file-scope declaration of 'x' specifies 'auto'" } */
! register int y; /* { dg-error "register name not specified for 'y'" } */
  
  void h (void) { extern void x (void) {} } /* { dg-error "nested function 'x' declared 'extern'" } */
  
Index: gcc/testsuite/gcc.dg/redecl-10.c
===================================================================
*** gcc/testsuite/gcc.dg/redecl-10.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/testsuite/gcc.dg/redecl-10.c	2009-07-07 13:25:57.000000000 +0200
*************** f (void)
*** 12,18 ****
    extern int w[] = { 1, 2 }; /* { dg-error "has both" } */
  }
  
! int x[];
  void
  g (void)
  {
--- 12,18 ----
    extern int w[] = { 1, 2 }; /* { dg-error "has both" } */
  }
  
! int x[]; /* { dg-warning "array 'x' assumed to have one element" } */
  void
  g (void)
  {
*************** h (void)
*** 26,32 ****
    extern int y[] = { 6 }; /* { dg-error "has both" } */
  }
  
! int z[];
  void
  i (void)
  {
--- 26,32 ----
    extern int y[] = { 6 }; /* { dg-error "has both" } */
  }
  
! int z[]; /* { dg-warning "array 'z' assumed to have one element" } */
  void
  i (void)
  {
Index: gcc/testsuite/gcc.target/i386/pr39082-1.c
===================================================================
*** gcc/testsuite/gcc.target/i386/pr39082-1.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/testsuite/gcc.target/i386/pr39082-1.c	2009-07-07 13:25:57.000000000 +0200
*************** extern int bar1 (union un);
*** 13,19 ****
  extern union un bar2 (int);
  
  int
! foo1 (union un u) /* { dg-message "note: The ABI of passing union with long double has changed in GCC 4.4" } */
  {
    bar1 (u);
    return u.i;
--- 13,19 ----
  extern union un bar2 (int);
  
  int
! foo1 (union un u)
  {
    bar1 (u);
    return u.i;
*************** foo2 (void)
*** 30,35 ****
  int
  foo3 (int x)
  {
!   union un u = bar2 (x);
    return u.i;
  }
--- 30,35 ----
  int
  foo3 (int x)
  {
!   union un u = bar2 (x); /* { dg-message "note: The ABI of passing union with long double has changed in GCC 4.4" } */
    return u.i;
  }
Index: gcc/testsuite/gcc.target/i386/pr39545-1.c
===================================================================
*** gcc/testsuite/gcc.target/i386/pr39545-1.c.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/testsuite/gcc.target/i386/pr39545-1.c	2009-07-07 13:25:57.000000000 +0200
*************** struct flex
*** 10,23 ****
  };
  
  int
! foo (struct flex s) /* { dg-message "note: The ABI of passing struct with a flexible array member has changed in GCC 4.4" } */
  {
    return s.i;
  }
  
  struct flex
  bar (int x)
! {
    struct flex s;
    s.i = x;
    return s;
--- 10,23 ----
  };
  
  int
! foo (struct flex s)
  {
    return s.i;
  }
  
  struct flex
  bar (int x)
! { /* { dg-message "note: The ABI of passing struct with a flexible array member has changed in GCC 4.4" } */
    struct flex s;
    s.i = x;
    return s;
Index: gcc/testsuite/gfortran.dg/missing_optional_dummy_5.f90
===================================================================
*** gcc/testsuite/gfortran.dg/missing_optional_dummy_5.f90.orig	2009-07-07 12:51:02.000000000 +0200
--- gcc/testsuite/gfortran.dg/missing_optional_dummy_5.f90	2009-07-07 13:25:57.000000000 +0200
*************** contains
*** 23,29 ****
   end function tm_doit
  end module krmod
  
! ! { dg-final { scan-tree-dump " tm_doit \\(&parm.\(6|7\), 0B, 0\\);" "original" } }
  ! { dg-final { cleanup-tree-dump "original" } }
  ! { dg-final { cleanup-modules "pr22146" } }
  
--- 23,29 ----
   end function tm_doit
  end module krmod
  
! ! { dg-final { scan-tree-dump " tm_doit \\(&parm\.., 0B, 0\\);" "original" } }
  ! { dg-final { cleanup-tree-dump "original" } }
  ! { dg-final { cleanup-modules "pr22146" } }
  
Index: gcc/testsuite/g++.dg/ext/asm3.C
===================================================================
*** gcc/testsuite/g++.dg/ext/asm3.C.orig	2006-02-07 11:15:12.000000000 +0100
--- gcc/testsuite/g++.dg/ext/asm3.C	2009-07-07 14:33:25.000000000 +0200
***************
*** 8,13 ****
  int two(int in)
  {
    register int out;
!   __asm__ ("" : "r" (out) : "r" (in)); // { dg-error "" "" }
    return out;
  }
--- 8,15 ----
  int two(int in)
  {
    register int out;
!   __asm__ ("" : "r" (out) : "r" (in));
    return out;
  }
+ 
+ // { dg-message "error:" "" { target *-*-* } 11 }
Index: gcc/testsuite/g++.dg/gomp/block-1.C
===================================================================
*** gcc/testsuite/g++.dg/gomp/block-1.C.orig	2006-03-14 10:47:11.000000000 +0100
--- gcc/testsuite/g++.dg/gomp/block-1.C	2009-07-07 14:21:15.000000000 +0200
*************** void foo()
*** 20,22 ****
--- 20,25 ----
  	{ ok1: break; }
      }
  }
+ 
+ // { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
+ // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 9 }
Index: gcc/testsuite/g++.dg/gomp/block-2.C
===================================================================
*** gcc/testsuite/g++.dg/gomp/block-2.C.orig	2006-03-14 10:47:11.000000000 +0100
--- gcc/testsuite/g++.dg/gomp/block-2.C	2009-07-07 14:18:29.000000000 +0200
*************** void foo()
*** 30,32 ****
--- 30,35 ----
    for (i = 0; i < 10; ++i)
      continue;
  }
+ 
+ // { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 14 }
+ // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 16 }
Index: gcc/testsuite/g++.dg/gomp/block-3.C
===================================================================
*** gcc/testsuite/g++.dg/gomp/block-3.C.orig	2006-03-14 10:47:11.000000000 +0100
--- gcc/testsuite/g++.dg/gomp/block-3.C	2009-07-07 14:19:37.000000000 +0200
*************** void foo()
*** 55,57 ****
--- 55,61 ----
  	}
      }
  }
+ 
+ // { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 21 }
+ // { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 26 }
+ // { dg-message "error: invalid entry to OpenMP structured block" "" { target *-*-* } 30 }
Index: gcc/testsuite/g++.dg/gomp/block-5.C
===================================================================
*** gcc/testsuite/g++.dg/gomp/block-5.C.orig	2006-03-14 10:47:11.000000000 +0100
--- gcc/testsuite/g++.dg/gomp/block-5.C	2009-07-07 14:20:27.000000000 +0200
*************** void foo()
*** 13,15 ****
--- 13,17 ----
        return;		// { dg-error "invalid exit" }
      }
  }
+ 
+ // { dg-message "error: invalid branch to/from an OpenMP structured block" "" { target *-*-* } 7 }
Index: gcc/testsuite/g++.dg/warn/unused-result1.C
===================================================================
*** gcc/testsuite/g++.dg/warn/unused-result1.C.orig	2009-01-29 15:59:43.000000000 +0100
--- gcc/testsuite/g++.dg/warn/unused-result1.C	2009-07-07 14:37:00.000000000 +0200
*************** public:
*** 6,10 ****
  };
  class QString {
    QByteArray toLocal8Bit() const __attribute__ ((warn_unused_result));
!   void fooWarnHere() const { toLocal8Bit(); } // { dg-warning "ignoring" }
  };
--- 6,10 ----
  };
  class QString {
    QByteArray toLocal8Bit() const __attribute__ ((warn_unused_result));
!   void fooWarnHere() const { toLocal8Bit(); } // { dg-warning "ignoring" "" { xfail *-*-* } }
  };
Index: gcc/testsuite/g++.old-deja/g++.jason/report.C
===================================================================
*** gcc/testsuite/g++.old-deja/g++.jason/report.C.orig	2008-09-17 11:01:37.000000000 +0200
--- gcc/testsuite/g++.old-deja/g++.jason/report.C	2009-07-07 14:16:30.000000000 +0200
*************** int darg (char X::*p)
*** 72,74 ****
--- 72,77 ----
  {
     undef3 (1); // { dg-error "" } implicit declaration
  }				// { dg-warning "no return statement" }
+ 
+ // { dg-message "warning: control reaches end of non-void function" "" { target *-*-* } 36 }
+ // { dg-message "warning: control reaches end of non-void function" "" { target *-*-* } 65 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]