[05/12] gdb: make gdbarch_alloc take ownership of the tdep

Message ID 20221206135729.3937767-6-simon.marchi@efficios.com
State Committed
Commit 2b16913cdca20ae1dafdbd816b025a6efdc6c06f
Headers
Series Initial support for ROCm platform (AMDGPU) debugging |

Commit Message

Simon Marchi Dec. 6, 2022, 1:57 p.m. UTC
  From: Simon Marchi <simon.marchi@polymtl.ca>

It's currently not clear how the ownership of gdbarch_tdep objects
works.  In fact, nothing ever takes ownership of it.  This is mostly
fine because we never free gdbarch objects, and thus we never free
gdbarch_tdep objects.  There is an exception to that however: when
initialization fails, we do free the gdbarch object that is not going to
be used, and we free the tdep too.  Currently, i386 and s390 do it.

To make things clearer, change gdbarch_alloc so that it takes ownership
of the tdep.  The tdep is thus automatically freed if the gdbarch is
freed.

Change all gdbarch initialization functions to pass a new gdbarch_tdep
object to gdbarch_alloc and then retrieve a non-owning reference from
the gdbarch object.

Before this patch, the xtensa architecture had a single global instance
of xtensa_gdbarch_tdep.  Since we need to pass a dynamically allocated
gdbarch_tdep_base instance to gdbarch_alloc, remove this global
instance, and dynamically allocate one as needed, like we do for all
other architectures.  Make the `rmap` array externally visible and
rename it to the less collision-prone `xtensa_rmap` name.

Change-Id: Id3d70493ef80ce4bdff701c57636f4c79ed8aea2
---
 gdb/aarch64-tdep.c    |  5 +++--
 gdb/alpha-tdep.c      |  7 +++----
 gdb/arc-tdep.c        |  6 +++---
 gdb/arch-utils.c      |  2 +-
 gdb/arm-tdep.c        |  6 +++---
 gdb/avr-tdep.c        |  6 +++---
 gdb/bfin-tdep.c       |  6 +++---
 gdb/bpf-tdep.c        |  4 ++--
 gdb/cris-tdep.c       |  6 +++---
 gdb/csky-tdep.c       |  7 ++++---
 gdb/frv-tdep.c        | 15 ++++++++-------
 gdb/ft32-tdep.c       |  6 +++---
 gdb/gdbarch.c         |  6 +++---
 gdb/gdbarch.h         |  5 ++++-
 gdb/hppa-tdep.c       |  7 +++----
 gdb/i386-tdep.c       |  7 +++----
 gdb/ia64-tdep.c       |  7 +++----
 gdb/lm32-tdep.c       |  6 ++----
 gdb/loongarch-tdep.c  |  6 ++++--
 gdb/m32c-tdep.c       |  5 ++---
 gdb/m32r-tdep.c       |  6 ++----
 gdb/m68hc11-tdep.c    |  7 ++++---
 gdb/m68k-tdep.c       |  7 ++++---
 gdb/mep-tdep.c        |  7 +++----
 gdb/microblaze-tdep.c |  5 ++---
 gdb/mips-tdep.c       |  7 ++++---
 gdb/mn10300-tdep.c    |  6 +++---
 gdb/moxie-tdep.c      |  6 ++----
 gdb/msp430-tdep.c     |  7 ++++---
 gdb/nds32-tdep.c      |  8 ++++----
 gdb/nios2-tdep.c      |  6 +++---
 gdb/or1k-tdep.c       |  7 ++++---
 gdb/riscv-tdep.c      |  7 ++++---
 gdb/rl78-tdep.c       |  7 ++++---
 gdb/rs6000-tdep.c     |  8 ++++----
 gdb/rx-tdep.c         |  7 ++++---
 gdb/s12z-tdep.c       |  4 ++--
 gdb/s390-tdep.c       | 13 +++++--------
 gdb/s390-tdep.h       |  2 ++
 gdb/sh-tdep.c         |  6 ++----
 gdb/sparc-tdep.c      |  6 +++---
 gdb/tic6x-tdep.c      |  6 +++---
 gdb/v850-tdep.c       |  7 ++++---
 gdb/xtensa-config.c   |  4 +---
 gdb/xtensa-tdep.c     | 10 +++++-----
 gdb/z80-tdep.c        |  6 +++---
 46 files changed, 148 insertions(+), 149 deletions(-)
  

Comments

Andrew Burgess Dec. 6, 2022, 5:06 p.m. UTC | #1
Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

> From: Simon Marchi <simon.marchi@polymtl.ca>
>
> It's currently not clear how the ownership of gdbarch_tdep objects
> works.  In fact, nothing ever takes ownership of it.  This is mostly
> fine because we never free gdbarch objects, and thus we never free
> gdbarch_tdep objects.  There is an exception to that however: when
> initialization fails, we do free the gdbarch object that is not going to
> be used, and we free the tdep too.  Currently, i386 and s390 do it.
>
> To make things clearer, change gdbarch_alloc so that it takes ownership
> of the tdep.  The tdep is thus automatically freed if the gdbarch is
> freed.
>
> Change all gdbarch initialization functions to pass a new gdbarch_tdep
> object to gdbarch_alloc and then retrieve a non-owning reference from
> the gdbarch object.
>
> Before this patch, the xtensa architecture had a single global instance
> of xtensa_gdbarch_tdep.  Since we need to pass a dynamically allocated
> gdbarch_tdep_base instance to gdbarch_alloc, remove this global
> instance, and dynamically allocate one as needed, like we do for all
> other architectures.  Make the `rmap` array externally visible and
> rename it to the less collision-prone `xtensa_rmap` name.

LGTM.

Thanks,
Andrew

