Fix throw specifiers on interface.
authorNathan Sidwell <nathan@acm.org>
Tue, 12 May 2020 17:54:53 +0000 (10:54 -0700)
committerNathan Sidwell <nathan@acm.org>
Tue, 12 May 2020 17:54:53 +0000 (10:54 -0700)
I discovered that libitm:
(a) declares __cxa_allocate_exception and friends directly,
(b) doesn't mark them as 'throw()'
(c) doesn't mark the replacment fns _ITM_$foo as nothrow either

We happen to get away with it because of code in the compiler that,
although it checks the parameter types, doesn't check the exception
specification.  (One reason being they used to not be part of the
language's type system, but now they are.)  I suspect this can lead us
to generate pessimal code later, if we've seen one of these decls
earlier.  Anyway, with modules it becomes trickier[*], so I'm trying
to clean it up and not be a problem.  I see Jakub fixed part of the
problem
(https://gcc.gnu.org/pipermail/gcc-patches/2018-December/513302.html)
AFAICT, he did fix libitm's decls, but left the lax parm-type checking
in the compiler.

libitm.h is not very informative about specification:
  in version 1 of http://www.intel.com/some/path/here.pdf.  */

Anyway, it was too fiddly to have libitm pick up the declarations from
libsupc++.  Besides it makes them weak declarations, and then provides
definitions for non-elf systems.  So this patch adds the expected
'throw()'

* libitm/libitm.h (_ITM_NOTHROW): Define.
(_ITM_cxa_allocate_exception, _ITM_cxa_free_exception)
(_ITM_cxa_begin_catch): Use it.
* eh_cpp.cc: Add throw() to __cxa_allocate_exception,
__cxa_free_exception, __cxa_begin_catch, __cxa_tm_cleanup,
__cxa_get_globals.
(_ITM_cxa_allocate_exception, _ITM_cxa_free_exception)
(_ITM_cxa_begin_catch): Likewise.

libitm/ChangeLog
libitm/eh_cpp.cc
libitm/libitm.h

index 37a1b443e11c80bb7bf4c97639ff3dae4e83779c..295fb9440678973fe8954bb40a73c93b99fefe03 100644 (file)
@@ -1,3 +1,15 @@
+2020-05-12  Nathan Sidwell  <nathan@acm.org>
+
+       Fix throw specifiers on interface.
+       * libitm/libitm.h (_ITM_NOTHROW): Define.
+       (_ITM_cxa_allocate_exception, _ITM_cxa_free_exception)
+       (_ITM_cxa_begin_catch): Use it.
+       * eh_cpp.cc: Add throw() to __cxa_allocate_exception,
+       __cxa_free_exception, __cxa_begin_catch, __cxa_tm_cleanup,
+       __cxa_get_globals.
+       (_ITM_cxa_allocate_exception, _ITM_cxa_free_exception)
+       (_ITM_cxa_begin_catch): Likewise.
+
 2020-05-05  Nathan Sidwell  <nathan@acm.org>
 
        * testsuite/lib/libitm.exp (libitm_init): Add
index 7d570e74fc2e621fdc3f26b53f4d06b6c177e97d..6c9da2d06e4c53b4cd7ffe73034e7d0ebb7e2a52 100644 (file)
@@ -87,23 +87,23 @@ struct __cxa_eh_globals
   unsigned int uncaughtExceptions;
 };
 
-extern void *__cxa_allocate_exception (size_t) WEAK;
-extern void __cxa_free_exception (void *) WEAK;
+extern void *__cxa_allocate_exception (size_t) _ITM_NOTHROW WEAK;
+extern void __cxa_free_exception (void *) _ITM_NOTHROW WEAK;
 extern void __cxa_throw (void *, void *, void (*) (void *)) WEAK;
-extern void *__cxa_begin_catch (void *) WEAK;
+extern void *__cxa_begin_catch (void *) _ITM_NOTHROW WEAK;
 extern void __cxa_end_catch (void) WEAK;
-extern void __cxa_tm_cleanup (void *, void *, unsigned int) WEAK;
-extern __cxa_eh_globals *__cxa_get_globals (void) WEAK;
+extern void __cxa_tm_cleanup (void *, void *, unsigned int) throw () WEAK;
+extern __cxa_eh_globals *__cxa_get_globals (void) _ITM_NOTHROW WEAK;
 
 #if !defined (HAVE_ELF_STYLE_WEAKREF) 
-void *__cxa_allocate_exception (size_t) { return NULL; }
-void __cxa_free_exception (void *) { return; }
+void *__cxa_allocate_exception (size_t) _ITM_NOTHROW { return NULL; }
+void __cxa_free_exception (void *) _ITM_NOTHROW { return; }
 void __cxa_throw (void *, void *, void (*) (void *)) { return; }
-void *__cxa_begin_catch (void *) { return NULL; }
+void *__cxa_begin_catch (void *) _ITM_NOTHROW { return NULL; }
 void __cxa_end_catch (void) { return; }
-void __cxa_tm_cleanup (void *, void *, unsigned int) { return; }
+void __cxa_tm_cleanup (void *, void *, unsigned int) throw () { return; }
 void _Unwind_DeleteException (_Unwind_Exception *) { return; }
-__cxa_eh_globals *__cxa_get_globals (void) { return NULL; }
+__cxa_eh_globals *__cxa_get_globals (void) _ITM_NOTHROW { return NULL; }
 #endif /* HAVE_ELF_STYLE_WEAKREF */
 
 }
