Index: libitm/libitm.h
===================================================================
--- libitm/libitm.h	(revision 162234)
+++ libitm/libitm.h	(working copy)
@@ -33,7 +33,10 @@
 #include <stdint.h>
 
 #ifdef __cplusplus
+#define THROW throw()
 extern "C" {
+#else
+#define THROW
 #endif
 
 #ifdef __i386__
@@ -278,8 +281,8 @@ extern void *_ITM_getTMCloneSafe (void *
 extern void _ITM_registerTMCloneTable (void *, size_t);
 extern void _ITM_deregisterTMCloneTable (void *);
 
-extern void *_ITM_cxa_allocate_exception (size_t);
-extern void _ITM_cxa_throw (void *obj, void *tinfo, void *dest);
+extern void *_ITM_cxa_allocate_exception (size_t) THROW __attribute__((malloc));
+extern void _ITM_cxa_throw (void *obj, void *tinfo, void (*)(void*));
 extern void *_ITM_cxa_begin_catch (void *exc_ptr);
 extern void _ITM_cxa_end_catch (void);
 extern void _ITM_commitTransactionEH(void *exc_ptr) ITM_REGPARM;
Index: libitm/eh_cpp.cc
===================================================================
--- libitm/eh_cpp.cc	(revision 162234)
+++ libitm/eh_cpp.cc	(working copy)
@@ -34,7 +34,7 @@ using namespace GTM;
 extern "C" {
 
 extern void *__cxa_allocate_exception (size_t) WEAK;
-extern void __cxa_throw (void *, void *, void *) WEAK;
+extern void __cxa_throw (void *, void *, void (*) (void*)) WEAK;
 extern void *__cxa_begin_catch (void *) WEAK;
 extern void *__cxa_end_catch (void) WEAK;
 extern void __cxa_tm_cleanup (void *, void *, unsigned int) WEAK;
@@ -51,7 +51,7 @@ _ITM_cxa_allocate_exception (size_t size
 }
 
 void
-_ITM_cxa_throw (void *obj, void *tinfo, void *dest)
+_ITM_cxa_throw (void *obj, void *tinfo, void (*dest)(void*))
 {
   gtm_tx()->cxa_unthrown = NULL;
   __cxa_throw (obj, tinfo, dest);
Index: libitm/testsuite/libitm.c++/throwdown.C
===================================================================
--- libitm/testsuite/libitm.c++/throwdown.C	(revision 0)
+++ libitm/testsuite/libitm.c++/throwdown.C	(revision 0)
@@ -0,0 +1,13 @@
+// { dg-do compile }
+
+#include <libitm.h>
+
+static void throwit() {
+	throw 1; 
+}
+
+void tranfunc() {
+	__transaction {
+		throwit();
+	}
+}
Index: gcc/cp/except.c
===================================================================
--- gcc/cp/except.c	(revision 161318)
+++ gcc/cp/except.c	(working copy)
@@ -209,7 +209,9 @@ do_begin_catch (void)
       if (flag_tm)
 	{
 	  tree fn2 = get_identifier ("_ITM_cxa_begin_catch");
-	  fn2 = declare_nothrow_library_fn (fn2, ptr_type_node, ptr_type_node);
+	  if (!get_global_value_if_present (fn2, &fn2))
+	    fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
+					      ptr_type_node);
 	  record_tm_replacement (fn, fn2);
 	}
     }
@@ -257,8 +259,11 @@ do_end_catch (tree type)
       if (flag_tm)
 	{
 	  tree fn2 = get_identifier ("_ITM_cxa_end_catch");
-	  fn2 = push_void_library_fn (fn2, void_list_node);
-	  TREE_NOTHROW (fn2) = 0;
+	  if (!get_global_value_if_present (fn2, &fn2))
+	    {
+	      fn2 = push_void_library_fn (fn2, void_list_node);
+	      TREE_NOTHROW (fn2) = 0;
+	    }
 	  record_tm_replacement (fn, fn2);
 	}
     }
@@ -576,7 +581,9 @@ do_allocate_exception (tree type)
       if (flag_tm)
 	{
 	  tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
-	  fn2 = declare_nothrow_library_fn (fn2, ptr_type_node, size_type_node);
+	  if (!get_global_value_if_present (fn2, &fn2))
+	    fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
+					      size_type_node);
 	  record_tm_replacement (fn, fn2);
 	}
     }
@@ -718,7 +725,8 @@ build_throw (tree exp)
 	  if (flag_tm)
 	    {
 	      tree fn2 = get_identifier ("_ITM_cxa_throw");
-	      fn2 = push_throw_library_fn (fn2, tmp);
+	      if (!get_global_value_if_present (fn2, &fn2))
+		fn2 = push_throw_library_fn (fn2, tmp);
 	      record_tm_replacement (fn, fn2);
 	    }
 	}