>
> Change-Id: Id3d70493ef80ce4bdff701c57636f4c79ed8aea2
> ---
>  gdb/aarch64-tdep.c    |  5 +++--
>  gdb/alpha-tdep.c      |  7 +++----
>  gdb/arc-tdep.c        |  6 +++---
>  gdb/arch-utils.c      |  2 +-
>  gdb/arm-tdep.c        |  6 +++---
>  gdb/avr-tdep.c        |  6 +++---
>  gdb/bfin-tdep.c       |  6 +++---
>  gdb/bpf-tdep.c        |  4 ++--
>  gdb/cris-tdep.c       |  6 +++---
>  gdb/csky-tdep.c       |  7 ++++---
>  gdb/frv-tdep.c        | 15 ++++++++-------
>  gdb/ft32-tdep.c       |  6 +++---
>  gdb/gdbarch.c         |  6 +++---
>  gdb/gdbarch.h         |  5 ++++-
>  gdb/hppa-tdep.c       |  7 +++----
>  gdb/i386-tdep.c       |  7 +++----
>  gdb/ia64-tdep.c       |  7 +++----
>  gdb/lm32-tdep.c       |  6 ++----
>  gdb/loongarch-tdep.c  |  6 ++++--
>  gdb/m32c-tdep.c       |  5 ++---
>  gdb/m32r-tdep.c       |  6 ++----
>  gdb/m68hc11-tdep.c    |  7 ++++---
>  gdb/m68k-tdep.c       |  7 ++++---
>  gdb/mep-tdep.c        |  7 +++----
>  gdb/microblaze-tdep.c |  5 ++---
>  gdb/mips-tdep.c       |  7 ++++---
>  gdb/mn10300-tdep.c    |  6 +++---
>  gdb/moxie-tdep.c      |  6 ++----
>  gdb/msp430-tdep.c     |  7 ++++---
>  gdb/nds32-tdep.c      |  8 ++++----
>  gdb/nios2-tdep.c      |  6 +++---
>  gdb/or1k-tdep.c       |  7 ++++---
>  gdb/riscv-tdep.c      |  7 ++++---
>  gdb/rl78-tdep.c       |  7 ++++---
>  gdb/rs6000-tdep.c     |  8 ++++----
>  gdb/rx-tdep.c         |  7 ++++---
>  gdb/s12z-tdep.c       |  4 ++--
>  gdb/s390-tdep.c       | 13 +++++--------
>  gdb/s390-tdep.h       |  2 ++
>  gdb/sh-tdep.c         |  6 ++----
>  gdb/sparc-tdep.c      |  6 +++---
>  gdb/tic6x-tdep.c      |  6 +++---
>  gdb/v850-tdep.c       |  7 ++++---
>  gdb/xtensa-config.c   |  4 +---
>  gdb/xtensa-tdep.c     | 10 +++++-----
>  gdb/z80-tdep.c        |  6 +++---
>  46 files changed, 148 insertions(+), 149 deletions(-)
>
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index cf20bb40b78..e59fcf726ae 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -3664,8 +3664,9 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>    /* AArch64 code is always little-endian.  */
>    info.byte_order_for_code = BFD_ENDIAN_LITTLE;
>  
> -  aarch64_gdbarch_tdep *tdep = new aarch64_gdbarch_tdep;
> -  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new aarch64_gdbarch_tdep));
> +  aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
>  
>    /* This should be low enough for everything.  */
>    tdep->lowest_pc = 0x20;
> diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
> index 99e51b8afec..2691c9d0055 100644
> --- a/gdb/alpha-tdep.c
> +++ b/gdb/alpha-tdep.c
> @@ -1719,15 +1719,14 @@ alpha_software_single_step (struct regcache *regcache)
>  static struct gdbarch *
>  alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
> -
>    /* Find a candidate among extant architectures.  */
>    arches = gdbarch_list_lookup_by_info (arches, &info);
>    if (arches != NULL)
>      return arches->gdbarch;
>  
> -  alpha_gdbarch_tdep *tdep = new alpha_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new alpha_gdbarch_tdep));
> +  alpha_gdbarch_tdep *tdep = gdbarch_tdep<alpha_gdbarch_tdep> (gdbarch);
>  
>    /* Lowest text address.  This is used by heuristic_proc_start()
>       to decide when to stop looking.  */
> diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
> index 3ab0930bb29..a8c7bdab533 100644
> --- a/gdb/arc-tdep.c
> +++ b/gdb/arc-tdep.c
> @@ -2256,11 +2256,11 @@ arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    /* Allocate the ARC-private target-dependent information structure, and the
>       GDB target-independent information structure.  */
> -  std::unique_ptr<arc_gdbarch_tdep> tdep_holder (new arc_gdbarch_tdep);
> -  arc_gdbarch_tdep *tdep = tdep_holder.get ();
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new arc_gdbarch_tdep));
> +  arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_gdbarch_tdep> (gdbarch);
>    tdep->jb_pc = -1; /* No longjmp support by default.  */
>    tdep->has_hw_loops = arc_check_for_hw_loops (tdesc, tdesc_data.get ());
> -  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep_holder.release ());
>  
>    /* Data types.  */
>    set_gdbarch_short_bit (gdbarch, 16);
> diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
> index dbe78647d5e..6afad9ef445 100644
> --- a/gdb/arch-utils.c
> +++ b/gdb/arch-utils.c
> @@ -1195,7 +1195,7 @@ gdbarch_tdep_1 (struct gdbarch *gdbarch)
>  {
>    if (gdbarch_debug >= 2)
>      gdb_printf (gdb_stdlog, "gdbarch_tdep_1 called\n");
> -  return gdbarch->tdep;
> +  return gdbarch->tdep.get ();
>  }
>  
>  registry<gdbarch> *
> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
> index 6f02f04b5cb..4ce8f08d908 100644
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -9990,7 +9990,6 @@ arm_get_pc_address_flags (frame_info_ptr frame, CORE_ADDR pc)
>  static struct gdbarch *
>  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    struct gdbarch_list *best_arch;
>    enum arm_abi_kind arm_abi = arm_abi_global;
>    enum arm_float_model fp_model = arm_fp_model;
> @@ -10534,8 +10533,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>    if (best_arch != NULL)
>      return best_arch->gdbarch;
>  
> -  arm_gdbarch_tdep *tdep = new arm_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new arm_gdbarch_tdep));
> +  arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
>  
>    /* Record additional information about the architecture we are defining.
>       These are gdbarch discriminators, like the OSABI.  */
> diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
> index bac0b3f5008..80ab2750fa8 100644
> --- a/gdb/avr-tdep.c
> +++ b/gdb/avr-tdep.c
> @@ -1426,7 +1426,6 @@ avr_address_class_name_to_type_flags (struct gdbarch *gdbarch,
>  static struct gdbarch *
>  avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    struct gdbarch_list *best_arch;
>    int call_length;
>  
> @@ -1466,8 +1465,9 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      }
>  
>    /* None found, create a new architecture from the information provided.  */
> -  avr_gdbarch_tdep *tdep = new avr_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new avr_gdbarch_tdep));
> +  avr_gdbarch_tdep *tdep = gdbarch_tdep<avr_gdbarch_tdep> (gdbarch);
>    
>    tdep->call_length = call_length;
>  
> diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
> index f751e278211..0f2b0021bdf 100644
> --- a/gdb/bfin-tdep.c
> +++ b/gdb/bfin-tdep.c
> @@ -778,7 +778,6 @@ bfin_abi (struct gdbarch *gdbarch)
>  static struct gdbarch *
>  bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    enum bfin_abi abi;
>  
>    abi = BFIN_ABI_FLAT;
> @@ -798,8 +797,9 @@ bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>        return arches->gdbarch;
>      }
>  
> -  bfin_gdbarch_tdep *tdep = new bfin_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new bfin_gdbarch_tdep));
> +  bfin_gdbarch_tdep *tdep = gdbarch_tdep<bfin_gdbarch_tdep> (gdbarch);
>  
>    tdep->bfin_abi = abi;
>  
> diff --git a/gdb/bpf-tdep.c b/gdb/bpf-tdep.c
> index ea7c1147378..09d1545a4b8 100644
> --- a/gdb/bpf-tdep.c
> +++ b/gdb/bpf-tdep.c
> @@ -321,8 +321,8 @@ bpf_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      return arches->gdbarch;
>  
>    /* Allocate space for the new architecture.  */
> -  bpf_gdbarch_tdep *tdep = new bpf_gdbarch_tdep;
> -  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new bpf_gdbarch_tdep));
>  
>    /* Information about registers, etc.  */
>    set_gdbarch_num_regs (gdbarch, BPF_NUM_REGS);
> diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
> index d38850aa1af..55cef2606c2 100644
> --- a/gdb/cris-tdep.c
> +++ b/gdb/cris-tdep.c
> @@ -3912,7 +3912,6 @@ set_cris_dwarf2_cfi (const char *ignore_args, int from_tty,
>  static struct gdbarch *
>  cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    unsigned int cris_version;
>  
>    if (usr_cmd_cris_version_valid)
> @@ -3948,9 +3947,10 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      }
>  
>    /* No matching architecture was found.  Create a new one.  */
> -  cris_gdbarch_tdep *tdep = new cris_gdbarch_tdep;
>    info.byte_order = BFD_ENDIAN_LITTLE;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new cris_gdbarch_tdep));
> +  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
>  
>    tdep->cris_version = usr_cmd_cris_version;
>    tdep->cris_mode = usr_cmd_cris_mode;
> diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
> index f293d204da2..5b3536f86fe 100644
> --- a/gdb/csky-tdep.c
> +++ b/gdb/csky-tdep.c
> @@ -2671,7 +2671,6 @@ csky_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
>  static struct gdbarch *
>  csky_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    /* Analyze info.abfd.  */
>    unsigned int fpu_abi = 0;
>    unsigned int vdsp_version = 0;
> @@ -2761,8 +2760,10 @@ csky_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    /* None found, create a new architecture from the information
>       provided.  */
> -  csky_gdbarch_tdep *tdep = new csky_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new csky_gdbarch_tdep));
> +  csky_gdbarch_tdep *tdep = gdbarch_tdep<csky_gdbarch_tdep> (gdbarch);
> +
>    tdep->fpu_abi = fpu_abi;
>    tdep->vdsp_version = vdsp_version;
>    tdep->fpu_hardfp = fpu_hardfp;
> diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c
> index 056aad3f17e..eacfb6efb14 100644
> --- a/gdb/frv-tdep.c
> +++ b/gdb/frv-tdep.c
> @@ -89,6 +89,8 @@ struct frv_gdbarch_tdep : gdbarch_tdep_base
>    const char **register_names = nullptr;
>  };
>  
> +using frv_gdbarch_tdep_up = std::unique_ptr<frv_gdbarch_tdep>;
> +
>  /* Return the FR-V ABI associated with GDBARCH.  */
>  enum frv_abi
>  frv_abi (struct gdbarch *gdbarch)
> @@ -130,12 +132,12 @@ frv_fdpic_loadmap_addresses (struct gdbarch *gdbarch, CORE_ADDR *interp_addr,
>  
>  /* Allocate a new variant structure, and set up default values for all
>     the fields.  */
> -static frv_gdbarch_tdep *
> -new_variant (void)
> +static frv_gdbarch_tdep_up
> +new_variant ()
>  {
>    int r;
>  
> -  frv_gdbarch_tdep *var = new frv_gdbarch_tdep;
> +  frv_gdbarch_tdep_up var (new frv_gdbarch_tdep);
>  
>    var->frv_abi = FRV_ABI_EABI;
>    var->num_gprs = 64;
> @@ -1427,7 +1429,6 @@ static const struct frame_base frv_frame_base = {
>  static struct gdbarch *
>  frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int elf_flags = 0;
>  
>    /* Check to see if we've already built an appropriate architecture
> @@ -1437,7 +1438,9 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      return arches->gdbarch;
>  
>    /* Select the right tdep structure for this variant.  */
> -  frv_gdbarch_tdep *var = new_variant ();
> +  gdbarch *gdbarch = gdbarch_alloc (&info, new_variant ());
> +  frv_gdbarch_tdep *var = gdbarch_tdep<frv_gdbarch_tdep> (gdbarch);
> +
>    switch (info.bfd_arch_info->mach)
>      {
>      case bfd_mach_frv:
> @@ -1471,8 +1474,6 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>    if (elf_flags & EF_FRV_CPU_FR450)
>      set_variant_scratch_registers (var);
>  
> -  gdbarch = gdbarch_alloc (&info, var);
> -
>    set_gdbarch_short_bit (gdbarch, 16);
>    set_gdbarch_int_bit (gdbarch, 32);
>    set_gdbarch_long_bit (gdbarch, 32);
> diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c
> index 8da3dbae592..0be8a95f298 100644
> --- a/gdb/ft32-tdep.c
> +++ b/gdb/ft32-tdep.c
> @@ -558,7 +558,6 @@ static const struct frame_base ft32_frame_base =
>  static struct gdbarch *
>  ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    struct type *void_type;
>    struct type *func_void_type;
>  
> @@ -568,8 +567,9 @@ ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      return arches->gdbarch;
>  
>    /* Allocate space for the new architecture.  */
> -  ft32_gdbarch_tdep *tdep = new ft32_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new ft32_gdbarch_tdep));
> +  ft32_gdbarch_tdep *tdep = gdbarch_tdep<ft32_gdbarch_tdep> (gdbarch);
>  
>    /* Create a type for PC.  We can't use builtin types here, as they may not
>       be defined.  */
> diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
> index 74c12c5e3ff..e4ca74eb44b 100644
> --- a/gdb/gdbarch.c
> +++ b/gdb/gdbarch.c
> @@ -45,7 +45,7 @@ struct gdbarch
>    const struct target_desc * target_desc;
>  
>    /* target specific vector.  */
> -  struct gdbarch_tdep_base *tdep = nullptr;
> +  gdbarch_tdep_up tdep;
>    gdbarch_dump_tdep_ftype *dump_tdep = nullptr;
>  
>    /* per-architecture data-pointers.  */
> @@ -262,13 +262,13 @@ struct gdbarch
>  
>  struct gdbarch *
>  gdbarch_alloc (const struct gdbarch_info *info,
> -	       struct gdbarch_tdep_base *tdep)
> +	       gdbarch_tdep_up tdep)
>  {
>    struct gdbarch *gdbarch;
>  
>    gdbarch = new struct gdbarch;
>  
> -  gdbarch->tdep = tdep;
> +  gdbarch->tdep = std::move (tdep);
>  
>    gdbarch->bfd_arch_info = info->bfd_arch_info;
>    gdbarch->byte_order = info->byte_order;
> diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
> index aea6c4335d9..196c7981450 100644
> --- a/gdb/gdbarch.h
> +++ b/gdb/gdbarch.h
> @@ -69,6 +69,8 @@ struct gdbarch_tdep_base
>    virtual ~gdbarch_tdep_base() = default;
>  };
>  
> +using gdbarch_tdep_up = std::unique_ptr<gdbarch_tdep_base>;
> +
>  /* The architecture associated with the inferior through the
>     connection to the target.
>  
> @@ -294,7 +296,8 @@ extern struct gdbarch_list *gdbarch_list_lookup_by_info (struct gdbarch_list *ar
>     parameters.  set_gdbarch_*() functions are called to complete the
>     initialization of the object.  */
>  
> -extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, struct gdbarch_tdep_base *tdep);
> +extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info,
> +				      gdbarch_tdep_up tdep);
>  
>  
>  /* Helper function.  Free a partially-constructed ``struct gdbarch''.
> diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
> index fb4c4b42eab..da5f025d4d4 100644
> --- a/gdb/hppa-tdep.c
> +++ b/gdb/hppa-tdep.c
> @@ -2982,16 +2982,15 @@ hppa_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
>  static struct gdbarch *
>  hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
> -
>    /* find a candidate among the list of pre-declared architectures.  */
>    arches = gdbarch_list_lookup_by_info (arches, &info);
>    if (arches != NULL)
>      return (arches->gdbarch);
>  
>    /* If none found, then allocate and initialize one.  */
> -  hppa_gdbarch_tdep *tdep = new hppa_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new hppa_gdbarch_tdep));
> +  hppa_gdbarch_tdep *tdep = gdbarch_tdep<hppa_gdbarch_tdep> (gdbarch);
>  
>    /* Determine from the bfd_arch_info structure if we are dealing with
>       a 32 or 64 bits architecture.  If the bfd_arch_info is not available,
> diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
> index e027df2b9c5..ea7f5b3e2b7 100644
> --- a/gdb/i386-tdep.c
> +++ b/gdb/i386-tdep.c
> @@ -8443,7 +8443,6 @@ i386_type_align (struct gdbarch *gdbarch, struct type *type)
>  static struct gdbarch *
>  i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    const struct target_desc *tdesc;
>    int mm0_regnum;
>    int ymm0_regnum;
> @@ -8456,8 +8455,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      return arches->gdbarch;
>  
>    /* Allocate space for the new architecture.  Assume i386 for now.  */
> -  i386_gdbarch_tdep *tdep = new i386_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new i386_gdbarch_tdep));
> +  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
>  
>    /* General-purpose registers.  */
>    tdep->gregset_reg_offset = NULL;
> @@ -8700,7 +8700,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    if (!i386_validate_tdesc_p (tdep, tdesc_data.get ()))
>      {
> -      delete tdep;
>        gdbarch_free (gdbarch);
>        return NULL;
>      }
> diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
> index 519c956e169..35ae7ab8c46 100644
> --- a/gdb/ia64-tdep.c
> +++ b/gdb/ia64-tdep.c
> @@ -3918,15 +3918,14 @@ ia64_size_of_register_frame (frame_info_ptr this_frame, ULONGEST cfm)
>  static struct gdbarch *
>  ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
> -
>    /* If there is already a candidate, use it.  */
>    arches = gdbarch_list_lookup_by_info (arches, &info);
>    if (arches != NULL)
>      return arches->gdbarch;
>  
> -  ia64_gdbarch_tdep *tdep = new ia64_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new ia64_gdbarch_tdep));
> +  ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
>  
>    tdep->size_of_register_frame = ia64_size_of_register_frame;
>  
> diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
> index dd601320c3a..f534b626ffb 100644
> --- a/gdb/lm32-tdep.c
> +++ b/gdb/lm32-tdep.c
> @@ -479,16 +479,14 @@ lm32_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
>  static struct gdbarch *
>  lm32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
> -
>    /* If there is already a candidate, use it.  */
>    arches = gdbarch_list_lookup_by_info (arches, &info);
>    if (arches != NULL)
>      return arches->gdbarch;
>  
>    /* None found, create a new architecture from the information provided.  */
> -  lm32_gdbarch_tdep *tdep = new lm32_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new lm32_gdbarch_tdep));
>  
>    /* Type sizes.  */
>    set_gdbarch_short_bit (gdbarch, 16);
> diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c
> index d727bc85062..62630c34434 100644
> --- a/gdb/loongarch-tdep.c
> +++ b/gdb/loongarch-tdep.c
> @@ -1441,7 +1441,6 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>    size_t regnum = 0;
>    struct loongarch_gdbarch_features features;
>    tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
> -  loongarch_gdbarch_tdep *tdep = new loongarch_gdbarch_tdep;
>    const struct target_desc *tdesc = info.target_desc;
>  
>    /* Ensure we always have a target description.  */
> @@ -1531,7 +1530,10 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      return arches->gdbarch;
>  
>    /* None found, so create a new architecture from the information provided.  */
> -  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new loongarch_gdbarch_tdep));
> +  loongarch_gdbarch_tdep *tdep = gdbarch_tdep<loongarch_gdbarch_tdep> (gdbarch);
> +
>    tdep->abi_features = abi_features;
>  
>    /* Target data types.  */
> diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
> index f5101635aed..552eaccf440 100644
> --- a/gdb/m32c-tdep.c
> +++ b/gdb/m32c-tdep.c
> @@ -2587,7 +2587,6 @@ m32c_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc,
>  static struct gdbarch *
>  m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    unsigned long mach = info.bfd_arch_info->mach;
>  
>    /* Find a candidate among the list of architectures we've created
> @@ -2597,8 +2596,8 @@ m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>         arches = gdbarch_list_lookup_by_info (arches->next, &info))
>      return arches->gdbarch;
>  
> -  m32c_gdbarch_tdep *tdep = new m32c_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new m32c_gdbarch_tdep));
>  
>    /* Essential types.  */
>    make_types (gdbarch);
> diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
> index fc304757a60..d9e19654a6a 100644
> --- a/gdb/m32r-tdep.c
> +++ b/gdb/m32r-tdep.c
> @@ -861,16 +861,14 @@ static gdbarch_init_ftype m32r_gdbarch_init;
>  static struct gdbarch *
>  m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
> -
>    /* If there is already a candidate, use it.  */
>    arches = gdbarch_list_lookup_by_info (arches, &info);
>    if (arches != NULL)
>      return arches->gdbarch;
>  
>    /* Allocate space for the new architecture.  */
> -  m32r_gdbarch_tdep *tdep = new m32r_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new m32r_gdbarch_tdep));
>  
>    set_gdbarch_wchar_bit (gdbarch, 16);
>    set_gdbarch_wchar_signed (gdbarch, 0);
> diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
> index c48fe4424b6..e59e6638042 100644
> --- a/gdb/m68hc11-tdep.c
> +++ b/gdb/m68hc11-tdep.c
> @@ -1396,7 +1396,6 @@ static struct gdbarch *
>  m68hc11_gdbarch_init (struct gdbarch_info info,
>  		      struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int elf_flags;
>  
>    soft_reg_initialized = 0;
> @@ -1423,8 +1422,10 @@ m68hc11_gdbarch_init (struct gdbarch_info info,
>      }
>  
>    /* Need a new architecture.  Fill in a target specific vector.  */
> -  m68gc11_gdbarch_tdep *tdep = new m68gc11_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new m68gc11_gdbarch_tdep));
> +  m68gc11_gdbarch_tdep *tdep = gdbarch_tdep<m68gc11_gdbarch_tdep> (gdbarch);
> +
>    tdep->elf_flags = elf_flags;
>  
>    switch (info.bfd_arch_info->arch)
> diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c
> index c0a33118814..4556c80ff6a 100644
> --- a/gdb/m68k-tdep.c
> +++ b/gdb/m68k-tdep.c
> @@ -1131,7 +1131,6 @@ m68k_embedded_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>  static struct gdbarch *
>  m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    struct gdbarch_list *best_arch;
>    tdesc_arch_data_up tdesc_data;
>    int i;
> @@ -1248,8 +1247,10 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>    if (best_arch != NULL)
>      return best_arch->gdbarch;
>  
> -  m68k_gdbarch_tdep *tdep = new m68k_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new m68k_gdbarch_tdep));
> +  m68k_gdbarch_tdep *tdep = gdbarch_tdep<m68k_gdbarch_tdep> (gdbarch);
> +
>    tdep->fpregs_present = has_fp;
>    tdep->float_return = float_return;
>    tdep->flavour = flavour;
> diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
> index a6416085fe4..8b2d83b0c42 100644
> --- a/gdb/mep-tdep.c
> +++ b/gdb/mep-tdep.c
> @@ -2331,8 +2331,6 @@ mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
>  static struct gdbarch *
>  mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
> -
>    /* Which me_module are we building a gdbarch object for?  */
>    CONFIG_ATTR me_module;
>  
> @@ -2397,8 +2395,9 @@ mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  	return arches->gdbarch;
>      }
>  
> -  mep_gdbarch_tdep *tdep = new mep_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new mep_gdbarch_tdep));
> +  mep_gdbarch_tdep *tdep = gdbarch_tdep<mep_gdbarch_tdep> (gdbarch);
>  
>    /* Get a CGEN CPU descriptor for this architecture.  */
>    {
> diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
> index efa1daaa7fc..6c7f5fe71a3 100644
> --- a/gdb/microblaze-tdep.c
> +++ b/gdb/microblaze-tdep.c
> @@ -637,7 +637,6 @@ microblaze_register_g_packet_guesses (struct gdbarch *gdbarch)
>  static struct gdbarch *
>  microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    tdesc_arch_data_up tdesc_data;
>    const struct target_desc *tdesc = info.target_desc;
>  
> @@ -683,8 +682,8 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      }
>  
>    /* Allocate space for the new architecture.  */
> -  microblaze_gdbarch_tdep *tdep = new microblaze_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new microblaze_gdbarch_tdep));
>  
>    set_gdbarch_long_double_bit (gdbarch, 128);
>  
> diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
> index 8c1643585f4..e9432eb760f 100644
> --- a/gdb/mips-tdep.c
> +++ b/gdb/mips-tdep.c
> @@ -8075,7 +8075,6 @@ value_of_mips_user_reg (frame_info_ptr frame, const void *baton)
>  static struct gdbarch *
>  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int elf_flags;
>    enum mips_abi mips_abi, found_abi, wanted_abi;
>    int i, num_regs;
> @@ -8475,8 +8474,10 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      }
>  
>    /* Need a new architecture.  Fill in a target specific vector.  */
> -  mips_gdbarch_tdep *tdep = new mips_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new mips_gdbarch_tdep));
> +  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
> +
>    tdep->elf_flags = elf_flags;
>    tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p;
>    tdep->found_abi = found_abi;
> diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
> index 815949c67ae..b85845ded12 100644
> --- a/gdb/mn10300-tdep.c
> +++ b/gdb/mn10300-tdep.c
> @@ -1332,15 +1332,15 @@ static struct gdbarch *
>  mn10300_gdbarch_init (struct gdbarch_info info,
>  		      struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int num_regs;
>  
>    arches = gdbarch_list_lookup_by_info (arches, &info);
>    if (arches != NULL)
>      return arches->gdbarch;
>  
> -  mn10300_gdbarch_tdep *tdep = new mn10300_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new mn10300_gdbarch_tdep));
> +  mn10300_gdbarch_tdep *tdep = gdbarch_tdep<mn10300_gdbarch_tdep> (gdbarch);
>  
>    switch (info.bfd_arch_info->mach)
>      {
> diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c
> index f1841e4e57e..cd8d7d648bc 100644
> --- a/gdb/moxie-tdep.c
> +++ b/gdb/moxie-tdep.c
> @@ -1049,16 +1049,14 @@ moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
>  static struct gdbarch *
>  moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
> -
>    /* If there is already a candidate, use it.  */
>    arches = gdbarch_list_lookup_by_info (arches, &info);
>    if (arches != NULL)
>      return arches->gdbarch;
>  
>    /* Allocate space for the new architecture.  */
> -  moxie_gdbarch_tdep *tdep = new moxie_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new moxie_gdbarch_tdep));
>  
>    set_gdbarch_wchar_bit (gdbarch, 32);
>    set_gdbarch_wchar_signed (gdbarch, 0);
> diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
> index 54554247230..5efb081a450 100644
> --- a/gdb/msp430-tdep.c
> +++ b/gdb/msp430-tdep.c
> @@ -835,7 +835,6 @@ msp430_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
>  static struct gdbarch *
>  msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int elf_flags, isa, code_model;
>  
>    /* Extract the elf_flags if available.  */
> @@ -917,8 +916,10 @@ msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    /* None found, create a new architecture from the information
>       provided.  */
> -  msp430_gdbarch_tdep *tdep = new msp430_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new msp430_gdbarch_tdep));
> +  msp430_gdbarch_tdep *tdep = gdbarch_tdep<msp430_gdbarch_tdep> (gdbarch);
> +
>    tdep->elf_flags = elf_flags;
>    tdep->isa = isa;
>    tdep->code_model = code_model;
> diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
> index 4ab91e67f06..0ace593831f 100644
> --- a/gdb/nds32-tdep.c
> +++ b/gdb/nds32-tdep.c
> @@ -1940,7 +1940,6 @@ nds32_validate_tdesc_p (const struct target_desc *tdesc,
>  static struct gdbarch *
>  nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    struct gdbarch_list *best_arch;
>    tdesc_arch_data_up tdesc_data;
>    const struct target_desc *tdesc = info.target_desc;
> @@ -1981,14 +1980,15 @@ nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      return NULL;
>  
>    /* Allocate space for the new architecture.  */
> -  nds32_gdbarch_tdep *tdep = new nds32_gdbarch_tdep;
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new nds32_gdbarch_tdep));
> +  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_gdbarch_tdep> (gdbarch);
> +
>    tdep->fpu_freg = fpu_freg;
>    tdep->use_pseudo_fsrs = use_pseudo_fsrs;
>    tdep->fs0_regnum = -1;
>    tdep->elf_abi = elf_abi;
>  
> -  gdbarch = gdbarch_alloc (&info, tdep);
> -
>    set_gdbarch_wchar_bit (gdbarch, 16);
>    set_gdbarch_wchar_signed (gdbarch, 0);
>  
> diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c
> index effa10bf97e..4c8e86165da 100644
> --- a/gdb/nios2-tdep.c
> +++ b/gdb/nios2-tdep.c
> @@ -2274,7 +2274,6 @@ nios2_gcc_target_options (struct gdbarch *gdbarch)
>  static struct gdbarch *
>  nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int i;
>    tdesc_arch_data_up tdesc_data;
>    const struct target_desc *tdesc = info.target_desc;
> @@ -2312,8 +2311,9 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    /* None found, create a new architecture from the information
>       provided.  */
> -  nios2_gdbarch_tdep *tdep = new nios2_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new nios2_gdbarch_tdep));
> +  nios2_gdbarch_tdep *tdep = gdbarch_tdep<nios2_gdbarch_tdep> (gdbarch);
>  
>    /* longjmp support not enabled by default.  */
>    tdep->jb_pc = -1;
> diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c
> index efaf8745482..5394e7c2211 100644
> --- a/gdb/or1k-tdep.c
> +++ b/gdb/or1k-tdep.c
> @@ -1142,7 +1142,6 @@ static const struct frame_unwind or1k_frame_unwind = {
>  static struct gdbarch *
>  or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    const struct bfd_arch_info *binfo;
>    tdesc_arch_data_up tdesc_data;
>    const struct target_desc *tdesc = info.target_desc;
> @@ -1157,10 +1156,12 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>       actually know which target we are talking to, but put in some defaults
>       for now.  */
>    binfo = info.bfd_arch_info;
> -  or1k_gdbarch_tdep *tdep = new or1k_gdbarch_tdep;
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new or1k_gdbarch_tdep));
> +  or1k_gdbarch_tdep *tdep = gdbarch_tdep<or1k_gdbarch_tdep> (gdbarch);
> +
>    tdep->bytes_per_word = binfo->bits_per_word / binfo->bits_per_byte;
>    tdep->bytes_per_address = binfo->bits_per_address / binfo->bits_per_byte;
> -  gdbarch = gdbarch_alloc (&info, tdep);
>  
>    /* Target data types */
>    set_gdbarch_short_bit (gdbarch, 16);
> diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
> index 0a050b272ff..d5133493b63 100644
> --- a/gdb/riscv-tdep.c
> +++ b/gdb/riscv-tdep.c
> @@ -3783,7 +3783,6 @@ static struct gdbarch *
>  riscv_gdbarch_init (struct gdbarch_info info,
>  		    struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    struct riscv_gdbarch_features features;
>    const struct target_desc *tdesc = info.target_desc;
>  
> @@ -3869,8 +3868,10 @@ riscv_gdbarch_init (struct gdbarch_info info,
>      return arches->gdbarch;
>  
>    /* None found, so create a new architecture from the information provided.  */
> -  riscv_gdbarch_tdep *tdep = new riscv_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new riscv_gdbarch_tdep));
> +  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
> +
>    tdep->isa_features = features;
>    tdep->abi_features = abi_features;
>  
> diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c
> index 206b9e2794f..edabc7d8602 100644
> --- a/gdb/rl78-tdep.c
> +++ b/gdb/rl78-tdep.c
> @@ -1375,7 +1375,6 @@ rl78_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
>  static struct gdbarch *
>  rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int elf_flags;
>  
>    /* Extract the elf_flags if available.  */
> @@ -1403,8 +1402,10 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    /* None found, create a new architecture from the information
>       provided.  */
> -  rl78_gdbarch_tdep * tdep = new rl78_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new rl78_gdbarch_tdep));
> +  rl78_gdbarch_tdep *tdep = gdbarch_tdep<rl78_gdbarch_tdep> (gdbarch);
> +
>    tdep->elf_flags = elf_flags;
>  
>    /* Initialize types.  */
> diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
> index cbd84514795..52e4a5a7dd9 100644
> --- a/gdb/rs6000-tdep.c
> +++ b/gdb/rs6000-tdep.c
> @@ -7471,7 +7471,6 @@ rs6000_program_breakpoint_here_p (gdbarch *gdbarch, CORE_ADDR address)
>  static struct gdbarch *
>  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int wordsize, from_xcoff_exec, from_elf_exec;
>    enum bfd_architecture arch;
>    unsigned long mach;
> @@ -8179,15 +8178,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>         - "set arch"		trust blindly
>         - GDB startup		useless but harmless */
>  
> -  ppc_gdbarch_tdep *tdep = new ppc_gdbarch_tdep;
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new ppc_gdbarch_tdep));
> +  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
> +
>    tdep->wordsize = wordsize;
>    tdep->elf_abi = elf_abi;
>    tdep->soft_float = soft_float;
>    tdep->long_double_abi = long_double_abi;
>    tdep->vector_abi = vector_abi;
>  
> -  gdbarch = gdbarch_alloc (&info, tdep);
> -
>    tdep->ppc_gp0_regnum = PPC_R0_REGNUM;
>    tdep->ppc_toc_regnum = PPC_R0_REGNUM + 2;
>    tdep->ppc_ps_regnum = PPC_MSR_REGNUM;
> diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c
> index d1c294b9ef0..c588be1f4d7 100644
> --- a/gdb/rx-tdep.c
> +++ b/gdb/rx-tdep.c
> @@ -944,7 +944,6 @@ rx_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
>  static struct gdbarch *
>  rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int elf_flags;
>    tdesc_arch_data_up tdesc_data;
>    const struct target_desc *tdesc = info.target_desc;
> @@ -997,8 +996,10 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    gdb_assert(tdesc_data != NULL);
>  
> -  rx_gdbarch_tdep *tdep = new rx_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new rx_gdbarch_tdep));
> +  rx_gdbarch_tdep *tdep = gdbarch_tdep<rx_gdbarch_tdep> (gdbarch);
> +
>    tdep->elf_flags = elf_flags;
>  
>    set_gdbarch_num_regs (gdbarch, RX_NUM_REGS);
> diff --git a/gdb/s12z-tdep.c b/gdb/s12z-tdep.c
> index ccc47c99804..79b33f2f8a4 100644
> --- a/gdb/s12z-tdep.c
> +++ b/gdb/s12z-tdep.c
> @@ -616,8 +616,8 @@ show_bdccsr_command (const char *args, int from_tty)
>  static struct gdbarch *
>  s12z_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  s12z_gdbarch_tdep *tdep = new s12z_gdbarch_tdep;
> -  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new s12z_gdbarch_tdep));
>  
>    add_cmd ("bdccsr", class_support, show_bdccsr_command,
>  	   _("Show the current value of the microcontroller's BDCCSR."),
> diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
> index d0dba7654bb..83b8869a87e 100644
> --- a/gdb/s390-tdep.c
> +++ b/gdb/s390-tdep.c
> @@ -6983,13 +6983,12 @@ s390_tdesc_valid (s390_gdbarch_tdep *tdep,
>    return true;
>  }
>  
> -/* Allocate and initialize new gdbarch_tdep.  Caller is responsible to free
> -   memory after use.  */
> +/* Allocate and initialize new gdbarch_tdep.  */
>  
> -static s390_gdbarch_tdep *
> +static s390_gdbarch_tdep_up
>  s390_gdbarch_tdep_alloc ()
>  {
> -  s390_gdbarch_tdep *tdep = new s390_gdbarch_tdep;
> +  s390_gdbarch_tdep_up tdep (new s390_gdbarch_tdep);
>  
>    tdep->tdesc = NULL;
>  
> @@ -7026,8 +7025,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>    static const char *const stap_register_indirection_suffixes[] = { ")",
>  								    NULL };
>  
> -  s390_gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc ();
> -  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch = gdbarch_alloc (&info, s390_gdbarch_tdep_alloc ());
> +  s390_gdbarch_tdep *tdep = gdbarch_tdep<s390_gdbarch_tdep> (gdbarch);
>    tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
>    info.tdesc_data = tdesc_data.get ();
>  
> @@ -7156,7 +7155,6 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>    /* Check any target description for validity.  */
>    if (!s390_tdesc_valid (tdep, tdesc_data.get ()))
>      {
> -      delete tdep;
>        gdbarch_free (gdbarch);
>        return NULL;
>      }
> @@ -7189,7 +7187,6 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>        if (tmp->vector_abi != tdep->vector_abi)
>  	continue;
>  
> -      delete tdep;
>        gdbarch_free (gdbarch);
>        return arches->gdbarch;
>      }
> diff --git a/gdb/s390-tdep.h b/gdb/s390-tdep.h
> index f0f7019ac6a..e75ee48df9a 100644
> --- a/gdb/s390-tdep.h
> +++ b/gdb/s390-tdep.h
> @@ -67,6 +67,8 @@ struct s390_gdbarch_tdep : gdbarch_tdep_base
>      = nullptr;
>  };
>  
> +using s390_gdbarch_tdep_up = std::unique_ptr<s390_gdbarch_tdep>;
> +
>  /* Decoding S/390 instructions.  */
>  
>  /* Named opcode values for the S/390 instructions we recognize.  Some
> diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
> index a2e91483229..40c4bdda212 100644
> --- a/gdb/sh-tdep.c
> +++ b/gdb/sh-tdep.c
> @@ -2195,8 +2195,6 @@ sh_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
>  static struct gdbarch *
>  sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
> -
>    /* If there is already a candidate, use it.  */
>    arches = gdbarch_list_lookup_by_info (arches, &info);
>    if (arches != NULL)
> @@ -2204,8 +2202,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    /* None found, create a new architecture from the information
>       provided.  */
> -  sh_gdbarch_tdep *tdep = new sh_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new sh_gdbarch_tdep));
>  
>    set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
>    set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
> diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
> index 49c055e43cb..b003ebcb90a 100644
> --- a/gdb/sparc-tdep.c
> +++ b/gdb/sparc-tdep.c
> @@ -1807,7 +1807,6 @@ static struct gdbarch *
>  sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
>    const struct target_desc *tdesc = info.target_desc;
> -  struct gdbarch *gdbarch;
>    int valid_p = 1;
>  
>    /* If there is already a candidate, use it.  */
> @@ -1816,8 +1815,9 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      return arches->gdbarch;
>  
>    /* Allocate space for the new architecture.  */
> -  sparc_gdbarch_tdep *tdep = new sparc_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new sparc_gdbarch_tdep));
> +  sparc_gdbarch_tdep *tdep = gdbarch_tdep<sparc_gdbarch_tdep> (gdbarch);
>  
>    tdep->pc_regnum = SPARC32_PC_REGNUM;
>    tdep->npc_regnum = SPARC32_NPC_REGNUM;
> diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c
> index 054f0e6f3b2..b59fbcc2f03 100644
> --- a/gdb/tic6x-tdep.c
> +++ b/gdb/tic6x-tdep.c
> @@ -1136,7 +1136,6 @@ tic6x_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
>  static struct gdbarch *
>  tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    tdesc_arch_data_up tdesc_data;
>    const struct target_desc *tdesc = info.target_desc;
>    int has_gp = 0;
> @@ -1221,10 +1220,11 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  	return arches->gdbarch;
>      }
>  
> -  tic6x_gdbarch_tdep *tdep = new tic6x_gdbarch_tdep;
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new tic6x_gdbarch_tdep));
> +  tic6x_gdbarch_tdep *tdep = gdbarch_tdep<tic6x_gdbarch_tdep> (gdbarch);
>  
>    tdep->has_gp = has_gp;
> -  gdbarch = gdbarch_alloc (&info, tdep);
>  
>    /* Data type sizes.  */
>    set_gdbarch_ptr_bit (gdbarch, 32);
> diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c
> index a40e9abf077..d8406a5f14c 100644
> --- a/gdb/v850-tdep.c
> +++ b/gdb/v850-tdep.c
> @@ -1348,7 +1348,6 @@ static const struct frame_base v850_frame_base = {
>  static struct gdbarch *
>  v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    int e_flags, e_machine;
>  
>    /* Extract the elf_flags if available.  */
> @@ -1380,7 +1379,10 @@ v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>        return arches->gdbarch;
>      }
>  
> -  v850_gdbarch_tdep *tdep = new v850_gdbarch_tdep;
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new v850_gdbarch_tdep));
> +  v850_gdbarch_tdep *tdep = gdbarch_tdep<v850_gdbarch_tdep> (gdbarch);
> +
>    tdep->e_flags = e_flags;
>    tdep->e_machine = e_machine;
>  
> @@ -1395,7 +1397,6 @@ v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      }
>  
>    tdep->eight_byte_align = (tdep->e_flags & EF_RH850_DATA_ALIGN8) ? 1 : 0;
> -  gdbarch = gdbarch_alloc (&info, tdep);
>  
>    switch (info.bfd_arch_info->mach)
>      {
> diff --git a/gdb/xtensa-config.c b/gdb/xtensa-config.c
> index a28ffd58c96..37f893aa8f1 100644
> --- a/gdb/xtensa-config.c
> +++ b/gdb/xtensa-config.c
> @@ -62,7 +62,7 @@ const xtensa_mask_t xtensa_mask15 = { 1, xtensa_submask15 };
>  
>  
>  /* Register map.  */
> -static xtensa_register_t rmap[] =
> +xtensa_register_t xtensa_rmap[] =
>  {
>    /*    idx ofs bi sz al targno  flags cp typ group name  */
>    XTREG(  0,  0,32, 4, 4,0x0020,0x0006,-2, 9,0x0100,pc,          0,0,0,0,0,0)
> @@ -212,5 +212,3 @@ static xtensa_register_t rmap[] =
>  	    0,0,&xtensa_mask15,0,0,0)
>    XTREG_END
>  };
> -
> -xtensa_gdbarch_tdep xtensa_tdep (rmap);
> diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
> index 27634f5f4ce..78b328c50dc 100644
> --- a/gdb/xtensa-tdep.c
> +++ b/gdb/xtensa-tdep.c
> @@ -3145,13 +3145,11 @@ xtensa_derive_tdep (xtensa_gdbarch_tdep *tdep)
>  
>  /* Module "constructor" function.  */
>  
> -extern xtensa_gdbarch_tdep xtensa_tdep;
> +extern xtensa_register_t xtensa_rmap[];
>  
>  static struct gdbarch *
>  xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
> -
>    DEBUGTRACE ("gdbarch_init()\n");
>  
>    if (!xtensa_default_isa)
> @@ -3160,8 +3158,10 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>    /* We have to set the byte order before we call gdbarch_alloc.  */
>    info.byte_order = XCHAL_HAVE_BE ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
>  
> -  xtensa_gdbarch_tdep *tdep = &xtensa_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info,
> +		     gdbarch_tdep_up (new xtensa_gdbarch_tdep (xtensa_rmap)));
> +  xtensa_gdbarch_tdep *tdep = gdbarch_tdep<xtensa_gdbarch_tdep> (gdbarch);
>    xtensa_derive_tdep (tdep);
>  
>    /* Verify our configuration.  */
> diff --git a/gdb/z80-tdep.c b/gdb/z80-tdep.c
> index 3141feb4d80..84a37b2d78d 100644
> --- a/gdb/z80-tdep.c
> +++ b/gdb/z80-tdep.c
> @@ -1081,7 +1081,6 @@ z80_frame_unwind =
>  static struct gdbarch *
>  z80_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
> -  struct gdbarch *gdbarch;
>    struct gdbarch_list *best_arch;
>    tdesc_arch_data_up tdesc_data;
>    unsigned long mach = info.bfd_arch_info->mach;
> @@ -1123,8 +1122,9 @@ z80_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>      }
>  
>    /* None found, create a new architecture from the information provided.  */
> -  z80_gdbarch_tdep *tdep = new z80_gdbarch_tdep;
> -  gdbarch = gdbarch_alloc (&info, tdep);
> +  gdbarch *gdbarch
> +    = gdbarch_alloc (&info, gdbarch_tdep_up (new z80_gdbarch_tdep));
> +  z80_gdbarch_tdep *tdep = gdbarch_tdep<z80_gdbarch_tdep> (gdbarch);
>  
>    if (mach == bfd_mach_ez80_adl)
>      {
> -- 
> 2.38.1
  

Patch

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index cf20bb40b78..e59fcf726ae 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -3664,8 +3664,9 @@  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* AArch64 code is always little-endian.  */
   info.byte_order_for_code = BFD_ENDIAN_LITTLE;
 
-  aarch64_gdbarch_tdep *tdep = new aarch64_gdbarch_tdep;
-  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new aarch64_gdbarch_tdep));
+  aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
 
   /* This should be low enough for everything.  */
   tdep->lowest_pc = 0x20;
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 99e51b8afec..2691c9d0055 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -1719,15 +1719,14 @@  alpha_software_single_step (struct regcache *regcache)
 static struct gdbarch *
 alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-
   /* Find a candidate among extant architectures.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
   if (arches != NULL)
     return arches->gdbarch;
 
-  alpha_gdbarch_tdep *tdep = new alpha_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new alpha_gdbarch_tdep));
+  alpha_gdbarch_tdep *tdep = gdbarch_tdep<alpha_gdbarch_tdep> (gdbarch);
 
   /* Lowest text address.  This is used by heuristic_proc_start()
      to decide when to stop looking.  */
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index 3ab0930bb29..a8c7bdab533 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -2256,11 +2256,11 @@  arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Allocate the ARC-private target-dependent information structure, and the
      GDB target-independent information structure.  */
