diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4dda512f74c26cefe6467f88655516dc18f1c723..fcbe897da35d55a83c8a616b81e7f30b8db8ef6c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2009-03-28  Jan Hubicka  <jh@suse.cz>
+
+	* dwarf2out.c (dwarf2out_begin_prologue): Use crtl->nothrow
+	* tree-eh.c (stmt_could_throw_p): Remove check for WEAK decls.
+	* function.h (rtl_data): Add nothrow flag.
+	* except.c (set_nothrow_function_flags): Use crtl->nothrow;
+	set DECL_NOTHROW for AVAILABLE functions.
+
 2009-03-28  Jakub Jelinek  <jakub@redhat.com>
 
 	* config/rs6000/rs6000-c.c (rs6000_macro_to_expand): If macro
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 9bab2a42934d1283461933eb627a212019ada2d2..1bc17306c099640788e634fa92031401d6918acd 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3231,7 +3231,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   fde->dw_fde_end = NULL;
   fde->dw_fde_cfi = NULL;
   fde->funcdef_number = current_function_funcdef_no;
-  fde->nothrow = TREE_NOTHROW (current_function_decl);
+  fde->nothrow = crtl->nothrow;
   fde->uses_eh_lsda = crtl->uses_eh_lsda;
   fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
   fde->drap_reg = INVALID_REGNUM;
diff --git a/gcc/except.c b/gcc/except.c
index 91af716f631760ec3dadc08267225fddec14d9d9..f18e78e3f48e2048b01a78a2ddd5f4363fec7cac 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2765,13 +2765,7 @@ set_nothrow_function_flags (void)
 {
   rtx insn;
 
-  /* If we don't know that this implementation of the function will
-     actually be used, then we must not set TREE_NOTHROW, since
-     callers must not assume that this function does not throw.  */
-  if (DECL_REPLACEABLE_P (current_function_decl))
-    return 0;
-
-  TREE_NOTHROW (current_function_decl) = 1;
+  crtl->nothrow = 1;
 
   /* Assume crtl->all_throwers_are_sibcalls until we encounter
      something that can throw an exception.  We specifically exempt
@@ -2781,13 +2775,19 @@ set_nothrow_function_flags (void)
 
   crtl->all_throwers_are_sibcalls = 1;
 
+  /* If we don't know that this implementation of the function will
+     actually be used, then we must not set TREE_NOTHROW, since
+     callers must not assume that this function does not throw.  */
+  if (TREE_NOTHROW (current_function_decl))
+    return 0;
+
   if (! flag_exceptions)
     return 0;
 
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     if (can_throw_external (insn))
       {
-        TREE_NOTHROW (current_function_decl) = 0;
+        crtl->nothrow = 0;
 
 	if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
 	  {
@@ -2800,7 +2800,7 @@ set_nothrow_function_flags (void)
        insn = XEXP (insn, 1))
     if (can_throw_external (insn))
       {
-        TREE_NOTHROW (current_function_decl) = 0;
+        crtl->nothrow = 0;
 
 	if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
 	  {
@@ -2808,6 +2808,10 @@ set_nothrow_function_flags (void)
 	    return 0;
 	  }
       }
+  if (crtl->nothrow
+      && (cgraph_function_body_availability (cgraph_node (current_function_decl))
+          >= AVAIL_AVAILABLE))
+    TREE_NOTHROW (current_function_decl) = 1;
   return 0;
 }
 
diff --git a/gcc/function.h b/gcc/function.h
index 31d223a3d395b3acda78e8a10d46b13bf26bb830..70797974bf0707aa17c6ede5ad06f7795211f248 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -441,6 +441,11 @@ struct rtl_data GTY(())
 
   /* True if dbr_schedule has already been called for this function.  */
   bool dbr_scheduled_p;
+
+  /* True if current function can not throw.  Unlike
+     TREE_NOTHROW (current_function_decl) it is set even for overwritable
+     function where currently compiled version of it is nothrow.  */
+  bool nothrow;
 };
 
 #define return_label (crtl->x_return_label)
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index c789acbd118c7231d4008f9140415ed19d9d92dd..c992f6d477e506f890f2cb0ba804f793eede5315 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2368,15 +2368,7 @@ stmt_could_throw_p (gimple stmt)
   if (code == GIMPLE_ASSIGN || code == GIMPLE_COND)
     return stmt_could_throw_1_p (stmt);
   else if (is_gimple_call (stmt))
-    {
-      tree t = gimple_call_fndecl (stmt);
-
-      /* Assume that calls to weak functions may trap.  */
-      if (!t || !DECL_P (t) || DECL_WEAK (t))
-	return true;
-
-      return (gimple_call_flags (stmt) & ECF_NOTHROW) == 0;
-    }
+    return (gimple_call_flags (stmt) & ECF_NOTHROW) == 0;
   else if (gimple_code (stmt) == GIMPLE_ASM)
     return (gimple_asm_volatile_p (stmt));
   else