diff options
-rw-r--r-- | gdb/ChangeLog | 24 | ||||
-rw-r--r-- | gdb/common/poison.h | 31 | ||||
-rw-r--r-- | gdb/common/traits.h | 8 | ||||
-rw-r--r-- | gdb/gdb_obstack.h | 36 | ||||
-rw-r--r-- | gdb/gdbarch.c | 9 | ||||
-rw-r--r-- | gdb/gdbarch.h | 10 | ||||
-rwxr-xr-x | gdb/gdbarch.sh | 21 | ||||
-rw-r--r-- | gdb/target-descriptions.c | 7 |
8 files changed, 115 insertions, 31 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b15d8d1..fb4d955 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2018-05-20 Simon Marchi <simon.marchi@ericsson.com> + + * common/traits.h (HAVE_IS_TRIVIALLY_COPYABLE): Define if + compiler supports std::is_trivially_constructible. + * common/poison.h: Include obstack.h. + (IsMallocable): Define to is_trivially_constructible if the + compiler supports it, define to true_type otherwise. + (xobnew): New. + (XOBNEW): Redefine. + (xobnewvec): New. + (XOBNEWVEC): Redefine. + * gdb_obstack.h (obstack_zalloc): New. + (OBSTACK_ZALLOC): Redefine. + (obstack_calloc): New. + (OBSTACK_CALLOC): Redefine. + (obstack_new): New. + * gdbarch.sh: Include gdb_obstack in gdbarch.h. + (gdbarch_obstack): New declaration in gdbarch.h, definition in + gdbarch.c. + (GDBARCH_OBSTACK_CALLOC, GDBARCH_OBSTACK_ZALLOC): Use + obstack_calloc/obstack_zalloc. + (gdbarch_obstack_zalloc): Remove. + * target-descriptions.c (tdesc_data_init): Use obstack_new. + 2018-05-19 Philippe Waroquiers <philippe.waroquiers@skynet.be> * stack.c (backtrace_command_1): Remove useless variable int i. diff --git a/gdb/common/poison.h b/gdb/common/poison.h index c98d2b3..ddab2c1 100644 --- a/gdb/common/poison.h +++ b/gdb/common/poison.h @@ -21,6 +21,7 @@ #define COMMON_POISON_H #include "traits.h" +#include "obstack.h" /* Poison memset of non-POD types. The idea is catching invalid initialization of non-POD structs that is easy to be introduced as @@ -88,7 +89,11 @@ void *memmove (D *dest, const S *src, size_t n) = delete; objects that require new/delete. */ template<typename T> -using IsMallocable = std::is_pod<T>; +#if HAVE_IS_TRIVIALLY_CONSTRUCTIBLE +using IsMallocable = std::is_trivially_constructible<T>; +#else +using IsMallocable = std::true_type; +#endif template<typename T> using IsFreeable = gdb::Or<std::is_trivially_destructible<T>, std::is_void<T>>; @@ -216,4 +221,28 @@ non-POD data type."); #undef XRESIZEVAR #define XRESIZEVAR(T, P, S) xresizevar<T> (P, S) +template<typename T> +static T * +xobnew (obstack *ob) +{ + static_assert (IsMallocable<T>::value, "Trying to use XOBNEW with a \ +non-POD data type."); + return XOBNEW (ob, T); +} + +#undef XOBNEW +#define XOBNEW(O, T) xobnew<T> (O) + +template<typename T> +static T * +xobnewvec (obstack *ob, size_t n) +{ + static_assert (IsMallocable<T>::value, "Trying to use XOBNEWVEC with a \ +non-POD data type."); + return XOBNEWVEC (ob, T, n); +} + +#undef XOBNEWVEC +#define XOBNEWVEC(O, T, N) xobnewvec<T> (O, N) + #endif /* COMMON_POISON_H */ diff --git a/gdb/common/traits.h b/gdb/common/traits.h index d9e6839..070ef15 100644 --- a/gdb/common/traits.h +++ b/gdb/common/traits.h @@ -33,6 +33,14 @@ # define HAVE_IS_TRIVIALLY_COPYABLE 1 #endif +/* HAVE_IS_TRIVIALLY_CONSTRUCTIBLE is defined as 1 iff + std::is_trivially_constructible is available. GCC only implemented it + in GCC 5. */ +#if (__has_feature(is_trivially_constructible) \ + || (defined __GNUC__ && __GNUC__ >= 5)) +# define HAVE_IS_TRIVIALLY_COPYABLE 1 +#endif + namespace gdb { /* Pre C++14-safe (CWG 1558) version of C++17's std::void_t. See diff --git a/gdb/gdb_obstack.h b/gdb/gdb_obstack.h index 1011008..29cad93 100644 --- a/gdb/gdb_obstack.h +++ b/gdb/gdb_obstack.h @@ -24,12 +24,40 @@ /* Utility macros - wrap obstack alloc into something more robust. */ -#define OBSTACK_ZALLOC(OBSTACK,TYPE) \ - ((TYPE *) memset (obstack_alloc ((OBSTACK), sizeof (TYPE)), 0, sizeof (TYPE))) +template <typename T> +static inline T* +obstack_zalloc (struct obstack *ob) +{ + static_assert (IsMallocable<T>::value, "Trying to use OBSTACK_ZALLOC with a \ +non-POD data type. Use obstack_new instead."); + return ((T *) memset (obstack_alloc (ob, sizeof (T)), 0, sizeof (T))); +} + +#define OBSTACK_ZALLOC(OBSTACK,TYPE) obstack_zalloc<TYPE> ((OBSTACK)) + +template <typename T> +static inline T * +obstack_calloc (struct obstack *ob, size_t number) +{ + static_assert (IsMallocable<T>::value, "Trying to use OBSTACK_CALLOC with a \ +non-POD data type. Use obstack_new instead."); + return ((T *) memset (obstack_alloc (ob, number * sizeof (T)), 0, + number * sizeof (T))); +} #define OBSTACK_CALLOC(OBSTACK,NUMBER,TYPE) \ - ((TYPE *) memset (obstack_alloc ((OBSTACK), (NUMBER) * sizeof (TYPE)), \ - 0, (NUMBER) * sizeof (TYPE))) + obstack_calloc<TYPE> ((OBSTACK), (NUMBER)) + +/* Allocate an object on OB and call its constructor. */ + +template <typename T, typename... Args> +static inline T* +obstack_new (struct obstack *ob, Args&&... args) +{ + T* object = (T *) obstack_alloc (ob, sizeof (T)); + object = new (object) T (std::forward<Args> (args)...); + return object; +} /* Unless explicitly specified, GDB obstacks always use xmalloc() and xfree(). */ diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 82ac751..c430ebe 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -471,15 +471,10 @@ gdbarch_alloc (const struct gdbarch_info *info, } -/* Allocate extra space using the per-architecture obstack. */ -void * -gdbarch_obstack_zalloc (struct gdbarch *arch, long size) +obstack *gdbarch_obstack (gdbarch *arch) { - void *data = obstack_alloc (arch->obstack, size); - - memset (data, 0, size); - return data; + return arch->obstack; } /* See gdbarch.h. */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index b3a15c9..09edcd5 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -38,6 +38,7 @@ #include <vector> #include "frame.h" #include "dis-asm.h" +#include "gdb_obstack.h" struct floatformat; struct ui_file; @@ -1705,14 +1706,17 @@ extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, struct gd extern void gdbarch_free (struct gdbarch *); +/* Get the obstack owned by ARCH. */ + +extern obstack *gdbarch_obstack (gdbarch *arch); /* Helper function. Allocate memory from the ``struct gdbarch'' obstack. The memory is freed when the corresponding architecture is also freed. */ -extern void *gdbarch_obstack_zalloc (struct gdbarch *gdbarch, long size); -#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), (NR) * sizeof (TYPE))) -#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), sizeof (TYPE))) +#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) obstack_calloc<TYPE> (gdbarch_obstack ((GDBARCH)), (NR)) + +#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) obstack_zalloc<TYPE> (gdbarch_obstack ((GDBARCH))) /* Duplicate STRING, returning an equivalent string that's allocated on the obstack associated with GDBARCH. The string is freed when the corresponding diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index bf12c68..7330430 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -1261,6 +1261,7 @@ cat <<EOF #include <vector> #include "frame.h" #include "dis-asm.h" +#include "gdb_obstack.h" struct floatformat; struct ui_file; @@ -1532,14 +1533,19 @@ extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, struct gd extern void gdbarch_free (struct gdbarch *); +/* Get the obstack owned by ARCH. */ + +extern obstack *gdbarch_obstack (gdbarch *arch); /* Helper function. Allocate memory from the \`\`struct gdbarch'' obstack. The memory is freed when the corresponding architecture is also freed. */ -extern void *gdbarch_obstack_zalloc (struct gdbarch *gdbarch, long size); -#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), (NR) * sizeof (TYPE))) -#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) ((TYPE *) gdbarch_obstack_zalloc ((GDBARCH), sizeof (TYPE))) +#define GDBARCH_OBSTACK_CALLOC(GDBARCH, NR, TYPE) \ + obstack_calloc<TYPE> (gdbarch_obstack ((GDBARCH)), (NR)) + +#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) \ + obstack_zalloc<TYPE> (gdbarch_obstack ((GDBARCH))) /* Duplicate STRING, returning an equivalent string that's allocated on the obstack associated with GDBARCH. The string is freed when the corresponding @@ -1849,15 +1855,10 @@ EOF printf "\n" printf "\n" cat <<EOF -/* Allocate extra space using the per-architecture obstack. */ -void * -gdbarch_obstack_zalloc (struct gdbarch *arch, long size) +obstack *gdbarch_obstack (gdbarch *arch) { - void *data = obstack_alloc (arch->obstack, size); - - memset (data, 0, size); - return data; + return arch->obstack; } /* See gdbarch.h. */ diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index e20bf9b..83a6f6c 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -723,12 +723,7 @@ tdesc_find_type (struct gdbarch *gdbarch, const char *id) static void * tdesc_data_init (struct obstack *obstack) { - struct tdesc_arch_data *data; - - data = OBSTACK_ZALLOC (obstack, struct tdesc_arch_data); - new (data) tdesc_arch_data (); - - return data; + return obstack_new<tdesc_arch_data> (obstack); } /* Similar, but for the temporary copy used during architecture |