-  std::unique_ptr<arc_gdbarch_tdep> tdep_holder (new arc_gdbarch_tdep);
-  arc_gdbarch_tdep *tdep = tdep_holder.get ();
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new arc_gdbarch_tdep));
+  arc_gdbarch_tdep *tdep = gdbarch_tdep<arc_gdbarch_tdep> (gdbarch);
   tdep->jb_pc = -1; /* No longjmp support by default.  */
   tdep->has_hw_loops = arc_check_for_hw_loops (tdesc, tdesc_data.get ());
-  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep_holder.release ());
 
   /* Data types.  */
   set_gdbarch_short_bit (gdbarch, 16);
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index dbe78647d5e..6afad9ef445 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -1195,7 +1195,7 @@  gdbarch_tdep_1 (struct gdbarch *gdbarch)
 {
   if (gdbarch_debug >= 2)
     gdb_printf (gdb_stdlog, "gdbarch_tdep_1 called\n");
-  return gdbarch->tdep;
+  return gdbarch->tdep.get ();
 }
 
 registry<gdbarch> *
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 6f02f04b5cb..4ce8f08d908 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -9990,7 +9990,6 @@  arm_get_pc_address_flags (frame_info_ptr frame, CORE_ADDR pc)
 static struct gdbarch *
 arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   struct gdbarch_list *best_arch;
   enum arm_abi_kind arm_abi = arm_abi_global;
   enum arm_float_model fp_model = arm_fp_model;
