unbreak throw declarations on operators new/delete

We now clearly separate PERFTOOLS_NOTHROW (used for tc_XXX functions)
and throw()/noexcept (used for operators we define).

The former is basically "nothrow() for our callers, nothing for
us". It is roughly equivalent of what glibc declares for malloc and
friends. If some exception-full C++ code calls such function it
doesn't have to bother setting up exception handling around such
call. Notably, it is still important for those functions to _not have
throw() declarations when we're building tcmalloc. Because C++ throw()
requires setting up handling of unexpected exceptions thrown from
under such functions which we don't want.

The later is necessary to have operators new/delete definitions have
"correct" exception specifications to calm down compiler
warnings. Particularly older clang versions warn if new/delete aren't
defined with correct exception specifications. Also this commit fixes
annoying gcc 7+ warning (and gnu++14 mode) that complains about
throw() being deprecated.
This commit is contained in:
Aliaksey Kandratsenka 2017-11-29 20:19:07 +00:00
parent 89fe59c831
commit 03da6afff5
6 changed files with 67 additions and 70 deletions

View File

@ -433,11 +433,4 @@ namespace base {
enum LinkerInitialized { LINKER_INITIALIZED };
}
#if __cpp_noexcept_function_type >= 201510
// Deprecated in C++17
# define PERFTOOLS_THROW(...)
#else
# define PERFTOOLS_THROW(...) throw(__VA_ARGS__)
#endif
#endif // _BASICTYPES_H_

View File

@ -58,6 +58,14 @@
#endif
#include <gperftools/tcmalloc.h>
#if __cplusplus >= 201103L
#define CPP_NOTHROW noexcept
#define CPP_BADALLOC
#else
#define CPP_NOTHROW throw()
#define CPP_BADALLOC throw(std::bad_alloc)
#endif
static void ReplaceSystemAlloc(); // defined in the .h files below
// For windows, there are two ways to get tcmalloc. If we're

View File

