Patchwork [trans-mem] make <libitm.h> work with C++

login
register
mail settings
Submitter Aldy Hernandez
Date July 16, 2010, 4:52 p.m.
Message ID <20100716165227.GA21636@redhat.com>
Download mbox | patch
Permalink /patch/59116/
State New
Headers show

Comments

Aldy Hernandez - July 16, 2010, 4:52 p.m.
Hi.

<libitm.h> was out of sync with the decls we were building in the C++ FE.

In fixing this, I realized we were calling
declare_nothrow_library_fn/etc regardless of if we had a global
definition.  This caused an ICE because somewhere down the call chain,
we replaced olddecl with newdecl, and poisoned the old one.  The way the
library building works in the C++ FE is that we first check
get_global_value_if_present() and only build the library decl if there's
no previous definition (presumably in the header files).

Tested on x86 32/64.

OK for branch?


libitm/
	* libitm.h (_ITM_cxa_allocate_exception): Add malloc attribute.
	(_ITM_cxa_throw): Change argument type.
	* eh_cpp.cc (__cxa_throw): Same.
	(_ITM_cxa_throw): Same.
gcc/
	* cp/except.c (do_begin_catch): Do not build TM library call if
	already defined.
	(do_end_catch): Same.
	(do_allocate_exception): Same.
	(build_throw): Same.

Patch

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);
 	    }
 	}