@@ -10534,8 +10533,9 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (best_arch != NULL)
     return best_arch->gdbarch;
 
-  arm_gdbarch_tdep *tdep = new arm_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new arm_gdbarch_tdep));
+  arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
 
   /* Record additional information about the architecture we are defining.
      These are gdbarch discriminators, like the OSABI.  */
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index bac0b3f5008..80ab2750fa8 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -1426,7 +1426,6 @@  avr_address_class_name_to_type_flags (struct gdbarch *gdbarch,
 static struct gdbarch *
 avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   struct gdbarch_list *best_arch;
   int call_length;
 
@@ -1466,8 +1465,9 @@  avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* None found, create a new architecture from the information provided.  */
-  avr_gdbarch_tdep *tdep = new avr_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new avr_gdbarch_tdep));
+  avr_gdbarch_tdep *tdep = gdbarch_tdep<avr_gdbarch_tdep> (gdbarch);
   
   tdep->call_length = call_length;
 
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index f751e278211..0f2b0021bdf 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -778,7 +778,6 @@  bfin_abi (struct gdbarch *gdbarch)
 static struct gdbarch *
 bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   enum bfin_abi abi;
 
   abi = BFIN_ABI_FLAT;
@@ -798,8 +797,9 @@  bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       return arches->gdbarch;
     }
 