@ -57,38 +57,34 @@
#define ALIAS(tc_fn) __attribute__ ((alias (#tc_fn), used))
void* operator new(size_t size) PERFTOOLS_THROW(std::bad_alloc)
ALIAS(tc_new);
void operator delete(void* p) PERFTOOLS_NOTHROW
ALIAS(tc_delete);
void* operator new[](size_t size) PERFTOOLS_THROW(std::bad_alloc)
ALIAS(tc_newarray);
void operator delete[](void* p) PERFTOOLS_NOTHROW
ALIAS(tc_deletearray);
void* operator new(size_t size, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
ALIAS(tc_new_nothrow);
void* operator new[](size_t size, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
ALIAS(tc_newarray_nothrow);
void operator delete(void* p, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
ALIAS(tc_delete_nothrow);
void operator delete[](void* p, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
ALIAS(tc_deletearray_nothrow);
void* operator new(size_t size) CPP_BADALLOC ALIAS(tc_new);
void operator delete(void* p) CPP_NOTHROW ALIAS(tc_delete);
void* operator new[](size_t size) CPP_BADALLOC ALIAS(tc_newarray);
void operator delete[](void* p) CPP_NOTHROW ALIAS(tc_deletearray);
void* operator new(size_t size, const std::nothrow_t& nt) CPP_NOTHROW
ALIAS(tc_new_nothrow);
void* operator new[](size_t size, const std::nothrow_t& nt) CPP_NOTHROW
ALIAS(tc_newarray_nothrow);
void operator delete(void* p, const std::nothrow_t& nt) CPP_NOTHROW
ALIAS(tc_delete_nothrow);
void operator delete[](void* p, const std::nothrow_t& nt) CPP_NOTHROW
ALIAS(tc_deletearray_nothrow);
#if defined(ENABLE_SIZED_DELETE)
void operator delete(void *p, size_t size) PERFTOOLS_NOTHROW
void operator delete(void *p, size_t size) CPP_NOTHROW
ALIAS(tc_delete_sized);
void operator delete[](void *p, size_t size) PERFTOOLS_NOTHROW
void operator delete[](void *p, size_t size) CPP_NOTHROW
ALIAS(tc_deletearray_sized);
#elif defined(ENABLE_DYNAMIC_SIZED_DELETE) && \
(__GNUC__ * 100 + __GNUC_MINOR__) >= 405
static void delegate_sized_delete(void *p, size_t s) PERFTOOLS_NOTHROW {
static void delegate_sized_delete(void *p, size_t s) {
(operator delete)(p);
}
static void delegate_sized_deletearray(void *p, size_t s) PERFTOOLS_NOTHROW {
static void delegate_sized_deletearray(void *p, size_t s) {
(operator delete[])(p);
}
@ -122,44 +118,44 @@ static void *resolve_deletearray_sized(void) {
}
void operator delete(void *p, size_t size) PERFTOOLS_NOTHROW
void operator delete(void *p, size_t size) CPP_NOTHROW
__attribute__((ifunc("resolve_delete_sized")));
void operator delete[](void *p, size_t size) PERFTOOLS_NOTHROW
void operator delete[](void *p, size_t size) CPP_NOTHROW
__attribute__((ifunc("resolve_deletearray_sized")));
#else /* !ENABLE_SIZED_DELETE && !ENABLE_DYN_SIZED_DELETE */
void operator delete(void *p, size_t size) PERFTOOLS_NOTHROW
void operator delete(void *p, size_t size) CPP_NOTHROW
ALIAS(tc_delete);
void operator delete[](void *p, size_t size) PERFTOOLS_NOTHROW
void operator delete[](void *p, size_t size) CPP_NOTHROW
ALIAS(tc_deletearray);
#endif /* !ENABLE_SIZED_DELETE && !ENABLE_DYN_SIZED_DELETE */
#if defined(ENABLE_ALIGNED_NEW_DELETE)
void* operator new(size_t size, std::align_val_t al) PERFTOOLS_THROW(std::bad_alloc)
void* operator new(size_t size, std::align_val_t al)
ALIAS(tc_new_aligned);
void operator delete(void* p, std::align_val_t al) PERFTOOLS_NOTHROW
void operator delete(void* p, std::align_val_t al) CPP_NOTHROW
ALIAS(tc_delete_aligned);
void* operator new[](size_t size, std::align_val_t al) PERFTOOLS_THROW(std::bad_alloc)
void* operator new[](size_t size, std::align_val_t al)
ALIAS(tc_newarray_aligned);
void operator delete[](void* p, std::align_val_t al) PERFTOOLS_NOTHROW
void operator delete[](void* p, std::align_val_t al) CPP_NOTHROW
ALIAS(tc_deletearray_aligned);
void* operator new(size_t size, std::align_val_t al, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
void* operator new(size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
ALIAS(tc_new_aligned_nothrow);
void* operator new[](size_t size, std::align_val_t al, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
void* operator new[](size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
ALIAS(tc_newarray_aligned_nothrow);
void operator delete(void* p, std::align_val_t al, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
void operator delete(void* p, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
ALIAS(tc_delete_aligned_nothrow);
void operator delete[](void* p, std::align_val_t al, const std::nothrow_t& nt) PERFTOOLS_NOTHROW
void operator delete[](void* p, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW
ALIAS(tc_deletearray_aligned_nothrow);
#if defined(ENABLE_SIZED_DELETE)
void operator delete(void *p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
ALIAS(tc_delete_sized_aligned);
void operator delete[](void *p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
ALIAS(tc_deletearray_sized_aligned);
#else /* defined(ENABLE_SIZED_DELETE) */
@ -167,11 +163,11 @@ void operator delete[](void *p, size_t size, std::align_val_t al) PERFTOOLS_NOTH
#if defined(ENABLE_DYNAMIC_SIZED_DELETE) && \
(__GNUC__ * 100 + __GNUC_MINOR__) >= 405
static void delegate_sized_aligned_delete(void *p, size_t s, std::align_val_t al) PERFTOOLS_NOTHROW {
static void delegate_sized_aligned_delete(void *p, size_t s, std::align_val_t al) {
(operator delete)(p, al);
}
static void delegate_sized_aligned_deletearray(void *p, size_t s, std::align_val_t al) PERFTOOLS_NOTHROW {
static void delegate_sized_aligned_deletearray(void *p, size_t s, std::align_val_t al) {
(operator delete[])(p, al);
}
@ -193,16 +189,16 @@ static void *resolve_deletearray_sized_aligned(void) {
}
void operator delete(void *p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
__attribute__((ifunc("resolve_delete_sized_aligned")));
void operator delete[](void *p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
__attribute__((ifunc("resolve_deletearray_sized_aligned")));
#else /* defined(ENABLE_DYN_SIZED_DELETE) */
void operator delete(void *p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
void operator delete(void *p, size_t size, std::align_val_t al) CPP_NOTHROW
ALIAS(tc_delete);
void operator delete[](void *p, size_t size, std::align_val_t al) PERFTOOLS_NOTHROW
void operator delete[](void *p, size_t size, std::align_val_t al) CPP_NOTHROW
ALIAS(tc_deletearray);
#endif /* defined(ENABLE_DYN_SIZED_DELETE) */

View File

@ -43,25 +43,25 @@
#define TCMALLOC_LIBC_OVERRIDE_REDEFINE_H_
void* operator new(size_t size) { return tc_new(size); }
void operator delete(void* p) PERFTOOLS_NOTHROW { tc_delete(p); }
void operator delete(void* p) CPP_NOTHROW { tc_delete(p); }
void* operator new[](size_t size) { return tc_newarray(size); }
void operator delete[](void* p) PERFTOOLS_NOTHROW { tc_deletearray(p); }
void* operator new(size_t size, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
void operator delete[](void* p) CPP_NOTHROW { tc_deletearray(p); }
void* operator new(size_t size, const std::nothrow_t& nt) CPP_NOTHROW {
return tc_new_nothrow(size, nt);
}
void* operator new[](size_t size, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
void* operator new[](size_t size, const std::nothrow_t& nt) CPP_NOTHROW {
return tc_newarray_nothrow(size, nt);
}
void operator delete(void* ptr, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
void operator delete(void* ptr, const std::nothrow_t& nt) CPP_NOTHROW {
return tc_delete_nothrow(ptr, nt);
}
void operator delete[](void* ptr, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
void operator delete[](void* ptr, const std::nothrow_t& nt) CPP_NOTHROW {
return tc_deletearray_nothrow(ptr, nt);
}
#ifdef ENABLE_SIZED_DELETE
void operator delete(void* p, size_t s) PERFTOOLS_NOTHROW { tc_delete_sized(p, s); }
void operator delete[](void* p, size_t s) PERFTOOLS_NOTHROW{ tc_deletearray_sized(p, s); }
void operator delete(void* p, size_t s) CPP_NOTHROW { tc_delete_sized(p, s); }
void operator delete[](void* p, size_t s) CPP_NOTHROW{ tc_deletearray_sized(p, s);}
#endif
#if defined(ENABLE_ALIGNED_NEW_DELETE)
@ -69,33 +69,33 @@ void operator delete[](void* p, size_t s) PERFTOOLS_NOTHROW{ tc_deletearray_size
void* operator new(size_t size, std::align_val_t al) {
return tc_new_aligned(size, al);
}
void operator delete(void* p, std::align_val_t al) PERFTOOLS_NOTHROW {
void operator delete(void* p, std::align_val_t al) CPP_NOTHROW {
tc_delete_aligned(p, al);
}
void* operator new[](size_t size, std::align_val_t al) {
return tc_newarray_aligned(size, al);
}
void operator delete[](void* p, std::align_val_t al) PERFTOOLS_NOTHROW {
void operator delete[](void* p, std::align_val_t al) CPP_NOTHROW {
tc_deletearray_aligned(p, al);
}
void* operator new(size_t size, std::align_val_t al, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
void* operator new(size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
return tc_new_aligned_nothrow(size, al, nt);
}
void* operator new[](size_t size, std::align_val_t al, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
void* operator new[](size_t size, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
return tc_newarray_aligned_nothrow(size, al, nt);
}
void operator delete(void* ptr, std::align_val_t al, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
void operator delete(void* ptr, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
return tc_delete_aligned_nothrow(ptr, al, nt);
}
void operator delete[](void* ptr, std::align_val_t al, const std::nothrow_t& nt) PERFTOOLS_NOTHROW {
void operator delete[](void* ptr, std::align_val_t al, const std::nothrow_t& nt) CPP_NOTHROW {
return tc_deletearray_aligned_nothrow(ptr, al, nt);
}
#ifdef ENABLE_SIZED_DELETE
void operator delete(void* p, size_t s, std::align_val_t al) PERFTOOLS_NOTHROW {
void operator delete(void* p, size_t s, std::align_val_t al) CPP_NOTHROW {
tc_delete_sized_aligned(p, s, al);
}
void operator delete[](void* p, size_t s, std::align_val_t al) PERFTOOLS_NOTHROW {
void operator delete[](void* p, size_t s, std::align_val_t al) CPP_NOTHROW {
tc_deletearray_sized_aligned(p, s, al);
}
#endif

View File

@ -679,7 +679,7 @@ static void TestRealloc() {
#endif
}
static void TestNewHandler() PERFTOOLS_THROW(std::bad_alloc) {
static void TestNewHandler() {
++news_handled;
throw std::bad_alloc();
}

View File

@ -55,11 +55,11 @@
static char m; // some dummy memory so new doesn't return NULL.
void* operator new(size_t size) { return &m; }
void operator delete(void* p) PERFTOOLS_NOTHROW { }
void operator delete(void* p) throw() { }
void* operator new[](size_t size) { return &m; }
void operator delete[](void* p) PERFTOOLS_NOTHROW { }
void operator delete[](void* p) throw() { }
void* operator new(size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW { return &m; }
void operator delete(void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW { }
void* operator new[](size_t size, const std::nothrow_t&) PERFTOOLS_NOTHROW { return &m; }
void operator delete[](void* p, const std::nothrow_t&) PERFTOOLS_NOTHROW { }
void* operator new(size_t size, const std::nothrow_t&) throw() { return &m; }
void operator delete(void* p, const std::nothrow_t&) throw() { }
void* operator new[](size_t size, const std::nothrow_t&) throw() { return &m; }
void operator delete[](void* p, const std::nothrow_t&) throw() { }