@@ -117,7 +117,7 @@ free_any_exception (void *exc_ptr)
 }
 
 void *
-_ITM_cxa_allocate_exception (size_t size)
+_ITM_cxa_allocate_exception (size_t size) _ITM_NOTHROW
 {
   void *r = __cxa_allocate_exception (size);
   gtm_thr()->record_allocation (r, free_any_exception);
@@ -125,7 +125,7 @@ _ITM_cxa_allocate_exception (size_t size)
 }
 
 void
-_ITM_cxa_free_exception (void *exc_ptr)
+_ITM_cxa_free_exception (void *exc_ptr) _ITM_NOTHROW
 {
   // __cxa_free_exception can be called from user code directly if
   // construction of an exception object throws another exception, in which
@@ -143,7 +143,7 @@ _ITM_cxa_throw (void *obj, void *tinfo, void (*dest) (void *))
 }
 
 void *
-_ITM_cxa_begin_catch (void *exc_ptr)
+_ITM_cxa_begin_catch (void *exc_ptr) _ITM_NOTHROW
 {
   // If this exception object has been allocated by this transaction, we
   // discard the undo log entry for the allocation; we are entering phase (3)
index 69f551e2675ad2db56fbef07bbca12964cd5cb26..4f8051bdfb7883a220dfd4e5074cb98d97099395 100644 (file)
@@ -45,6 +45,15 @@ extern "C" {
 
 #define ITM_NORETURN   __attribute__((noreturn))
 #define ITM_PURE __attribute__((transaction_pure))
+#ifdef _GLIBCXX_NOTHROW
+# define _ITM_NOTHROW _GLIBCXX_NOTHROW
+#elif !defined (__cplusplus)
+# define _ITM_NOTHROW __attribute__((__nothrow__))
+#elif __cplusplus < 201103L
+# define _ITM_NOTHROW throw ()
+#else
+# define _ITM_NOTHROW noexcept
+#endif  
 
 /* The following are externally visible definitions and functions, though
    only very few of these should be called by user code.  */
@@ -282,11 +291,11 @@ extern void *_ITM_getTMCloneSafe (void *) ITM_REGPARM;
 extern void _ITM_registerTMCloneTable (void *, size_t);
 extern void _ITM_deregisterTMCloneTable (void *);
 
-extern void *_ITM_cxa_allocate_exception (size_t);
-extern void _ITM_cxa_free_exception (void *exc_ptr);
+extern void *_ITM_cxa_allocate_exception (size_t) _ITM_NOTHROW;
+extern void _ITM_cxa_free_exception (void *exc_ptr) _ITM_NOTHROW;
 extern void _ITM_cxa_throw (void *obj, void *tinfo, void (*dest) (void *));
-extern void *_ITM_cxa_begin_catch (void *exc_ptr);
-extern void _ITM_cxa_end_catch (void);
+extern void *_ITM_cxa_begin_catch (void *exc_ptr) _ITM_NOTHROW;
+extern void _ITM_cxa_end_catch (void); /* This can throw.  */
 extern void _ITM_commitTransactionEH(void *exc_ptr) ITM_REGPARM;
 
 #ifdef __cplusplus