-  bfin_gdbarch_tdep *tdep = new bfin_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new bfin_gdbarch_tdep));
+  bfin_gdbarch_tdep *tdep = gdbarch_tdep<bfin_gdbarch_tdep> (gdbarch);
 
   tdep->bfin_abi = abi;
 
diff --git a/gdb/bpf-tdep.c b/gdb/bpf-tdep.c
index ea7c1147378..09d1545a4b8 100644
--- a/gdb/bpf-tdep.c
+++ b/gdb/bpf-tdep.c
@@ -321,8 +321,8 @@  bpf_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  */
-  bpf_gdbarch_tdep *tdep = new bpf_gdbarch_tdep;
-  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new bpf_gdbarch_tdep));
 
   /* Information about registers, etc.  */
   set_gdbarch_num_regs (gdbarch, BPF_NUM_REGS);
diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
index d38850aa1af..55cef2606c2 100644
--- a/gdb/cris-tdep.c
+++ b/gdb/cris-tdep.c
@@ -3912,7 +3912,6 @@  set_cris_dwarf2_cfi (const char *ignore_args, int from_tty,
 static struct gdbarch *
 cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   unsigned int cris_version;
 
   if (usr_cmd_cris_version_valid)
@@ -3948,9 +3947,10 @@  cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* No matching architecture was found.  Create a new one.  */
-  cris_gdbarch_tdep *tdep = new cris_gdbarch_tdep;
   info.byte_order = BFD_ENDIAN_LITTLE;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new cris_gdbarch_tdep));
+  cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
 
   tdep->cris_version = usr_cmd_cris_version;
   tdep->cris_mode = usr_cmd_cris_mode;
diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index f293d204da2..5b3536f86fe 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -2671,7 +2671,6 @@  csky_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 static struct gdbarch *
 csky_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   /* Analyze info.abfd.  */
   unsigned int fpu_abi = 0;
   unsigned int vdsp_version = 0;
@@ -2761,8 +2760,10 @@  csky_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* None found, create a new architecture from the information
      provided.  */
-  csky_gdbarch_tdep *tdep = new csky_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new csky_gdbarch_tdep));
+  csky_gdbarch_tdep *tdep = gdbarch_tdep<csky_gdbarch_tdep> (gdbarch);
+
   tdep->fpu_abi = fpu_abi;
   tdep->vdsp_version = vdsp_version;
   tdep->fpu_hardfp = fpu_hardfp;
diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c
index 056aad3f17e..eacfb6efb14 100644
--- a/gdb/frv-tdep.c
+++ b/gdb/frv-tdep.c
@@ -89,6 +89,8 @@  struct frv_gdbarch_tdep : gdbarch_tdep_base
   const char **register_names = nullptr;
 };
 
+using frv_gdbarch_tdep_up = std::unique_ptr<frv_gdbarch_tdep>;
+
 /* Return the FR-V ABI associated with GDBARCH.  */
 enum frv_abi
 frv_abi (struct gdbarch *gdbarch)
@@ -130,12 +132,12 @@  frv_fdpic_loadmap_addresses (struct gdbarch *gdbarch, CORE_ADDR *interp_addr,
 
 /* Allocate a new variant structure, and set up default values for all
    the fields.  */
-static frv_gdbarch_tdep *
-new_variant (void)
+static frv_gdbarch_tdep_up
+new_variant ()
 {
   int r;
 
-  frv_gdbarch_tdep *var = new frv_gdbarch_tdep;
+  frv_gdbarch_tdep_up var (new frv_gdbarch_tdep);
 
   var->frv_abi = FRV_ABI_EABI;
   var->num_gprs = 64;
@@ -1427,7 +1429,6 @@  static const struct frame_base frv_frame_base = {
 static struct gdbarch *
 frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int elf_flags = 0;
 
   /* Check to see if we've already built an appropriate architecture
@@ -1437,7 +1438,9 @@  frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return arches->gdbarch;
 
   /* Select the right tdep structure for this variant.  */
-  frv_gdbarch_tdep *var = new_variant ();
+  gdbarch *gdbarch = gdbarch_alloc (&info, new_variant ());
+  frv_gdbarch_tdep *var = gdbarch_tdep<frv_gdbarch_tdep> (gdbarch);
+
   switch (info.bfd_arch_info->mach)
     {
     case bfd_mach_frv:
@@ -1471,8 +1474,6 @@  frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (elf_flags & EF_FRV_CPU_FR450)
     set_variant_scratch_registers (var);
 
-  gdbarch = gdbarch_alloc (&info, var);
-
   set_gdbarch_short_bit (gdbarch, 16);
   set_gdbarch_int_bit (gdbarch, 32);
   set_gdbarch_long_bit (gdbarch, 32);
diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c
index 8da3dbae592..0be8a95f298 100644
--- a/gdb/ft32-tdep.c
+++ b/gdb/ft32-tdep.c
@@ -558,7 +558,6 @@  static const struct frame_base ft32_frame_base =
 static struct gdbarch *
 ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   struct type *void_type;
   struct type *func_void_type;
 
@@ -568,8 +567,9 @@  ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  */
-  ft32_gdbarch_tdep *tdep = new ft32_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new ft32_gdbarch_tdep));
+  ft32_gdbarch_tdep *tdep = gdbarch_tdep<ft32_gdbarch_tdep> (gdbarch);
 
   /* Create a type for PC.  We can't use builtin types here, as they may not
      be defined.  */
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 74c12c5e3ff..e4ca74eb44b 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -45,7 +45,7 @@  struct gdbarch
   const struct target_desc * target_desc;
 
   /* target specific vector.  */
-  struct gdbarch_tdep_base *tdep = nullptr;
+  gdbarch_tdep_up tdep;
   gdbarch_dump_tdep_ftype *dump_tdep = nullptr;
 
   /* per-architecture data-pointers.  */
@@ -262,13 +262,13 @@  struct gdbarch
 
 struct gdbarch *
 gdbarch_alloc (const struct gdbarch_info *info,
-	       struct gdbarch_tdep_base *tdep)
+	       gdbarch_tdep_up tdep)
 {
   struct gdbarch *gdbarch;
 
   gdbarch = new struct gdbarch;
 
-  gdbarch->tdep = tdep;
+  gdbarch->tdep = std::move (tdep);
 
   gdbarch->bfd_arch_info = info->bfd_arch_info;
   gdbarch->byte_order = info->byte_order;
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index aea6c4335d9..196c7981450 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -69,6 +69,8 @@  struct gdbarch_tdep_base
   virtual ~gdbarch_tdep_base() = default;
 };
 
+using gdbarch_tdep_up = std::unique_ptr<gdbarch_tdep_base>;
+
 /* The architecture associated with the inferior through the
    connection to the target.
 
@@ -294,7 +296,8 @@  extern struct gdbarch_list *gdbarch_list_lookup_by_info (struct gdbarch_list *ar
    parameters.  set_gdbarch_*() functions are called to complete the
    initialization of the object.  */
 
-extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, struct gdbarch_tdep_base *tdep);
+extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info,
+				      gdbarch_tdep_up tdep);
 
 
 /* Helper function.  Free a partially-constructed ``struct gdbarch''.
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index fb4c4b42eab..da5f025d4d4 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -2982,16 +2982,15 @@  hppa_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 static struct gdbarch *
 hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-
   /* find a candidate among the list of pre-declared architectures.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
   if (arches != NULL)
     return (arches->gdbarch);
 
   /* If none found, then allocate and initialize one.  */
-  hppa_gdbarch_tdep *tdep = new hppa_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new hppa_gdbarch_tdep));
+  hppa_gdbarch_tdep *tdep = gdbarch_tdep<hppa_gdbarch_tdep> (gdbarch);
 
   /* Determine from the bfd_arch_info structure if we are dealing with
      a 32 or 64 bits architecture.  If the bfd_arch_info is not available,
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index e027df2b9c5..ea7f5b3e2b7 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8443,7 +8443,6 @@  i386_type_align (struct gdbarch *gdbarch, struct type *type)
 static struct gdbarch *
 i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   const struct target_desc *tdesc;
   int mm0_regnum;
   int ymm0_regnum;
@@ -8456,8 +8455,9 @@  i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  Assume i386 for now.  */
-  i386_gdbarch_tdep *tdep = new i386_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new i386_gdbarch_tdep));
+  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
 
   /* General-purpose registers.  */
   tdep->gregset_reg_offset = NULL;
@@ -8700,7 +8700,6 @@  i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   if (!i386_validate_tdesc_p (tdep, tdesc_data.get ()))
     {
-      delete tdep;
       gdbarch_free (gdbarch);
       return NULL;
     }
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 519c956e169..35ae7ab8c46 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -3918,15 +3918,14 @@  ia64_size_of_register_frame (frame_info_ptr this_frame, ULONGEST cfm)
 static struct gdbarch *
 ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-
   /* If there is already a candidate, use it.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
   if (arches != NULL)
     return arches->gdbarch;
 
-  ia64_gdbarch_tdep *tdep = new ia64_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new ia64_gdbarch_tdep));
+  ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
 
   tdep->size_of_register_frame = ia64_size_of_register_frame;
 
diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
index dd601320c3a..f534b626ffb 100644
--- a/gdb/lm32-tdep.c
+++ b/gdb/lm32-tdep.c
@@ -479,16 +479,14 @@  lm32_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
 static struct gdbarch *
 lm32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-
   /* If there is already a candidate, use it.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
   if (arches != NULL)
     return arches->gdbarch;
 
   /* None found, create a new architecture from the information provided.  */
-  lm32_gdbarch_tdep *tdep = new lm32_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new lm32_gdbarch_tdep));
 
   /* Type sizes.  */
   set_gdbarch_short_bit (gdbarch, 16);
diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c
index d727bc85062..62630c34434 100644
--- a/gdb/loongarch-tdep.c
+++ b/gdb/loongarch-tdep.c
@@ -1441,7 +1441,6 @@  loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   size_t regnum = 0;
   struct loongarch_gdbarch_features features;
   tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
-  loongarch_gdbarch_tdep *tdep = new loongarch_gdbarch_tdep;
   const struct target_desc *tdesc = info.target_desc;
 
   /* Ensure we always have a target description.  */
@@ -1531,7 +1530,10 @@  loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return arches->gdbarch;
 
   /* None found, so create a new architecture from the information provided.  */
-  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new loongarch_gdbarch_tdep));
+  loongarch_gdbarch_tdep *tdep = gdbarch_tdep<loongarch_gdbarch_tdep> (gdbarch);
+
   tdep->abi_features = abi_features;
 
   /* Target data types.  */
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index f5101635aed..552eaccf440 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -2587,7 +2587,6 @@  m32c_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc,
 static struct gdbarch *
 m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   unsigned long mach = info.bfd_arch_info->mach;
 
   /* Find a candidate among the list of architectures we've created
@@ -2597,8 +2596,8 @@  m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        arches = gdbarch_list_lookup_by_info (arches->next, &info))
     return arches->gdbarch;
 
-  m32c_gdbarch_tdep *tdep = new m32c_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new m32c_gdbarch_tdep));
 
   /* Essential types.  */
   make_types (gdbarch);
diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
index fc304757a60..d9e19654a6a 100644
--- a/gdb/m32r-tdep.c
+++ b/gdb/m32r-tdep.c
@@ -861,16 +861,14 @@  static gdbarch_init_ftype m32r_gdbarch_init;
 static struct gdbarch *
 m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-
   /* If there is already a candidate, use it.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
   if (arches != NULL)
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  */
-  m32r_gdbarch_tdep *tdep = new m32r_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new m32r_gdbarch_tdep));
 
   set_gdbarch_wchar_bit (gdbarch, 16);
   set_gdbarch_wchar_signed (gdbarch, 0);
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index c48fe4424b6..e59e6638042 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -1396,7 +1396,6 @@  static struct gdbarch *
 m68hc11_gdbarch_init (struct gdbarch_info info,
 		      struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int elf_flags;
 
   soft_reg_initialized = 0;
@@ -1423,8 +1422,10 @@  m68hc11_gdbarch_init (struct gdbarch_info info,
     }
 
   /* Need a new architecture.  Fill in a target specific vector.  */
-  m68gc11_gdbarch_tdep *tdep = new m68gc11_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new m68gc11_gdbarch_tdep));
+  m68gc11_gdbarch_tdep *tdep = gdbarch_tdep<m68gc11_gdbarch_tdep> (gdbarch);
+
   tdep->elf_flags = elf_flags;
 
   switch (info.bfd_arch_info->arch)
diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c
index c0a33118814..4556c80ff6a 100644
--- a/gdb/m68k-tdep.c
+++ b/gdb/m68k-tdep.c
@@ -1131,7 +1131,6 @@  m68k_embedded_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 static struct gdbarch *
 m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   struct gdbarch_list *best_arch;
   tdesc_arch_data_up tdesc_data;
   int i;
@@ -1248,8 +1247,10 @@  m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (best_arch != NULL)
     return best_arch->gdbarch;
 
-  m68k_gdbarch_tdep *tdep = new m68k_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new m68k_gdbarch_tdep));
+  m68k_gdbarch_tdep *tdep = gdbarch_tdep<m68k_gdbarch_tdep> (gdbarch);
+
   tdep->fpregs_present = has_fp;
   tdep->float_return = float_return;
   tdep->flavour = flavour;
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index a6416085fe4..8b2d83b0c42 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -2331,8 +2331,6 @@  mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 static struct gdbarch *
 mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-
   /* Which me_module are we building a gdbarch object for?  */
   CONFIG_ATTR me_module;
 
@@ -2397,8 +2395,9 @@  mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	return arches->gdbarch;
     }
 
-  mep_gdbarch_tdep *tdep = new mep_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new mep_gdbarch_tdep));
+  mep_gdbarch_tdep *tdep = gdbarch_tdep<mep_gdbarch_tdep> (gdbarch);
 
   /* Get a CGEN CPU descriptor for this architecture.  */
   {
diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
index efa1daaa7fc..6c7f5fe71a3 100644
--- a/gdb/microblaze-tdep.c
+++ b/gdb/microblaze-tdep.c
@@ -637,7 +637,6 @@  microblaze_register_g_packet_guesses (struct gdbarch *gdbarch)
 static struct gdbarch *
 microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
 
@@ -683,8 +682,8 @@  microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* Allocate space for the new architecture.  */
-  microblaze_gdbarch_tdep *tdep = new microblaze_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new microblaze_gdbarch_tdep));
 
   set_gdbarch_long_double_bit (gdbarch, 128);
 
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 8c1643585f4..e9432eb760f 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -8075,7 +8075,6 @@  value_of_mips_user_reg (frame_info_ptr frame, const void *baton)
 static struct gdbarch *
 mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int elf_flags;
   enum mips_abi mips_abi, found_abi, wanted_abi;
   int i, num_regs;
@@ -8475,8 +8474,10 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* Need a new architecture.  Fill in a target specific vector.  */
-  mips_gdbarch_tdep *tdep = new mips_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new mips_gdbarch_tdep));
+  mips_gdbarch_tdep *tdep = gdbarch_tdep<mips_gdbarch_tdep> (gdbarch);
+
   tdep->elf_flags = elf_flags;
   tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p;
   tdep->found_abi = found_abi;
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 815949c67ae..b85845ded12 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -1332,15 +1332,15 @@  static struct gdbarch *
 mn10300_gdbarch_init (struct gdbarch_info info,
 		      struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int num_regs;
 
   arches = gdbarch_list_lookup_by_info (arches, &info);
   if (arches != NULL)
     return arches->gdbarch;
 
-  mn10300_gdbarch_tdep *tdep = new mn10300_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new mn10300_gdbarch_tdep));
+  mn10300_gdbarch_tdep *tdep = gdbarch_tdep<mn10300_gdbarch_tdep> (gdbarch);
 
   switch (info.bfd_arch_info->mach)
     {
diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c
index f1841e4e57e..cd8d7d648bc 100644
--- a/gdb/moxie-tdep.c
+++ b/gdb/moxie-tdep.c
@@ -1049,16 +1049,14 @@  moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
 static struct gdbarch *
 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-
   /* If there is already a candidate, use it.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
   if (arches != NULL)
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  */
-  moxie_gdbarch_tdep *tdep = new moxie_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new moxie_gdbarch_tdep));
 
   set_gdbarch_wchar_bit (gdbarch, 32);
   set_gdbarch_wchar_signed (gdbarch, 0);
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 54554247230..5efb081a450 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -835,7 +835,6 @@  msp430_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 static struct gdbarch *
 msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int elf_flags, isa, code_model;
 
   /* Extract the elf_flags if available.  */
@@ -917,8 +916,10 @@  msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* None found, create a new architecture from the information
      provided.  */
-  msp430_gdbarch_tdep *tdep = new msp430_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new msp430_gdbarch_tdep));
+  msp430_gdbarch_tdep *tdep = gdbarch_tdep<msp430_gdbarch_tdep> (gdbarch);
+
   tdep->elf_flags = elf_flags;
   tdep->isa = isa;
   tdep->code_model = code_model;
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index 4ab91e67f06..0ace593831f 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -1940,7 +1940,6 @@  nds32_validate_tdesc_p (const struct target_desc *tdesc,
 static struct gdbarch *
 nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   struct gdbarch_list *best_arch;
   tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
@@ -1981,14 +1980,15 @@  nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return NULL;
 
   /* Allocate space for the new architecture.  */
-  nds32_gdbarch_tdep *tdep = new nds32_gdbarch_tdep;
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new nds32_gdbarch_tdep));
+  nds32_gdbarch_tdep *tdep = gdbarch_tdep<nds32_gdbarch_tdep> (gdbarch);
+
   tdep->fpu_freg = fpu_freg;
   tdep->use_pseudo_fsrs = use_pseudo_fsrs;
   tdep->fs0_regnum = -1;
   tdep->elf_abi = elf_abi;
 
-  gdbarch = gdbarch_alloc (&info, tdep);
-
   set_gdbarch_wchar_bit (gdbarch, 16);
   set_gdbarch_wchar_signed (gdbarch, 0);
 
diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c
index effa10bf97e..4c8e86165da 100644
--- a/gdb/nios2-tdep.c
+++ b/gdb/nios2-tdep.c
@@ -2274,7 +2274,6 @@  nios2_gcc_target_options (struct gdbarch *gdbarch)
 static struct gdbarch *
 nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int i;
   tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
@@ -2312,8 +2311,9 @@  nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* None found, create a new architecture from the information
      provided.  */
-  nios2_gdbarch_tdep *tdep = new nios2_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new nios2_gdbarch_tdep));
+  nios2_gdbarch_tdep *tdep = gdbarch_tdep<nios2_gdbarch_tdep> (gdbarch);
 
   /* longjmp support not enabled by default.  */
   tdep->jb_pc = -1;
diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c
index efaf8745482..5394e7c2211 100644
--- a/gdb/or1k-tdep.c
+++ b/gdb/or1k-tdep.c
@@ -1142,7 +1142,6 @@  static const struct frame_unwind or1k_frame_unwind = {
 static struct gdbarch *
 or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   const struct bfd_arch_info *binfo;
   tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
@@ -1157,10 +1156,12 @@  or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      actually know which target we are talking to, but put in some defaults
      for now.  */
   binfo = info.bfd_arch_info;
-  or1k_gdbarch_tdep *tdep = new or1k_gdbarch_tdep;
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new or1k_gdbarch_tdep));
+  or1k_gdbarch_tdep *tdep = gdbarch_tdep<or1k_gdbarch_tdep> (gdbarch);
+
   tdep->bytes_per_word = binfo->bits_per_word / binfo->bits_per_byte;
   tdep->bytes_per_address = binfo->bits_per_address / binfo->bits_per_byte;
-  gdbarch = gdbarch_alloc (&info, tdep);
 
   /* Target data types */
   set_gdbarch_short_bit (gdbarch, 16);
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 0a050b272ff..d5133493b63 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -3783,7 +3783,6 @@  static struct gdbarch *
 riscv_gdbarch_init (struct gdbarch_info info,
 		    struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   struct riscv_gdbarch_features features;
   const struct target_desc *tdesc = info.target_desc;
 
@@ -3869,8 +3868,10 @@  riscv_gdbarch_init (struct gdbarch_info info,
     return arches->gdbarch;
 
   /* None found, so create a new architecture from the information provided.  */
-  riscv_gdbarch_tdep *tdep = new riscv_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new riscv_gdbarch_tdep));
+  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
+
   tdep->isa_features = features;
   tdep->abi_features = abi_features;
 
diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c
index 206b9e2794f..edabc7d8602 100644
--- a/gdb/rl78-tdep.c
+++ b/gdb/rl78-tdep.c
@@ -1375,7 +1375,6 @@  rl78_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 static struct gdbarch *
 rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int elf_flags;
 
   /* Extract the elf_flags if available.  */
@@ -1403,8 +1402,10 @@  rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* None found, create a new architecture from the information
      provided.  */
-  rl78_gdbarch_tdep * tdep = new rl78_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new rl78_gdbarch_tdep));
+  rl78_gdbarch_tdep *tdep = gdbarch_tdep<rl78_gdbarch_tdep> (gdbarch);
+
   tdep->elf_flags = elf_flags;
 
   /* Initialize types.  */
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index cbd84514795..52e4a5a7dd9 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -7471,7 +7471,6 @@  rs6000_program_breakpoint_here_p (gdbarch *gdbarch, CORE_ADDR address)
 static struct gdbarch *
 rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int wordsize, from_xcoff_exec, from_elf_exec;
   enum bfd_architecture arch;
   unsigned long mach;
@@ -8179,15 +8178,16 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        - "set arch"		trust blindly
        - GDB startup		useless but harmless */
 
-  ppc_gdbarch_tdep *tdep = new ppc_gdbarch_tdep;
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new ppc_gdbarch_tdep));
+  ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
+
   tdep->wordsize = wordsize;
   tdep->elf_abi = elf_abi;
   tdep->soft_float = soft_float;
   tdep->long_double_abi = long_double_abi;
   tdep->vector_abi = vector_abi;
 
-  gdbarch = gdbarch_alloc (&info, tdep);
-
   tdep->ppc_gp0_regnum = PPC_R0_REGNUM;
   tdep->ppc_toc_regnum = PPC_R0_REGNUM + 2;
   tdep->ppc_ps_regnum = PPC_MSR_REGNUM;
diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c
index d1c294b9ef0..c588be1f4d7 100644
--- a/gdb/rx-tdep.c
+++ b/gdb/rx-tdep.c
@@ -944,7 +944,6 @@  rx_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 static struct gdbarch *
 rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int elf_flags;
   tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
@@ -997,8 +996,10 @@  rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   gdb_assert(tdesc_data != NULL);
 
-  rx_gdbarch_tdep *tdep = new rx_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new rx_gdbarch_tdep));
+  rx_gdbarch_tdep *tdep = gdbarch_tdep<rx_gdbarch_tdep> (gdbarch);
+
   tdep->elf_flags = elf_flags;
 
   set_gdbarch_num_regs (gdbarch, RX_NUM_REGS);
diff --git a/gdb/s12z-tdep.c b/gdb/s12z-tdep.c
index ccc47c99804..79b33f2f8a4 100644
--- a/gdb/s12z-tdep.c
+++ b/gdb/s12z-tdep.c
@@ -616,8 +616,8 @@  show_bdccsr_command (const char *args, int from_tty)
 static struct gdbarch *
 s12z_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  s12z_gdbarch_tdep *tdep = new s12z_gdbarch_tdep;
-  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new s12z_gdbarch_tdep));
 
   add_cmd ("bdccsr", class_support, show_bdccsr_command,
 	   _("Show the current value of the microcontroller's BDCCSR."),
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index d0dba7654bb..83b8869a87e 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -6983,13 +6983,12 @@  s390_tdesc_valid (s390_gdbarch_tdep *tdep,
   return true;
 }
 
-/* Allocate and initialize new gdbarch_tdep.  Caller is responsible to free
-   memory after use.  */
+/* Allocate and initialize new gdbarch_tdep.  */
 
-static s390_gdbarch_tdep *
+static s390_gdbarch_tdep_up
 s390_gdbarch_tdep_alloc ()
 {
-  s390_gdbarch_tdep *tdep = new s390_gdbarch_tdep;
+  s390_gdbarch_tdep_up tdep (new s390_gdbarch_tdep);
 
   tdep->tdesc = NULL;
 
@@ -7026,8 +7025,8 @@  s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   static const char *const stap_register_indirection_suffixes[] = { ")",
 								    NULL };
 
-  s390_gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc ();
-  struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch = gdbarch_alloc (&info, s390_gdbarch_tdep_alloc ());
+  s390_gdbarch_tdep *tdep = gdbarch_tdep<s390_gdbarch_tdep> (gdbarch);
   tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
   info.tdesc_data = tdesc_data.get ();
 
@@ -7156,7 +7155,6 @@  s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Check any target description for validity.  */
   if (!s390_tdesc_valid (tdep, tdesc_data.get ()))
     {
-      delete tdep;
       gdbarch_free (gdbarch);
       return NULL;
     }
@@ -7189,7 +7187,6 @@  s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (tmp->vector_abi != tdep->vector_abi)
 	continue;
 
-      delete tdep;
       gdbarch_free (gdbarch);
       return arches->gdbarch;
     }
diff --git a/gdb/s390-tdep.h b/gdb/s390-tdep.h
index f0f7019ac6a..e75ee48df9a 100644
--- a/gdb/s390-tdep.h
+++ b/gdb/s390-tdep.h
@@ -67,6 +67,8 @@  struct s390_gdbarch_tdep : gdbarch_tdep_base
     = nullptr;
 };
 
+using s390_gdbarch_tdep_up = std::unique_ptr<s390_gdbarch_tdep>;
+
 /* Decoding S/390 instructions.  */
 
 /* Named opcode values for the S/390 instructions we recognize.  Some
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index a2e91483229..40c4bdda212 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -2195,8 +2195,6 @@  sh_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
 static struct gdbarch *
 sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-
   /* If there is already a candidate, use it.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
   if (arches != NULL)
@@ -2204,8 +2202,8 @@  sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* None found, create a new architecture from the information
      provided.  */
-  sh_gdbarch_tdep *tdep = new sh_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new sh_gdbarch_tdep));
 
   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
   set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 49c055e43cb..b003ebcb90a 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -1807,7 +1807,6 @@  static struct gdbarch *
 sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   const struct target_desc *tdesc = info.target_desc;
-  struct gdbarch *gdbarch;
   int valid_p = 1;
 
   /* If there is already a candidate, use it.  */
@@ -1816,8 +1815,9 @@  sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return arches->gdbarch;
 
   /* Allocate space for the new architecture.  */
-  sparc_gdbarch_tdep *tdep = new sparc_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new sparc_gdbarch_tdep));
+  sparc_gdbarch_tdep *tdep = gdbarch_tdep<sparc_gdbarch_tdep> (gdbarch);
 
   tdep->pc_regnum = SPARC32_PC_REGNUM;
   tdep->npc_regnum = SPARC32_NPC_REGNUM;
diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c
index 054f0e6f3b2..b59fbcc2f03 100644
--- a/gdb/tic6x-tdep.c
+++ b/gdb/tic6x-tdep.c
@@ -1136,7 +1136,6 @@  tic6x_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
 static struct gdbarch *
 tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
   int has_gp = 0;
@@ -1221,10 +1220,11 @@  tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	return arches->gdbarch;
     }
 
-  tic6x_gdbarch_tdep *tdep = new tic6x_gdbarch_tdep;
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new tic6x_gdbarch_tdep));
+  tic6x_gdbarch_tdep *tdep = gdbarch_tdep<tic6x_gdbarch_tdep> (gdbarch);
 
   tdep->has_gp = has_gp;
-  gdbarch = gdbarch_alloc (&info, tdep);
 
   /* Data type sizes.  */
   set_gdbarch_ptr_bit (gdbarch, 32);
diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c
index a40e9abf077..d8406a5f14c 100644
--- a/gdb/v850-tdep.c
+++ b/gdb/v850-tdep.c
@@ -1348,7 +1348,6 @@  static const struct frame_base v850_frame_base = {
 static struct gdbarch *
 v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   int e_flags, e_machine;
 
   /* Extract the elf_flags if available.  */
@@ -1380,7 +1379,10 @@  v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       return arches->gdbarch;
     }
 
-  v850_gdbarch_tdep *tdep = new v850_gdbarch_tdep;
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new v850_gdbarch_tdep));
+  v850_gdbarch_tdep *tdep = gdbarch_tdep<v850_gdbarch_tdep> (gdbarch);
+
   tdep->e_flags = e_flags;
   tdep->e_machine = e_machine;
 
@@ -1395,7 +1397,6 @@  v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   tdep->eight_byte_align = (tdep->e_flags & EF_RH850_DATA_ALIGN8) ? 1 : 0;
-  gdbarch = gdbarch_alloc (&info, tdep);
 
   switch (info.bfd_arch_info->mach)
     {
diff --git a/gdb/xtensa-config.c b/gdb/xtensa-config.c
index a28ffd58c96..37f893aa8f1 100644
--- a/gdb/xtensa-config.c
+++ b/gdb/xtensa-config.c
@@ -62,7 +62,7 @@  const xtensa_mask_t xtensa_mask15 = { 1, xtensa_submask15 };
 
 
 /* Register map.  */
-static xtensa_register_t rmap[] =
+xtensa_register_t xtensa_rmap[] =
 {
   /*    idx ofs bi sz al targno  flags cp typ group name  */
   XTREG(  0,  0,32, 4, 4,0x0020,0x0006,-2, 9,0x0100,pc,          0,0,0,0,0,0)
@@ -212,5 +212,3 @@  static xtensa_register_t rmap[] =
 	    0,0,&xtensa_mask15,0,0,0)
   XTREG_END
 };
-
-xtensa_gdbarch_tdep xtensa_tdep (rmap);
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 27634f5f4ce..78b328c50dc 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -3145,13 +3145,11 @@  xtensa_derive_tdep (xtensa_gdbarch_tdep *tdep)
 
 /* Module "constructor" function.  */
 
-extern xtensa_gdbarch_tdep xtensa_tdep;
+extern xtensa_register_t xtensa_rmap[];
 
 static struct gdbarch *
 xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
-
   DEBUGTRACE ("gdbarch_init()\n");
 
   if (!xtensa_default_isa)
@@ -3160,8 +3158,10 @@  xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* We have to set the byte order before we call gdbarch_alloc.  */
   info.byte_order = XCHAL_HAVE_BE ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
 
-  xtensa_gdbarch_tdep *tdep = &xtensa_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info,
+		     gdbarch_tdep_up (new xtensa_gdbarch_tdep (xtensa_rmap)));
+  xtensa_gdbarch_tdep *tdep = gdbarch_tdep<xtensa_gdbarch_tdep> (gdbarch);
   xtensa_derive_tdep (tdep);
 
   /* Verify our configuration.  */
diff --git a/gdb/z80-tdep.c b/gdb/z80-tdep.c
index 3141feb4d80..84a37b2d78d 100644
--- a/gdb/z80-tdep.c
+++ b/gdb/z80-tdep.c
@@ -1081,7 +1081,6 @@  z80_frame_unwind =
 static struct gdbarch *
 z80_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
-  struct gdbarch *gdbarch;
   struct gdbarch_list *best_arch;
   tdesc_arch_data_up tdesc_data;
   unsigned long mach = info.bfd_arch_info->mach;
@@ -1123,8 +1122,9 @@  z80_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* None found, create a new architecture from the information provided.  */
-  z80_gdbarch_tdep *tdep = new z80_gdbarch_tdep;
-  gdbarch = gdbarch_alloc (&info, tdep);
+  gdbarch *gdbarch
+    = gdbarch_alloc (&info, gdbarch_tdep_up (new z80_gdbarch_tdep));
+  z80_gdbarch_tdep *tdep = gdbarch_tdep<z80_gdbarch_tdep> (gdbarch);
 
   if (mach == bfd_mach_ez80_adl)
     {