Change management of tdesc_arch_data

Message ID 20200727193605.2224169-1-tromey@adacore.com
State New
Headers show
Series
  • Change management of tdesc_arch_data
Related show

Commit Message

Tom Tromey July 27, 2020, 7:36 p.m.
While working on something else, I noticed that tdesc_data_cleanup
took a void* parameter.  Looking more into this, I found that
tdesc_use_registers expected a transfer of ownership.

I think it's better to express this sort of thing via the type system,
when possible.  This patch changes tdesc_data_alloc to return a unique
pointer, changes tdesc_use_registers to accept an rvalue reference,
and then adapts all the users.

Note that a deleter structure is introduced to avoid having to move
tdesc_arch_data to the header file.

gdb/ChangeLog
2020-07-27  Tom Tromey  <tromey@adacore.com>

	* tic6x-tdep.c (tic6x_gdbarch_init): Update.
	* target-descriptions.h (struct tdesc_arch_data_deleter): New.
	(tdesc_arch_data_up): New typedef.
	(tdesc_use_registers, tdesc_data_alloc): Update.
	(tdesc_data_cleanup): Don't declare.
	* target-descriptions.c (tdesc_data_alloc): Return a
	tdesc_arch_data_up.
	(tdesc_arch_data_deleter::operator()): Rename from
	tdesc_data_cleanup.  Change argument type.
	(tdesc_use_registers): Change early_data to an rvalue reference.
	(tdesc_use_registers): Don't use delete.
	* sparc-tdep.c (sparc32_gdbarch_init): Update.
	* s390-tdep.c (s390_gdbarch_init): Update.
	* rx-tdep.c (rx_gdbarch_init): Update.
	* rs6000-tdep.c (rs6000_gdbarch_init): Update.
	* riscv-tdep.c (riscv_gdbarch_init): Update.
	* or1k-tdep.c (or1k_gdbarch_init): Update.
	* nios2-tdep.c (nios2_gdbarch_init): Update.
	* nds32-tdep.c (nds32_gdbarch_init): Update.
	* mips-tdep.c (mips_gdbarch_init): Update.
	* microblaze-tdep.c (microblaze_gdbarch_init): Update.
	* m68k-tdep.c (m68k_gdbarch_init): Update.
	* i386-tdep.c (i386_gdbarch_init): Update.
	* arm-tdep.c (arm_gdbarch_init): Update.
	* arc-tdep.c (arc_tdesc_init): Update.
	(arc_gdbarch_init): Update.
	* aarch64-tdep.c (aarch64_gdbarch_init): Update.
---
 gdb/ChangeLog             |  30 +++++++
 gdb/aarch64-tdep.c        |  19 ++--
 gdb/arc-tdep.c            |  18 ++--
 gdb/arm-tdep.c            |  61 +++++--------
 gdb/i386-tdep.c           |  10 +--
 gdb/m68k-tdep.c           |  26 ++----
 gdb/microblaze-tdep.c     |  15 ++--
 gdb/mips-tdep.c           |  74 ++++++---------
 gdb/nds32-tdep.c          |  14 ++-
 gdb/nios2-tdep.c          |  13 ++-
 gdb/or1k-tdep.c           |  11 +--
 gdb/riscv-tdep.c          |  19 ++--
 gdb/rs6000-tdep.c         | 184 +++++++++++++-------------------------
 gdb/rx-tdep.c             |  13 ++-
 gdb/s390-tdep.c           |  10 +--
 gdb/sparc-tdep.c          |  17 ++--
 gdb/target-descriptions.c |  11 +--
 gdb/target-descriptions.h |  22 +++--
 gdb/tic6x-tdep.c          |  40 ++++-----
 19 files changed, 248 insertions(+), 359 deletions(-)

-- 
2.26.2

Comments

Andrew Burgess July 28, 2020, 9:14 a.m. | #1
* Tom Tromey <tromey@adacore.com> [2020-07-27 13:36:05 -0600]:

> While working on something else, I noticed that tdesc_data_cleanup

> took a void* parameter.  Looking more into this, I found that

> tdesc_use_registers expected a transfer of ownership.

> 

> I think it's better to express this sort of thing via the type system,

> when possible.  This patch changes tdesc_data_alloc to return a unique

> pointer, changes tdesc_use_registers to accept an rvalue reference,

> and then adapts all the users.

> 

> Note that a deleter structure is introduced to avoid having to move

> tdesc_arch_data to the header file.

> 

> gdb/ChangeLog

> 2020-07-27  Tom Tromey  <tromey@adacore.com>

> 

> 	* tic6x-tdep.c (tic6x_gdbarch_init): Update.

> 	* target-descriptions.h (struct tdesc_arch_data_deleter): New.

> 	(tdesc_arch_data_up): New typedef.

> 	(tdesc_use_registers, tdesc_data_alloc): Update.

> 	(tdesc_data_cleanup): Don't declare.

> 	* target-descriptions.c (tdesc_data_alloc): Return a

> 	tdesc_arch_data_up.

> 	(tdesc_arch_data_deleter::operator()): Rename from

> 	tdesc_data_cleanup.  Change argument type.

> 	(tdesc_use_registers): Change early_data to an rvalue reference.

> 	(tdesc_use_registers): Don't use delete.

> 	* sparc-tdep.c (sparc32_gdbarch_init): Update.

> 	* s390-tdep.c (s390_gdbarch_init): Update.

> 	* rx-tdep.c (rx_gdbarch_init): Update.

> 	* rs6000-tdep.c (rs6000_gdbarch_init): Update.

> 	* riscv-tdep.c (riscv_gdbarch_init): Update.

> 	* or1k-tdep.c (or1k_gdbarch_init): Update.

> 	* nios2-tdep.c (nios2_gdbarch_init): Update.

> 	* nds32-tdep.c (nds32_gdbarch_init): Update.

> 	* mips-tdep.c (mips_gdbarch_init): Update.

> 	* microblaze-tdep.c (microblaze_gdbarch_init): Update.

> 	* m68k-tdep.c (m68k_gdbarch_init): Update.

> 	* i386-tdep.c (i386_gdbarch_init): Update.

> 	* arm-tdep.c (arm_gdbarch_init): Update.

> 	* arc-tdep.c (arc_tdesc_init): Update.

> 	(arc_gdbarch_init): Update.

> 	* aarch64-tdep.c (aarch64_gdbarch_init): Update.


LGTM.

Thanks,
Andrewx


> ---

>  gdb/ChangeLog             |  30 +++++++

>  gdb/aarch64-tdep.c        |  19 ++--

>  gdb/arc-tdep.c            |  18 ++--

>  gdb/arm-tdep.c            |  61 +++++--------

>  gdb/i386-tdep.c           |  10 +--

>  gdb/m68k-tdep.c           |  26 ++----

>  gdb/microblaze-tdep.c     |  15 ++--

>  gdb/mips-tdep.c           |  74 ++++++---------

>  gdb/nds32-tdep.c          |  14 ++-

>  gdb/nios2-tdep.c          |  13 ++-

>  gdb/or1k-tdep.c           |  11 +--

>  gdb/riscv-tdep.c          |  19 ++--

>  gdb/rs6000-tdep.c         | 184 +++++++++++++-------------------------

>  gdb/rx-tdep.c             |  13 ++-

>  gdb/s390-tdep.c           |  10 +--

>  gdb/sparc-tdep.c          |  17 ++--

>  gdb/target-descriptions.c |  11 +--

>  gdb/target-descriptions.h |  22 +++--

>  gdb/tic6x-tdep.c          |  40 ++++-----

>  19 files changed, 248 insertions(+), 359 deletions(-)

> 

> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c

> index 5e7d0d0b868..b2dfb0e6234 100644

> --- a/gdb/aarch64-tdep.c

> +++ b/gdb/aarch64-tdep.c

> @@ -3264,12 +3264,12 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    if (feature_core == nullptr)

>      return nullptr;

>  

> -  struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();

> +  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();

>  

>    /* Validate the description provides the mandatory core R registers

>       and allocate their numbers.  */

>    for (i = 0; i < ARRAY_SIZE (aarch64_r_register_names); i++)

> -    valid_p &= tdesc_numbered_register (feature_core, tdesc_data,

> +    valid_p &= tdesc_numbered_register (feature_core, tdesc_data.get (),

>  					AARCH64_X0_REGNUM + i,

>  					aarch64_r_register_names[i]);

>  

> @@ -3284,7 +3284,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        /* Validate the description provides the mandatory V registers

>  	 and allocate their numbers.  */

>        for (i = 0; i < ARRAY_SIZE (aarch64_v_register_names); i++)

> -	valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data,

> +	valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (),

>  					    AARCH64_V0_REGNUM + i,

>  					    aarch64_v_register_names[i]);

>  

> @@ -3297,7 +3297,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        /* Validate the description provides the mandatory SVE registers

>  	 and allocate their numbers.  */

>        for (i = 0; i < ARRAY_SIZE (aarch64_sve_register_names); i++)

> -	valid_p &= tdesc_numbered_register (feature_sve, tdesc_data,

> +	valid_p &= tdesc_numbered_register (feature_sve, tdesc_data.get (),

>  					    AARCH64_SVE_Z0_REGNUM + i,

>  					    aarch64_sve_register_names[i]);

>  

> @@ -3322,7 +3322,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        /* Validate the descriptor provides the mandatory PAUTH registers and

>  	 allocate their numbers.  */

>        for (i = 0; i < ARRAY_SIZE (aarch64_pauth_register_names); i++)

> -	valid_p &= tdesc_numbered_register (feature_pauth, tdesc_data,

> +	valid_p &= tdesc_numbered_register (feature_pauth, tdesc_data.get (),

>  					    first_pauth_regnum + i,

>  					    aarch64_pauth_register_names[i]);

>  

> @@ -3331,10 +3331,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>      }

>  

>    if (!valid_p)

> -    {

> -      tdesc_data_cleanup (tdesc_data);

> -      return nullptr;

> -    }

> +    return nullptr;

>  

>    /* AArch64 code is always little-endian.  */

>    info.byte_order_for_code = BFD_ENDIAN_LITTLE;

> @@ -3415,7 +3412,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>    /* Hook in the ABI-specific overrides, if they have been registered.  */

>    info.target_desc = tdesc;

> -  info.tdesc_data = tdesc_data;

> +  info.tdesc_data = tdesc_data.get ();

>    gdbarch_init_osabi (info, gdbarch);

>  

>    dwarf2_frame_set_init_reg (gdbarch, aarch64_dwarf2_frame_init_reg);

> @@ -3444,7 +3441,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>    set_gdbarch_get_pc_address_flags (gdbarch, aarch64_get_pc_address_flags);

>  

> -  tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>    /* Add standard register aliases.  */

>    for (i = 0; i < ARRAY_SIZE (aarch64_register_aliases); i++)

> diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c

> index 7e6d29c334b..3441eceb4bb 100644

> --- a/gdb/arc-tdep.c

> +++ b/gdb/arc-tdep.c

> @@ -1724,7 +1724,7 @@ static const struct frame_base arc_normal_base = {

>  

>  static bool

>  arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,

> -		struct tdesc_arch_data **tdesc_data)

> +		tdesc_arch_data_up *tdesc_data)

>  {

>    if (arc_debug)

>      debug_printf ("arc: Target description initialization.\n");

> @@ -1846,7 +1846,7 @@ arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,

>  	}

>      }

>  

> -  struct tdesc_arch_data *tdesc_data_loc = tdesc_data_alloc ();

> +  tdesc_arch_data_up tdesc_data_loc = tdesc_data_alloc ();

>  

>    gdb_assert (feature != NULL);

>    int valid_p = 1;

> @@ -1858,7 +1858,7 @@ arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,

>  			    || (i >= ARC_R16_REGNUM && i <= ARC_R25_REGNUM)))

>  	continue;

>  

> -      valid_p = tdesc_numbered_register (feature, tdesc_data_loc, i,

> +      valid_p = tdesc_numbered_register (feature, tdesc_data_loc.get (), i,

>  					 core_regs[i]);

>  

>        /* - Ignore errors in extension registers - they are optional.

> @@ -1875,7 +1875,6 @@ arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,

>  	{

>  	  arc_print (_("Error: Cannot find required register `%s' in "

>  		       "feature `%s'.\n"), core_regs[i], core_feature_name);

> -	  tdesc_data_cleanup (tdesc_data_loc);

>  	  return false;

>  	}

>      }

> @@ -1887,26 +1886,25 @@ arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,

>      {

>        arc_print (_("Error: Cannot find required feature `%s' in supplied "

>  		   "target description.\n"), aux_minimal_feature_name);

> -      tdesc_data_cleanup (tdesc_data_loc);

>        return false;

>      }

>  

>    for (int i = ARC_FIRST_AUX_REGNUM; i <= ARC_LAST_AUX_REGNUM; i++)

>      {

>        const char *name = aux_minimal_register_names[i - ARC_FIRST_AUX_REGNUM];

> -      valid_p = tdesc_numbered_register (feature, tdesc_data_loc, i, name);

> +      valid_p = tdesc_numbered_register (feature, tdesc_data_loc.get (),

> +					 i, name);

>        if (!valid_p)

>  	{

>  	  arc_print (_("Error: Cannot find required register `%s' "

>  		       "in feature `%s'.\n"),

>  		     name, tdesc_feature_name (feature));

> -	  tdesc_data_cleanup (tdesc_data_loc);

>  	  return false;

>  	}

>      }

>  

>    *tdesc = tdesc_loc;

> -  *tdesc_data = tdesc_data_loc;

> +  *tdesc_data = std::move (tdesc_data_loc);

>  

>    return true;

>  }

> @@ -1945,7 +1943,7 @@ static struct gdbarch *

>  arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  {

>    const struct target_desc *tdesc;

> -  struct tdesc_arch_data *tdesc_data;

> +  tdesc_arch_data_up tdesc_data;

>  

>    if (arc_debug)

>      debug_printf ("arc: Architecture initialization.\n");

> @@ -2096,7 +2094,7 @@ arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	}

>      }

>  

> -  tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>    return gdbarch;

>  }

> diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c

> index 9cedcc85755..d32f5a7291e 100644

> --- a/gdb/arm-tdep.c

> +++ b/gdb/arm-tdep.c

> @@ -8856,7 +8856,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    struct gdbarch_list *best_arch;

>    enum arm_abi_kind arm_abi = arm_abi_global;

>    enum arm_float_model fp_model = arm_fp_model;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    int i;

>    bool is_m = false;

>    int vfp_register_count = 0;

> @@ -9045,29 +9045,26 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>        valid_p = 1;

>        for (i = 0; i < ARM_SP_REGNUM; i++)

> -	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> +	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>  					    arm_register_names[i]);

> -      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),

>  						  ARM_SP_REGNUM,

>  						  arm_sp_names);

> -      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),

>  						  ARM_LR_REGNUM,

>  						  arm_lr_names);

> -      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),

>  						  ARM_PC_REGNUM,

>  						  arm_pc_names);

>        if (is_m)

> -	valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					    ARM_PS_REGNUM, "xpsr");

>        else

> -	valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					    ARM_PS_REGNUM, "cpsr");

>  

>        if (!valid_p)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>  

>        feature = tdesc_find_feature (tdesc,

>  				    "org.gnu.gdb.arm.fpa");

> @@ -9075,13 +9072,10 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	{

>  	  valid_p = 1;

>  	  for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>  						arm_register_names[i]);

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	}

>        else

>  	have_fpa_registers = false;

> @@ -9100,25 +9094,22 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	  valid_p = 1;

>  	  for (i = ARM_WR0_REGNUM; i <= ARM_WR15_REGNUM; i++)

>  	    valid_p

> -	      &= tdesc_numbered_register (feature, tdesc_data, i,

> +	      &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>  					  iwmmxt_names[i - ARM_WR0_REGNUM]);

>  

>  	  /* Check for the control registers, but do not fail if they

>  	     are missing.  */

>  	  for (i = ARM_WC0_REGNUM; i <= ARM_WCASF_REGNUM; i++)

> -	    tdesc_numbered_register (feature, tdesc_data, i,

> +	    tdesc_numbered_register (feature, tdesc_data.get (), i,

>  				     iwmmxt_names[i - ARM_WR0_REGNUM]);

>  

>  	  for (i = ARM_WCGR0_REGNUM; i <= ARM_WCGR3_REGNUM; i++)

>  	    valid_p

> -	      &= tdesc_numbered_register (feature, tdesc_data, i,

> +	      &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>  					  iwmmxt_names[i - ARM_WR0_REGNUM]);

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  

>  	  have_wmmx_registers = true;

>  	}

> @@ -9142,7 +9133,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	  valid_p = 1;

>  	  for (i = 0; i < 32; i++)

>  	    {

> -	      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						  ARM_D0_REGNUM + i,

>  						  vfp_double_names[i]);

>  	      if (!valid_p)

> @@ -9152,13 +9143,10 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	    valid_p = 1;

>  

>  	  /* Also require FPSCR.  */

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      ARM_FPSCR_REGNUM, "fpscr");

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  

>  	  if (tdesc_unnumbered_register (feature, "s0") == 0)

>  	    have_vfp_pseudos = true;

> @@ -9174,10 +9162,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	    {

>  	      /* NEON requires 32 double-precision registers.  */

>  	      if (i != 32)

> -		{

> -		  tdesc_data_cleanup (tdesc_data);

> -		  return NULL;

> -		}

> +		return NULL;

>  

>  	      /* If there are quad registers defined by the stub, use

>  		 their type; otherwise (normally) provide them with

> @@ -9217,11 +9202,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>      }

>  

>    if (best_arch != NULL)

> -    {

> -      if (tdesc_data != NULL)

> -	tdesc_data_cleanup (tdesc_data);

> -      return best_arch->gdbarch;

> -    }

> +    return best_arch->gdbarch;

>  

>    tdep = XCNEW (struct gdbarch_tdep);

>    gdbarch = gdbarch_alloc (&info, tdep);

> @@ -9423,11 +9404,11 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);

>      }

>  

> -  if (tdesc_data)

> +  if (tdesc_data != nullptr)

>      {

>        set_tdesc_pseudo_register_name (gdbarch, arm_register_name);

>  

> -      tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>        /* Override tdesc_register_type to adjust the types of VFP

>  	 registers for NEON.  */

> diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c

> index 9b905c1996a..6fb8dc4fdff 100644

> --- a/gdb/i386-tdep.c

> +++ b/gdb/i386-tdep.c

> @@ -8420,7 +8420,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  {

>    struct gdbarch_tdep *tdep;

>    struct gdbarch *gdbarch;

> -  struct tdesc_arch_data *tdesc_data;

>    const struct target_desc *tdesc;

>    int mm0_regnum;

>    int ymm0_regnum;

> @@ -8656,7 +8655,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    /* No segment base registers.  */

>    tdep->fsbase_regnum = -1;

>  

> -  tdesc_data = tdesc_data_alloc ();

> +  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();

>  

>    set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction);

>  

> @@ -8669,12 +8668,11 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    /* Hook in ABI-specific overrides, if they have been registered.

>       Note: If INFO specifies a 64 bit arch, this is where we turn

>       a 32-bit i386 into a 64-bit amd64.  */

> -  info.tdesc_data = tdesc_data;

> +  info.tdesc_data = tdesc_data.get ();

>    gdbarch_init_osabi (info, gdbarch);

>  

> -  if (!i386_validate_tdesc_p (tdep, tdesc_data))

> +  if (!i386_validate_tdesc_p (tdep, tdesc_data.get ()))

>      {

> -      tdesc_data_cleanup (tdesc_data);

>        xfree (tdep);

>        gdbarch_free (gdbarch);

>        return NULL;

> @@ -8696,7 +8694,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    /* Target description may be changed.  */

>    tdesc = tdep->tdesc;

>  

> -  tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>    /* Override gdbarch_register_reggroup_p set in tdesc_use_registers.  */

>    set_gdbarch_register_reggroup_p (gdbarch, tdep->register_reggroup_p);

> diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c

> index 27870252a36..c2ee3815882 100644

> --- a/gdb/m68k-tdep.c

> +++ b/gdb/m68k-tdep.c

> @@ -1075,7 +1075,7 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    struct gdbarch_tdep *tdep = NULL;

>    struct gdbarch *gdbarch;

>    struct gdbarch_list *best_arch;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    int i;

>    enum m68k_flavour flavour = m68k_no_flavour;

>    int has_fp = 1;

> @@ -1113,14 +1113,11 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>        valid_p = 1;

>        for (i = 0; i <= M68K_PC_REGNUM; i++)

> -	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> +	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>  					    m68k_register_names[i]);

>  

>        if (!valid_p)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>  

>        feature = tdesc_find_feature (info.target_desc,

>  				    "org.gnu.gdb.coldfire.fp");

> @@ -1128,13 +1125,10 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	{

>  	  valid_p = 1;

>  	  for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>  						m68k_register_names[i]);

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	}

>        else

>  	has_fp = 0;

> @@ -1170,11 +1164,7 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>      }

>  

>    if (best_arch != NULL)

> -    {

> -      if (tdesc_data != NULL)

> -	tdesc_data_cleanup (tdesc_data);

> -      return best_arch->gdbarch;

> -    }

> +    return best_arch->gdbarch;

>  

>    tdep = XCNEW (struct gdbarch_tdep);

>    gdbarch = gdbarch_alloc (&info, tdep);

> @@ -1265,8 +1255,8 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>    frame_unwind_append_unwinder (gdbarch, &m68k_frame_unwind);

>  

> -  if (tdesc_data)

> -    tdesc_use_registers (gdbarch, info.target_desc, tdesc_data);

> +  if (tdesc_data != nullptr)

> +    tdesc_use_registers (gdbarch, info.target_desc, std::move (tdesc_data));

>  

>    return gdbarch;

>  }

> diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c

> index 5c804133040..f3d0966cc08 100644

> --- a/gdb/microblaze-tdep.c

> +++ b/gdb/microblaze-tdep.c

> @@ -651,7 +651,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  {

>    struct gdbarch_tdep *tdep;

>    struct gdbarch *gdbarch;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    const struct target_desc *tdesc = info.target_desc;

>  

>    /* If there is already a candidate, use it.  */

> @@ -676,26 +676,23 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>        valid_p = 1;

>        for (i = 0; i < MICROBLAZE_NUM_CORE_REGS; i++)

> -        valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> +        valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>                                              microblaze_register_names[i]);

>        feature = tdesc_find_feature (tdesc,

>                                      "org.gnu.gdb.microblaze.stack-protect");

>        if (feature != NULL)

>          {

>            valid_p = 1;

> -          valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +          valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>                                                MICROBLAZE_SLR_REGNUM,

>                                                "rslr");

> -          valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +          valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>                                                MICROBLAZE_SHR_REGNUM,

>                                                "rshr");

>          }

>  

>        if (!valid_p)

> -        {

> -          tdesc_data_cleanup (tdesc_data);

> -          return NULL;

> -        }

> +	return NULL;

>      }

>  

>    /* Allocate space for the new architecture.  */

> @@ -748,7 +745,7 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    frame_unwind_append_unwinder (gdbarch, &microblaze_frame_unwind);

>    frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);

>    if (tdesc_data != NULL)

> -    tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>    return gdbarch;

>  }

> diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c

> index e0f04888808..e948cace212 100644

> --- a/gdb/mips-tdep.c

> +++ b/gdb/mips-tdep.c

> @@ -8047,7 +8047,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    enum mips_abi mips_abi, found_abi, wanted_abi;

>    int i, num_regs;

>    enum mips_fpu_type fpu_type;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    int elf_fpu_type = Val_GNU_MIPS_ABI_FP_ANY;

>    const char **reg_names;

>    struct mips_regnum mips_regnum, *regnum;

> @@ -8310,73 +8310,58 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>        valid_p = 1;

>        for (i = MIPS_ZERO_REGNUM; i <= MIPS_RA_REGNUM; i++)

> -	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> +	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>  					    mips_gprs[i]);

>  

>  

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					  mips_regnum.lo, "lo");

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					  mips_regnum.hi, "hi");

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					  mips_regnum.pc, "pc");

>  

>        if (!valid_p)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>  

>        feature = tdesc_find_feature (info.target_desc,

>  				    "org.gnu.gdb.mips.cp0");

>        if (feature == NULL)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>  

>        valid_p = 1;

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					  mips_regnum.badvaddr, "badvaddr");

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					  MIPS_PS_REGNUM, "status");

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					  mips_regnum.cause, "cause");

>  

>        if (!valid_p)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>  

>        /* FIXME drow/2007-05-17: The FPU should be optional.  The MIPS

>  	 backend is not prepared for that, though.  */

>        feature = tdesc_find_feature (info.target_desc,

>  				    "org.gnu.gdb.mips.fpu");

>        if (feature == NULL)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>  

>        valid_p = 1;

>        for (i = 0; i < 32; i++)

> -	valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					    i + mips_regnum.fp0, mips_fprs[i]);

>  

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					  mips_regnum.fp_control_status,

>  					  "fcsr");

>        valid_p

> -	&= tdesc_numbered_register (feature, tdesc_data,

> +	&= tdesc_numbered_register (feature, tdesc_data.get (),

>  				    mips_regnum.fp_implementation_revision,

>  				    "fir");

>  

>        if (!valid_p)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>  

>        num_regs = mips_regnum.fp_implementation_revision + 1;

>  

> @@ -8389,27 +8374,24 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	    {

>  	      i = 0;

>  	      valid_p = 1;

> -	      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						  dspacc + i++, "hi1");

> -	      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						  dspacc + i++, "lo1");

> -	      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						  dspacc + i++, "hi2");

> -	      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						  dspacc + i++, "lo2");

> -	      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						  dspacc + i++, "hi3");

> -	      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						  dspacc + i++, "lo3");

>  

> -	      valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						  dspctl, "dspctl");

>  

>  	      if (!valid_p)

> -		{

> -		  tdesc_data_cleanup (tdesc_data);

> -		  return NULL;

> -		}

> +		return NULL;

>  

>  	      mips_regnum.dspacc = dspacc;

>  	      mips_regnum.dspctl = dspctl;

> @@ -8445,8 +8427,6 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        if (MIPS_FPU_TYPE (arches->gdbarch) != fpu_type)

>  	continue;

>  

> -      if (tdesc_data != NULL)

> -	tdesc_data_cleanup (tdesc_data);

>        return arches->gdbarch;

>      }

>  

> @@ -8743,7 +8723,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    mips_register_g_packet_guesses (gdbarch);

>  

>    /* Hook in OS ABI-specific overrides, if they have been registered.  */

> -  info.tdesc_data = tdesc_data;

> +  info.tdesc_data = tdesc_data.get ();

>    gdbarch_init_osabi (info, gdbarch);

>  

>    /* The hook may have adjusted num_regs, fetch the final value and

> @@ -8764,10 +8744,10 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    frame_base_append_sniffer (gdbarch, mips_micro_frame_base_sniffer);

>    frame_base_append_sniffer (gdbarch, mips_insn32_frame_base_sniffer);

>  

> -  if (tdesc_data)

> +  if (tdesc_data != nullptr)

>      {

>        set_tdesc_pseudo_register_type (gdbarch, mips_pseudo_register_type);

> -      tdesc_use_registers (gdbarch, info.target_desc, tdesc_data);

> +      tdesc_use_registers (gdbarch, info.target_desc, std::move (tdesc_data));

>  

>        /* Override the normal target description methods to handle our

>  	 dual real and pseudo registers.  */

> diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c

> index 94ac234d3fb..4305292522e 100644

> --- a/gdb/nds32-tdep.c

> +++ b/gdb/nds32-tdep.c

> @@ -1955,7 +1955,7 @@ nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    struct gdbarch *gdbarch;

>    struct gdbarch_tdep *tdep;

>    struct gdbarch_list *best_arch;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    const struct target_desc *tdesc = info.target_desc;

>    int elf_abi = E_NDS_ABI_AABI;

>    int fpu_freg = -1;

> @@ -1988,11 +1988,9 @@ nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>    tdesc_data = tdesc_data_alloc ();

>  

> -  if (!nds32_validate_tdesc_p (tdesc, tdesc_data, &fpu_freg, &use_pseudo_fsrs))

> -    {

> -      tdesc_data_cleanup (tdesc_data);

> -      return NULL;

> -    }

> +  if (!nds32_validate_tdesc_p (tdesc, tdesc_data.get (), &fpu_freg,

> +			       &use_pseudo_fsrs))

> +    return NULL;

>  

>    /* Allocate space for the new architecture.  */

>    tdep = XCNEW (struct gdbarch_tdep);

> @@ -2022,7 +2020,7 @@ nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>      num_regs = NDS32_NUM_REGS + num_fdr_map[fpu_freg] + num_fsr_map[fpu_freg];

>  

>    set_gdbarch_num_regs (gdbarch, num_regs);

> -  tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>    /* Cache the register number of fs0.  */

>    if (fpu_freg != -1)

> @@ -2061,7 +2059,7 @@ nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    nds32_add_reggroups (gdbarch);

>  

>    /* Hook in ABI-specific overrides, if they have been registered.  */

> -  info.tdesc_data = tdesc_data;

> +  info.tdesc_data = tdesc_data.get ();

>    gdbarch_init_osabi (info, gdbarch);

>  

>    /* Override tdesc_register callbacks for system registers.  */

> diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c

> index acc28735035..09eb6fcb5dd 100644

> --- a/gdb/nios2-tdep.c

> +++ b/gdb/nios2-tdep.c

> @@ -2275,7 +2275,7 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    struct gdbarch *gdbarch;

>    struct gdbarch_tdep *tdep;

>    int i;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    const struct target_desc *tdesc = info.target_desc;

>  

>    if (!tdesc_has_registers (tdesc))

> @@ -2297,14 +2297,11 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        valid_p = 1;

>        

>        for (i = 0; i < NIOS2_NUM_REGS; i++)

> -	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> +	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>  					    nios2_reg_names[i]);

>  

>        if (!valid_p)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>      }

>  

>    /* Find a candidate among the list of pre-declared architectures.  */

> @@ -2384,8 +2381,8 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    /* Enable inferior call support.  */

>    set_gdbarch_push_dummy_call (gdbarch, nios2_push_dummy_call);

>  

> -  if (tdesc_data)

> -    tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +  if (tdesc_data != nullptr)

> +    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>    return gdbarch;

>  }

> diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c

> index 75df206a2bd..fd067a9c782 100644

> --- a/gdb/or1k-tdep.c

> +++ b/gdb/or1k-tdep.c

> @@ -1113,7 +1113,7 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    struct gdbarch *gdbarch;

>    struct gdbarch_tdep *tdep;

>    const struct bfd_arch_info *binfo;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    const struct target_desc *tdesc = info.target_desc;

>  

>    /* Find a candidate among the list of pre-declared architectures.  */

> @@ -1221,14 +1221,11 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        valid_p = 1;

>  

>        for (i = 0; i < OR1K_NUM_REGS; i++)

> -        valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> +        valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>                                              or1k_reg_names[i]);

>  

>        if (!valid_p)

> -        {

> -          tdesc_data_cleanup (tdesc_data);

> -          return NULL;

> -        }

> +	return NULL;

>      }

>  

>    if (tdesc_data != NULL)

> @@ -1243,7 +1240,7 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        reggroup_add (gdbarch, save_reggroup);

>        reggroup_add (gdbarch, restore_reggroup);

>  

> -      tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>      }

>  

>    /* Hook in ABI-specific overrides, if they have been registered.  */

> diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c

> index b86ba630540..46ce3674d31 100644

> --- a/gdb/riscv-tdep.c

> +++ b/gdb/riscv-tdep.c

> @@ -3320,10 +3320,10 @@ riscv_gdbarch_init (struct gdbarch_info info,

>    if (feature_cpu == NULL)

>      return NULL;

>  

> -  struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();

> +  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();

>    std::vector<riscv_pending_register_alias> pending_aliases;

>  

> -  bool valid_p = riscv_check_tdesc_feature (tdesc_data,

> +  bool valid_p = riscv_check_tdesc_feature (tdesc_data.get (),

>                                              feature_cpu, feature_csr,

>                                              &riscv_xreg_feature,

>                                              &pending_aliases);

> @@ -3345,7 +3345,7 @@ riscv_gdbarch_init (struct gdbarch_info info,

>  

>    if (feature_fpu != NULL)

>      {

> -      valid_p &= riscv_check_tdesc_feature (tdesc_data, feature_fpu,

> +      valid_p &= riscv_check_tdesc_feature (tdesc_data.get (), feature_fpu,

>  					    feature_csr,

>                                              &riscv_freg_feature,

>                                              &pending_aliases);

> @@ -3383,12 +3383,12 @@ riscv_gdbarch_init (struct gdbarch_info info,

>      }

>  

>    if (feature_virtual)

> -    riscv_check_tdesc_feature (tdesc_data, feature_virtual, feature_csr,

> +    riscv_check_tdesc_feature (tdesc_data.get (), feature_virtual, feature_csr,

>                                 &riscv_virtual_feature,

>                                 &pending_aliases);

>  

>    if (feature_csr)

> -    riscv_check_tdesc_feature (tdesc_data, feature_csr, nullptr,

> +    riscv_check_tdesc_feature (tdesc_data.get (), feature_csr, nullptr,

>                                 &riscv_csr_feature,

>                                 &pending_aliases);

>  

> @@ -3396,7 +3396,6 @@ riscv_gdbarch_init (struct gdbarch_info info,

>      {

>        if (riscv_debug_gdbarch)

>          fprintf_unfiltered (gdb_stdlog, "Target description is not valid\n");

> -      tdesc_data_cleanup (tdesc_data);

>        return NULL;

>      }

>  

> @@ -3442,10 +3441,7 @@ riscv_gdbarch_init (struct gdbarch_info info,

>      }

>  

>    if (arches != NULL)

> -    {

> -      tdesc_data_cleanup (tdesc_data);

> -      return arches->gdbarch;

> -    }

> +    return arches->gdbarch;

>  

>    /* None found, so create a new architecture from the information provided.  */

>    tdep = new (struct gdbarch_tdep);

> @@ -3511,7 +3507,8 @@ riscv_gdbarch_init (struct gdbarch_info info,

>    set_gdbarch_print_registers_info (gdbarch, riscv_print_registers_info);

>  

>    /* Finalise the target description registers.  */

> -  tdesc_use_registers (gdbarch, tdesc, tdesc_data, riscv_tdesc_unknown_reg);

> +  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data),

> +		       riscv_tdesc_unknown_reg);

>  

>    /* Override the register type callback setup by the target description

>       mechanism.  This allows us to provide special type for floating point

> diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c

> index 84278e708e7..82d4b205796 100644

> --- a/gdb/rs6000-tdep.c

> +++ b/gdb/rs6000-tdep.c

> @@ -6138,7 +6138,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    int have_htm_tar = 0;

>    int tdesc_wordsize = -1;

>    const struct target_desc *tdesc = info.target_desc;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    int num_pseudoregs = 0;

>    int cur_reg;

>  

> @@ -6235,31 +6235,29 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>        valid_p = 1;

>        for (i = 0; i < ppc_num_gprs; i++)

> -	valid_p &= tdesc_numbered_register (feature, tdesc_data, i, gprs[i]);

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_PC_REGNUM,

> -					  "pc");

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_LR_REGNUM,

> -					  "lr");

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_XER_REGNUM,

> -					  "xer");

> +	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

> +					    i, gprs[i]);

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

> +					  PPC_PC_REGNUM, "pc");

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

> +					  PPC_LR_REGNUM, "lr");

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

> +					  PPC_XER_REGNUM, "xer");

>  

>        /* Allow alternate names for these registers, to accomodate GDB's

>  	 historic naming.  */

> -      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),

>  						  PPC_MSR_REGNUM, msr_names);

> -      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),

>  						  PPC_CR_REGNUM, cr_names);

> -      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,

> +      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),

>  						  PPC_CTR_REGNUM, ctr_names);

>  

>        if (!valid_p)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>  

> -      have_mq = tdesc_numbered_register (feature, tdesc_data, PPC_MQ_REGNUM,

> -					 "mq");

> +      have_mq = tdesc_numbered_register (feature, tdesc_data.get (),

> +					 PPC_MQ_REGNUM, "mq");

>  

>        tdesc_wordsize = tdesc_register_bitsize (feature, "pc") / 8;

>        if (wordsize == -1)

> @@ -6277,16 +6275,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	  };

>  	  valid_p = 1;

>  	  for (i = 0; i < ppc_num_fprs; i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						PPC_F0_REGNUM + i, fprs[i]);

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_FPSCR_REGNUM, "fpscr");

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_fpu = 1;

>  

>  	  /* The fpscr register was expanded in isa 2.05 to 64 bits

> @@ -6311,19 +6306,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>  	  valid_p = 1;

>  	  for (i = 0; i < ppc_num_gprs; i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						PPC_VR0_REGNUM + i,

>  						vector_regs[i]);

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_VSCR_REGNUM, "vscr");

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_VRSAVE_REGNUM, "vrsave");

>  

>  	  if (have_spe || !valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_altivec = 1;

>  	}

>        else

> @@ -6347,15 +6339,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	  valid_p = 1;

>  

>  	  for (i = 0; i < ppc_num_vshrs; i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						PPC_VSR0_UPPER_REGNUM + i,

>  						vsx_regs[i]);

>  

>  	  if (!valid_p || !have_fpu || !have_altivec)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  

>  	  have_vsx = 1;

>  	}

> @@ -6392,19 +6381,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>  	  valid_p = 1;

>  	  for (i = 0; i < ppc_num_gprs; i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						PPC_SPE_UPPER_GP0_REGNUM + i,

>  						upper_spe[i]);

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_SPE_ACC_REGNUM, "acc");

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_SPE_FSCR_REGNUM, "spefscr");

>  

>  	  if (have_mq || have_fpu || !valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_spe = 1;

>  	}

>        else

> @@ -6416,14 +6402,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        if (feature != NULL)

>  	{

>  	  valid_p = 1;

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_PPR_REGNUM, "ppr");

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_ppr = 1;

>  	}

>        else

> @@ -6435,14 +6418,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        if (feature != NULL)

>  	{

>  	  valid_p = 1;

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_DSCR_REGNUM, "dscr");

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_dscr = 1;

>  	}

>        else

> @@ -6454,14 +6434,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        if (feature != NULL)

>  	{

>  	  valid_p = 1;

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_TAR_REGNUM, "tar");

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_tar = 1;

>  	}

>        else

> @@ -6478,14 +6455,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>  	  valid_p = 1;

>  	  for (i = 0; i < ARRAY_SIZE (ebb_regs); i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						PPC_BESCR_REGNUM + i,

>  						ebb_regs[i]);

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_ebb = 1;

>  	}

>        else

> @@ -6499,27 +6473,24 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	{

>  	  valid_p = 1;

>  

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_MMCR0_REGNUM,

>  					      "mmcr0");

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_MMCR2_REGNUM,

>  					      "mmcr2");

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_SIAR_REGNUM,

>  					      "siar");

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_SDAR_REGNUM,

>  					      "sdar");

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  					      PPC_SIER_REGNUM,

>  					      "sier");

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_pmu = 1;

>  	}

>        else

> @@ -6536,14 +6507,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>  	  valid_p = 1;

>  	  for (i = 0; i < ARRAY_SIZE (tm_spr_regs); i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						PPC_TFHAR_REGNUM + i,

>  						tm_spr_regs[i]);

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  

>  	  have_htm_spr = 1;

>  	}

> @@ -6565,14 +6533,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	  valid_p = 1;

>  

>  	  for (i = 0; i < ARRAY_SIZE (cgprs); i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						PPC_CR0_REGNUM + i,

>  						cgprs[i]);

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  

>  	  have_htm_core = 1;

>  	}

> @@ -6594,15 +6559,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	  };

>  

>  	  for (i = 0; i < ARRAY_SIZE (cfprs); i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						PPC_CF0_REGNUM + i,

>  						cfprs[i]);

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_htm_fpu = 1;

>  	}

>        else

> @@ -6624,15 +6586,12 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	  };

>  

>  	  for (i = 0; i < ARRAY_SIZE (cvmx); i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						PPC_CVR0_REGNUM + i,

>  						cvmx[i]);

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_htm_altivec = 1;

>  	}

>        else

> @@ -6654,16 +6613,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	  };

>  

>  	  for (i = 0; i < ARRAY_SIZE (cvsx); i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data,

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

>  						(PPC_CVSR0_UPPER_REGNUM

>  						 + i),

>  						cvsx[i]);

>  

>  	  if (!valid_p || !have_htm_fpu || !have_htm_altivec)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_htm_vsx = 1;

>  	}

>        else

> @@ -6673,14 +6629,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  				    "org.gnu.gdb.power.htm.ppr");

>        if (feature != NULL)

>  	{

> -	  valid_p = tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p = tdesc_numbered_register (feature, tdesc_data.get (),

>  					     PPC_CPPR_REGNUM, "cppr");

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_htm_ppr = 1;

>  	}

>        else

> @@ -6690,14 +6643,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  				    "org.gnu.gdb.power.htm.dscr");

>        if (feature != NULL)

>  	{

> -	  valid_p = tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p = tdesc_numbered_register (feature, tdesc_data.get (),

>  					     PPC_CDSCR_REGNUM, "cdscr");

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_htm_dscr = 1;

>  	}

>        else

> @@ -6707,14 +6657,11 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  				    "org.gnu.gdb.power.htm.tar");

>        if (feature != NULL)

>  	{

> -	  valid_p = tdesc_numbered_register (feature, tdesc_data,

> +	  valid_p = tdesc_numbered_register (feature, tdesc_data.get (),

>  					     PPC_CTAR_REGNUM, "ctar");

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	  have_htm_tar = 1;

>  	}

>        else

> @@ -6733,10 +6680,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>       supplies a 64-bit description while debugging a 32-bit

>       binary.  */

>    if (tdesc_wordsize != -1 && tdesc_wordsize != wordsize)

> -    {

> -      tdesc_data_cleanup (tdesc_data);

> -      return NULL;

> -    }

> +    return NULL;

>  

>  #ifdef HAVE_ELF

>    if (from_elf_exec)

> @@ -6872,11 +6816,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        if (tdep && tdep->vector_abi != vector_abi)

>  	continue;

>        if (tdep && tdep->wordsize == wordsize)

> -	{

> -	  if (tdesc_data != NULL)

> -	    tdesc_data_cleanup (tdesc_data);

> -	  return arches->gdbarch;

> -	}

> +	return arches->gdbarch;

>      }

>  

>    /* None found, create a new architecture from INFO, whose bfd_arch_info

> @@ -7070,7 +7010,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>    /* Hook in ABI-specific overrides, if they have been registered.  */

>    info.target_desc = tdesc;

> -  info.tdesc_data = tdesc_data;

> +  info.tdesc_data = tdesc_data.get ();

>    gdbarch_init_osabi (info, gdbarch);

>  

>    switch (info.osabi)

> @@ -7093,7 +7033,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    set_tdesc_pseudo_register_type (gdbarch, rs6000_pseudo_register_type);

>    set_tdesc_pseudo_register_reggroup_p (gdbarch,

>  					rs6000_pseudo_register_reggroup_p);

> -  tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>    /* Override the normal target description method to make the SPE upper

>       halves anonymous.  */

> diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c

> index 1148eeae0e3..9352ff11c23 100644

> --- a/gdb/rx-tdep.c

> +++ b/gdb/rx-tdep.c

> @@ -944,7 +944,7 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    struct gdbarch *gdbarch;

>    struct gdbarch_tdep *tdep;

>    int elf_flags;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    const struct target_desc *tdesc = info.target_desc;

>  

>    /* Extract the elf_flags if available.  */

> @@ -982,15 +982,12 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	{

>  	  tdesc_data = tdesc_data_alloc ();

>  	  for (int i = 0; i < RX_NUM_REGS; i++)

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> -                                            rx_register_names[i]);

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

> +						rx_register_names[i]);

>  	}

>  

>        if (!valid_p)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>      }

>  

>    gdb_assert(tdesc_data != NULL);

> @@ -1000,7 +997,7 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    tdep->elf_flags = elf_flags;

>  

>    set_gdbarch_num_regs (gdbarch, RX_NUM_REGS);

> -  tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>    set_gdbarch_num_pseudo_regs (gdbarch, 0);

>    set_gdbarch_pc_regnum (gdbarch, RX_PC_REGNUM);

> diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c

> index 0ee7a372563..2a326e38083 100644

> --- a/gdb/s390-tdep.c

> +++ b/gdb/s390-tdep.c

> @@ -7020,8 +7020,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>    struct gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc ();

>    struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);

> -  struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();

> -  info.tdesc_data = tdesc_data;

> +  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();

> +  info.tdesc_data = tdesc_data.get ();

>  

>    set_gdbarch_believe_pcc_promotion (gdbarch, 0);

>    set_gdbarch_char_signed (gdbarch, 0);

> @@ -7147,9 +7147,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    tdep->tdesc = tdesc;

>  

>    /* Check any target description for validity.  */

> -  if (!s390_tdesc_valid (tdep, tdesc_data))

> +  if (!s390_tdesc_valid (tdep, tdesc_data.get ()))

>      {

> -      tdesc_data_cleanup (tdesc_data);

>        xfree (tdep);

>        gdbarch_free (gdbarch);

>        return NULL;

> @@ -7180,13 +7179,12 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>        if (tmp->vector_abi != tdep->vector_abi)

>  	continue;

>  

> -      tdesc_data_cleanup (tdesc_data);

>        xfree (tdep);

>        gdbarch_free (gdbarch);

>        return arches->gdbarch;

>      }

>  

> -  tdesc_use_registers (gdbarch, tdep->tdesc, tdesc_data);

> +  tdesc_use_registers (gdbarch, tdep->tdesc, std::move (tdesc_data));

>    set_gdbarch_register_name (gdbarch, s390_register_name);

>  

>    /* Assign pseudo register numbers.  */

> diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c

> index 9e00a678a19..7ad43d347a8 100644

> --- a/gdb/sparc-tdep.c

> +++ b/gdb/sparc-tdep.c

> @@ -1892,35 +1892,32 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>    if (tdesc_has_registers (tdesc))

>      {

> -      struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();

> +      tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();

>  

>        /* Validate that the descriptor provides the mandatory registers

>           and allocate their numbers. */

> -      valid_p &= validate_tdesc_registers (tdesc, tdesc_data,

> +      valid_p &= validate_tdesc_registers (tdesc, tdesc_data.get (),

>                                             "org.gnu.gdb.sparc.cpu",

>                                             sparc_core_register_names,

>                                             ARRAY_SIZE (sparc_core_register_names),

>                                             SPARC_G0_REGNUM);

> -      valid_p &= validate_tdesc_registers (tdesc, tdesc_data,

> +      valid_p &= validate_tdesc_registers (tdesc, tdesc_data.get (),

>                                             "org.gnu.gdb.sparc.fpu",

>                                             tdep->fpu_register_names,

>                                             tdep->fpu_registers_num,

>                                             SPARC_F0_REGNUM);

> -      valid_p &= validate_tdesc_registers (tdesc, tdesc_data,

> +      valid_p &= validate_tdesc_registers (tdesc, tdesc_data.get (),

>                                             "org.gnu.gdb.sparc.cp0",

>                                             tdep->cp0_register_names,

>                                             tdep->cp0_registers_num,

>                                             SPARC_F0_REGNUM

>                                             + tdep->fpu_registers_num);

>        if (!valid_p)

> -        {

> -          tdesc_data_cleanup (tdesc_data);

> -          return NULL;

> -        }

> +	return NULL;

>  

>        /* Target description may have changed. */

> -      info.tdesc_data = tdesc_data;

> -      tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +      info.tdesc_data = tdesc_data.get ();

> +      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>      }

>  

>    /* If we have register sets, enable the generic core file support.  */

> diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c

> index 20d624c0c65..762ab4b8a6a 100644

> --- a/gdb/target-descriptions.c

> +++ b/gdb/target-descriptions.c

> @@ -773,10 +773,10 @@ tdesc_data_init (struct obstack *obstack)

>  /* Similar, but for the temporary copy used during architecture

>     initialization.  */

>  

> -struct tdesc_arch_data *

> +tdesc_arch_data_up

>  tdesc_data_alloc (void)

>  {

> -  return new tdesc_arch_data ();

> +  return tdesc_arch_data_up (new tdesc_arch_data ());

>  }

>  

>  /* Free something allocated by tdesc_data_alloc, if it is not going

> @@ -784,10 +784,8 @@ tdesc_data_alloc (void)

>     architecture).  */

>  

>  void

> -tdesc_data_cleanup (void *data_untyped)

> +tdesc_arch_data_deleter::operator() (struct tdesc_arch_data *data) const

>  {

> -  struct tdesc_arch_data *data = (struct tdesc_arch_data *) data_untyped;

> -

>    delete data;

>  }

>  

> @@ -1097,7 +1095,7 @@ set_tdesc_pseudo_register_reggroup_p

>  void

>  tdesc_use_registers (struct gdbarch *gdbarch,

>  		     const struct target_desc *target_desc,

> -		     struct tdesc_arch_data *early_data,

> +		     tdesc_arch_data_up &&early_data,

>  		     tdesc_unknown_register_ftype unk_reg_cb)

>  {

>    int num_regs = gdbarch_num_regs (gdbarch);

> @@ -1112,7 +1110,6 @@ tdesc_use_registers (struct gdbarch *gdbarch,

>  

>    data = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);

>    data->arch_regs = early_data->arch_regs;

> -  delete early_data;

>  

>    /* Build up a set of all registers, so that we can assign register

>       numbers where needed.  The hash table expands as necessary, so

> diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h

> index 66a2c213dc2..171ef76379a 100644

> --- a/gdb/target-descriptions.h

> +++ b/gdb/target-descriptions.h

> @@ -104,6 +104,18 @@ typedef int (*tdesc_unknown_register_ftype)

>  	(struct gdbarch *gdbarch, tdesc_feature *feature,

>  	 const char *reg_name, int possible_regnum);

>  

> +/* A deleter adapter for a target arch data.  */

> +

> +struct tdesc_arch_data_deleter

> +{

> +  void operator() (struct tdesc_arch_data *data) const;

> +};

> +

> +/* A unique pointer specialization that holds a target_desc.  */

> +

> +typedef std::unique_ptr<tdesc_arch_data, tdesc_arch_data_deleter>

> +  tdesc_arch_data_up;

> +

>  /* Update GDBARCH to use the TARGET_DESC for registers.  TARGET_DESC

>     may be GDBARCH's target description or (if GDBARCH does not have

>     one which describes registers) another target description

> @@ -119,19 +131,13 @@ typedef int (*tdesc_unknown_register_ftype)

>  

>  void tdesc_use_registers (struct gdbarch *gdbarch,

>  			  const struct target_desc *target_desc,

> -			  struct tdesc_arch_data *early_data,

> +			  tdesc_arch_data_up &&early_data,

>  			  tdesc_unknown_register_ftype unk_reg_cb = NULL);

>  

>  /* Allocate initial data for validation of a target description during

>     gdbarch initialization.  */

>  

> -struct tdesc_arch_data *tdesc_data_alloc (void);

> -

> -/* Clean up data allocated by tdesc_data_alloc.  This should only

> -   be called to discard the data; tdesc_use_registers takes ownership

> -   of its EARLY_DATA argument.  */

> -

> -void tdesc_data_cleanup (void *data_untyped);

> +tdesc_arch_data_up tdesc_data_alloc ();

>  

>  /* Search FEATURE for a register named NAME.  Record REGNO and the

>     register in DATA; when tdesc_use_registers is called, REGNO will be

> diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c

> index 57945d21db7..b78db89b4e2 100644

> --- a/gdb/tic6x-tdep.c

> +++ b/gdb/tic6x-tdep.c

> @@ -1140,7 +1140,7 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  {

>    struct gdbarch *gdbarch;

>    struct gdbarch_tdep *tdep;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;

>    const struct target_desc *tdesc = info.target_desc;

>    int has_gp = 0;

>  

> @@ -1159,20 +1159,17 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  

>        valid_p = 1;

>        for (i = 0; i < 32; i++)	/* A0 - A15, B0 - B15 */

> -	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,

> +	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,

>  					    tic6x_register_names[i]);

>  

>        /* CSR */

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data, i++,

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i++,

>  					  tic6x_register_names[TIC6X_CSR_REGNUM]);

> -      valid_p &= tdesc_numbered_register (feature, tdesc_data, i++,

> +      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i++,

>  					  tic6x_register_names[TIC6X_PC_REGNUM]);

>  

>        if (!valid_p)

> -	{

> -	  tdesc_data_cleanup (tdesc_data);

> -	  return NULL;

> -	}

> +	return NULL;

>  

>        feature = tdesc_find_feature (tdesc, "org.gnu.gdb.tic6x.gp");

>        if (feature)

> @@ -1189,28 +1186,25 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  	  has_gp = 1;

>  	  valid_p = 1;

>  	  for (j = 0; j < 32; j++)	/* A16 - A31, B16 - B31 */

> -	    valid_p &= tdesc_numbered_register (feature, tdesc_data, i++,

> -						gp[j]);

> +	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

> +						i++, gp[j]);

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	}

>  

>        feature = tdesc_find_feature (tdesc, "org.gnu.gdb.tic6x.c6xp");

>        if (feature)

>  	{

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data, i++, "TSR");

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data, i++, "ILC");

> -	  valid_p &= tdesc_numbered_register (feature, tdesc_data, i++, "RILC");

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

> +					      i++, "TSR");

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

> +					      i++, "ILC");

> +	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),

> +					      i++, "RILC");

>  

>  	  if (!valid_p)

> -	    {

> -	      tdesc_data_cleanup (tdesc_data);

> -	      return NULL;

> -	    }

> +	    return NULL;

>  	}

>  

>      }

> @@ -1295,8 +1289,8 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>    /* Hook in ABI-specific overrides, if they have been registered.  */

>    gdbarch_init_osabi (info, gdbarch);

>  

> -  if (tdesc_data)

> -    tdesc_use_registers (gdbarch, tdesc, tdesc_data);

> +  if (tdesc_data != nullptr)

> +    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

>  

>    return gdbarch;

>  }

> -- 

> 2.26.2

>
Simon Marchi July 28, 2020, 1:41 p.m. | #2
On 2020-07-27 3:36 p.m., Tom Tromey wrote:
> While working on something else, I noticed that tdesc_data_cleanup

> took a void* parameter.  Looking more into this, I found that

> tdesc_use_registers expected a transfer of ownership.

> 

> I think it's better to express this sort of thing via the type system,

> when possible.  This patch changes tdesc_data_alloc to return a unique

> pointer, changes tdesc_use_registers to accept an rvalue reference,

> and then adapts all the users.

> 

> Note that a deleter structure is introduced to avoid having to move

> tdesc_arch_data to the header file.


Good idea.

> @@ -784,10 +784,8 @@ tdesc_data_alloc (void)

>     architecture).  */

>  

>  void

> -tdesc_data_cleanup (void *data_untyped)

> +tdesc_arch_data_deleter::operator() (struct tdesc_arch_data *data) const


I think the comment above this is not relevant, and should be made into the
usual /* See foo.h. */.

> @@ -1097,7 +1095,7 @@ set_tdesc_pseudo_register_reggroup_p

>  void

>  tdesc_use_registers (struct gdbarch *gdbarch,

>  		     const struct target_desc *target_desc,

> -		     struct tdesc_arch_data *early_data,

> +		     tdesc_arch_data_up &&early_data,

>  		     tdesc_unknown_register_ftype unk_reg_cb)

>  {

>    int num_regs = gdbarch_num_regs (gdbarch);

> @@ -1112,7 +1110,6 @@ tdesc_use_registers (struct gdbarch *gdbarch,

>  

>    data = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);

>    data->arch_regs = early_data->arch_regs;


Not really important, but this could be an std::move to avoid copying the vector.

And since the function now takes an rvalue reference, we know it's fine to do this.
> diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c

> index 57945d21db7..b78db89b4e2 100644

> --- a/gdb/tic6x-tdep.c

> +++ b/gdb/tic6x-tdep.c

> @@ -1140,7 +1140,7 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)

>  {

>    struct gdbarch *gdbarch;

>    struct gdbarch_tdep *tdep;

> -  struct tdesc_arch_data *tdesc_data = NULL;

> +  tdesc_arch_data_up tdesc_data;


Move this where this is used, in the if?  That will avoid unnecessary construction/destruction.

That would apply to other arches as well.

Simon
Tom Tromey Sept. 17, 2020, 8:26 p.m. | #3
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:


>> @@ -784,10 +784,8 @@ tdesc_data_alloc (void)

>> architecture).  */

>> 

>> void

>> -tdesc_data_cleanup (void *data_untyped)

>> +tdesc_arch_data_deleter::operator() (struct tdesc_arch_data *data) const


Simon> I think the comment above this is not relevant, and should be made into the
Simon> usual /* See foo.h. */.

I made this change.

>> data-> arch_regs = early_data->arch_regs;


Simon> Not really important, but this could be an std::move to avoid
Simon> copying the vector.

And this one.

>> +  tdesc_arch_data_up tdesc_data;


Simon> Move this where this is used, in the if?  That will avoid
Simon> unnecessary construction/destruction.

It's used near the end of the function:

  if (tdesc_data != nullptr)
    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

This pattern is typical, so I didn't change anything here.

I'm going to check this patch in shortly.

Tom

Patch

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 5e7d0d0b868..b2dfb0e6234 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -3264,12 +3264,12 @@  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (feature_core == nullptr)
     return nullptr;
 
-  struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();
+  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
 
   /* Validate the description provides the mandatory core R registers
      and allocate their numbers.  */
   for (i = 0; i < ARRAY_SIZE (aarch64_r_register_names); i++)
-    valid_p &= tdesc_numbered_register (feature_core, tdesc_data,
+    valid_p &= tdesc_numbered_register (feature_core, tdesc_data.get (),
 					AARCH64_X0_REGNUM + i,
 					aarch64_r_register_names[i]);
 
@@ -3284,7 +3284,7 @@  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       /* Validate the description provides the mandatory V registers
 	 and allocate their numbers.  */
       for (i = 0; i < ARRAY_SIZE (aarch64_v_register_names); i++)
-	valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data,
+	valid_p &= tdesc_numbered_register (feature_fpu, tdesc_data.get (),
 					    AARCH64_V0_REGNUM + i,
 					    aarch64_v_register_names[i]);
 
@@ -3297,7 +3297,7 @@  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       /* Validate the description provides the mandatory SVE registers
 	 and allocate their numbers.  */
       for (i = 0; i < ARRAY_SIZE (aarch64_sve_register_names); i++)
-	valid_p &= tdesc_numbered_register (feature_sve, tdesc_data,
+	valid_p &= tdesc_numbered_register (feature_sve, tdesc_data.get (),
 					    AARCH64_SVE_Z0_REGNUM + i,
 					    aarch64_sve_register_names[i]);
 
@@ -3322,7 +3322,7 @@  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       /* Validate the descriptor provides the mandatory PAUTH registers and
 	 allocate their numbers.  */
       for (i = 0; i < ARRAY_SIZE (aarch64_pauth_register_names); i++)
-	valid_p &= tdesc_numbered_register (feature_pauth, tdesc_data,
+	valid_p &= tdesc_numbered_register (feature_pauth, tdesc_data.get (),
 					    first_pauth_regnum + i,
 					    aarch64_pauth_register_names[i]);
 
@@ -3331,10 +3331,7 @@  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   if (!valid_p)
-    {
-      tdesc_data_cleanup (tdesc_data);
-      return nullptr;
-    }
+    return nullptr;
 
   /* AArch64 code is always little-endian.  */
   info.byte_order_for_code = BFD_ENDIAN_LITTLE;
@@ -3415,7 +3412,7 @@  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Hook in the ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
-  info.tdesc_data = tdesc_data;
+  info.tdesc_data = tdesc_data.get ();
   gdbarch_init_osabi (info, gdbarch);
 
   dwarf2_frame_set_init_reg (gdbarch, aarch64_dwarf2_frame_init_reg);
@@ -3444,7 +3441,7 @@  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_get_pc_address_flags (gdbarch, aarch64_get_pc_address_flags);
 
-  tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   /* Add standard register aliases.  */
   for (i = 0; i < ARRAY_SIZE (aarch64_register_aliases); i++)
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index 7e6d29c334b..3441eceb4bb 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -1724,7 +1724,7 @@  static const struct frame_base arc_normal_base = {
 
 static bool
 arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
-		struct tdesc_arch_data **tdesc_data)
+		tdesc_arch_data_up *tdesc_data)
 {
   if (arc_debug)
     debug_printf ("arc: Target description initialization.\n");
@@ -1846,7 +1846,7 @@  arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
 	}
     }
 
-  struct tdesc_arch_data *tdesc_data_loc = tdesc_data_alloc ();
+  tdesc_arch_data_up tdesc_data_loc = tdesc_data_alloc ();
 
   gdb_assert (feature != NULL);
   int valid_p = 1;
@@ -1858,7 +1858,7 @@  arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
 			    || (i >= ARC_R16_REGNUM && i <= ARC_R25_REGNUM)))
 	continue;
 
-      valid_p = tdesc_numbered_register (feature, tdesc_data_loc, i,
+      valid_p = tdesc_numbered_register (feature, tdesc_data_loc.get (), i,
 					 core_regs[i]);
 
       /* - Ignore errors in extension registers - they are optional.
@@ -1875,7 +1875,6 @@  arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
 	{
 	  arc_print (_("Error: Cannot find required register `%s' in "
 		       "feature `%s'.\n"), core_regs[i], core_feature_name);
-	  tdesc_data_cleanup (tdesc_data_loc);
 	  return false;
 	}
     }
@@ -1887,26 +1886,25 @@  arc_tdesc_init (struct gdbarch_info info, const struct target_desc **tdesc,
     {
       arc_print (_("Error: Cannot find required feature `%s' in supplied "
 		   "target description.\n"), aux_minimal_feature_name);
-      tdesc_data_cleanup (tdesc_data_loc);
       return false;
     }
 
   for (int i = ARC_FIRST_AUX_REGNUM; i <= ARC_LAST_AUX_REGNUM; i++)
     {
       const char *name = aux_minimal_register_names[i - ARC_FIRST_AUX_REGNUM];
-      valid_p = tdesc_numbered_register (feature, tdesc_data_loc, i, name);
+      valid_p = tdesc_numbered_register (feature, tdesc_data_loc.get (),
+					 i, name);
       if (!valid_p)
 	{
 	  arc_print (_("Error: Cannot find required register `%s' "
 		       "in feature `%s'.\n"),
 		     name, tdesc_feature_name (feature));
-	  tdesc_data_cleanup (tdesc_data_loc);
 	  return false;
 	}
     }
 
   *tdesc = tdesc_loc;
-  *tdesc_data = tdesc_data_loc;
+  *tdesc_data = std::move (tdesc_data_loc);
 
   return true;
 }
@@ -1945,7 +1943,7 @@  static struct gdbarch *
 arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   const struct target_desc *tdesc;
-  struct tdesc_arch_data *tdesc_data;
+  tdesc_arch_data_up tdesc_data;
 
   if (arc_debug)
     debug_printf ("arc: Architecture initialization.\n");
@@ -2096,7 +2094,7 @@  arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	}
     }
 
-  tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   return gdbarch;
 }
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 9cedcc85755..d32f5a7291e 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -8856,7 +8856,7 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   struct gdbarch_list *best_arch;
   enum arm_abi_kind arm_abi = arm_abi_global;
   enum arm_float_model fp_model = arm_fp_model;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   int i;
   bool is_m = false;
   int vfp_register_count = 0;
@@ -9045,29 +9045,26 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
       valid_p = 1;
       for (i = 0; i < ARM_SP_REGNUM; i++)
-	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
 					    arm_register_names[i]);
-      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
 						  ARM_SP_REGNUM,
 						  arm_sp_names);
-      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
 						  ARM_LR_REGNUM,
 						  arm_lr_names);
-      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
 						  ARM_PC_REGNUM,
 						  arm_pc_names);
       if (is_m)
-	valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					    ARM_PS_REGNUM, "xpsr");
       else
-	valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					    ARM_PS_REGNUM, "cpsr");
 
       if (!valid_p)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
 
       feature = tdesc_find_feature (tdesc,
 				    "org.gnu.gdb.arm.fpa");
@@ -9075,13 +9072,10 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	{
 	  valid_p = 1;
 	  for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
 						arm_register_names[i]);
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	}
       else
 	have_fpa_registers = false;
@@ -9100,25 +9094,22 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  valid_p = 1;
 	  for (i = ARM_WR0_REGNUM; i <= ARM_WR15_REGNUM; i++)
 	    valid_p
-	      &= tdesc_numbered_register (feature, tdesc_data, i,
+	      &= tdesc_numbered_register (feature, tdesc_data.get (), i,
 					  iwmmxt_names[i - ARM_WR0_REGNUM]);
 
 	  /* Check for the control registers, but do not fail if they
 	     are missing.  */
 	  for (i = ARM_WC0_REGNUM; i <= ARM_WCASF_REGNUM; i++)
-	    tdesc_numbered_register (feature, tdesc_data, i,
+	    tdesc_numbered_register (feature, tdesc_data.get (), i,
 				     iwmmxt_names[i - ARM_WR0_REGNUM]);
 
 	  for (i = ARM_WCGR0_REGNUM; i <= ARM_WCGR3_REGNUM; i++)
 	    valid_p
-	      &= tdesc_numbered_register (feature, tdesc_data, i,
+	      &= tdesc_numbered_register (feature, tdesc_data.get (), i,
 					  iwmmxt_names[i - ARM_WR0_REGNUM]);
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 
 	  have_wmmx_registers = true;
 	}
@@ -9142,7 +9133,7 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  valid_p = 1;
 	  for (i = 0; i < 32; i++)
 	    {
-	      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						  ARM_D0_REGNUM + i,
 						  vfp_double_names[i]);
 	      if (!valid_p)
@@ -9152,13 +9143,10 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	    valid_p = 1;
 
 	  /* Also require FPSCR.  */
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      ARM_FPSCR_REGNUM, "fpscr");
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 
 	  if (tdesc_unnumbered_register (feature, "s0") == 0)
 	    have_vfp_pseudos = true;
@@ -9174,10 +9162,7 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	    {
 	      /* NEON requires 32 double-precision registers.  */
 	      if (i != 32)
-		{
-		  tdesc_data_cleanup (tdesc_data);
-		  return NULL;
-		}
+		return NULL;
 
 	      /* If there are quad registers defined by the stub, use
 		 their type; otherwise (normally) provide them with
@@ -9217,11 +9202,7 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   if (best_arch != NULL)
-    {
-      if (tdesc_data != NULL)
-	tdesc_data_cleanup (tdesc_data);
-      return best_arch->gdbarch;
-    }
+    return best_arch->gdbarch;
 
   tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
@@ -9423,11 +9404,11 @@  arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
     }
 
-  if (tdesc_data)
+  if (tdesc_data != nullptr)
     {
       set_tdesc_pseudo_register_name (gdbarch, arm_register_name);
 
-      tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
       /* Override tdesc_register_type to adjust the types of VFP
 	 registers for NEON.  */
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 9b905c1996a..6fb8dc4fdff 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8420,7 +8420,6 @@  i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch_tdep *tdep;
   struct gdbarch *gdbarch;
-  struct tdesc_arch_data *tdesc_data;
   const struct target_desc *tdesc;
   int mm0_regnum;
   int ymm0_regnum;
@@ -8656,7 +8655,7 @@  i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* No segment base registers.  */
   tdep->fsbase_regnum = -1;
 
-  tdesc_data = tdesc_data_alloc ();
+  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
 
   set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction);
 
@@ -8669,12 +8668,11 @@  i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Hook in ABI-specific overrides, if they have been registered.
      Note: If INFO specifies a 64 bit arch, this is where we turn
      a 32-bit i386 into a 64-bit amd64.  */
-  info.tdesc_data = tdesc_data;
+  info.tdesc_data = tdesc_data.get ();
   gdbarch_init_osabi (info, gdbarch);
 
-  if (!i386_validate_tdesc_p (tdep, tdesc_data))
+  if (!i386_validate_tdesc_p (tdep, tdesc_data.get ()))
     {
-      tdesc_data_cleanup (tdesc_data);
       xfree (tdep);
       gdbarch_free (gdbarch);
       return NULL;
@@ -8696,7 +8694,7 @@  i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Target description may be changed.  */
   tdesc = tdep->tdesc;
 
-  tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   /* Override gdbarch_register_reggroup_p set in tdesc_use_registers.  */
   set_gdbarch_register_reggroup_p (gdbarch, tdep->register_reggroup_p);
diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c
index 27870252a36..c2ee3815882 100644
--- a/gdb/m68k-tdep.c
+++ b/gdb/m68k-tdep.c
@@ -1075,7 +1075,7 @@  m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   struct gdbarch_tdep *tdep = NULL;
   struct gdbarch *gdbarch;
   struct gdbarch_list *best_arch;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   int i;
   enum m68k_flavour flavour = m68k_no_flavour;
   int has_fp = 1;
@@ -1113,14 +1113,11 @@  m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
       valid_p = 1;
       for (i = 0; i <= M68K_PC_REGNUM; i++)
-	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
 					    m68k_register_names[i]);
 
       if (!valid_p)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
 
       feature = tdesc_find_feature (info.target_desc,
 				    "org.gnu.gdb.coldfire.fp");
@@ -1128,13 +1125,10 @@  m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	{
 	  valid_p = 1;
 	  for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
 						m68k_register_names[i]);
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	}
       else
 	has_fp = 0;
@@ -1170,11 +1164,7 @@  m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   if (best_arch != NULL)
-    {
-      if (tdesc_data != NULL)
-	tdesc_data_cleanup (tdesc_data);
-      return best_arch->gdbarch;
-    }
+    return best_arch->gdbarch;
 
   tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
@@ -1265,8 +1255,8 @@  m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   frame_unwind_append_unwinder (gdbarch, &m68k_frame_unwind);
 
-  if (tdesc_data)
-    tdesc_use_registers (gdbarch, info.target_desc, tdesc_data);
+  if (tdesc_data != nullptr)
+    tdesc_use_registers (gdbarch, info.target_desc, std::move (tdesc_data));
 
   return gdbarch;
 }
diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
index 5c804133040..f3d0966cc08 100644
--- a/gdb/microblaze-tdep.c
+++ b/gdb/microblaze-tdep.c
@@ -651,7 +651,7 @@  microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch_tdep *tdep;
   struct gdbarch *gdbarch;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
 
   /* If there is already a candidate, use it.  */
@@ -676,26 +676,23 @@  microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
       valid_p = 1;
       for (i = 0; i < MICROBLAZE_NUM_CORE_REGS; i++)
-        valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+        valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
                                             microblaze_register_names[i]);
       feature = tdesc_find_feature (tdesc,
                                     "org.gnu.gdb.microblaze.stack-protect");
       if (feature != NULL)
         {
           valid_p = 1;
-          valid_p &= tdesc_numbered_register (feature, tdesc_data,
+          valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                               MICROBLAZE_SLR_REGNUM,
                                               "rslr");
-          valid_p &= tdesc_numbered_register (feature, tdesc_data,
+          valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
                                               MICROBLAZE_SHR_REGNUM,
                                               "rshr");
         }
 
       if (!valid_p)
-        {
-          tdesc_data_cleanup (tdesc_data);
-          return NULL;
-        }
+	return NULL;
     }
 
   /* Allocate space for the new architecture.  */
@@ -748,7 +745,7 @@  microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   frame_unwind_append_unwinder (gdbarch, &microblaze_frame_unwind);
   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
   if (tdesc_data != NULL)
-    tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   return gdbarch;
 }
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index e0f04888808..e948cace212 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -8047,7 +8047,7 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   enum mips_abi mips_abi, found_abi, wanted_abi;
   int i, num_regs;
   enum mips_fpu_type fpu_type;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   int elf_fpu_type = Val_GNU_MIPS_ABI_FP_ANY;
   const char **reg_names;
   struct mips_regnum mips_regnum, *regnum;
@@ -8310,73 +8310,58 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
       valid_p = 1;
       for (i = MIPS_ZERO_REGNUM; i <= MIPS_RA_REGNUM; i++)
-	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
 					    mips_gprs[i]);
 
 
-      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					  mips_regnum.lo, "lo");
-      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					  mips_regnum.hi, "hi");
-      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					  mips_regnum.pc, "pc");
 
       if (!valid_p)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
 
       feature = tdesc_find_feature (info.target_desc,
 				    "org.gnu.gdb.mips.cp0");
       if (feature == NULL)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
 
       valid_p = 1;
-      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					  mips_regnum.badvaddr, "badvaddr");
-      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					  MIPS_PS_REGNUM, "status");
-      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					  mips_regnum.cause, "cause");
 
       if (!valid_p)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
 
       /* FIXME drow/2007-05-17: The FPU should be optional.  The MIPS
 	 backend is not prepared for that, though.  */
       feature = tdesc_find_feature (info.target_desc,
 				    "org.gnu.gdb.mips.fpu");
       if (feature == NULL)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
 
       valid_p = 1;
       for (i = 0; i < 32; i++)
-	valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					    i + mips_regnum.fp0, mips_fprs[i]);
 
-      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					  mips_regnum.fp_control_status,
 					  "fcsr");
       valid_p
-	&= tdesc_numbered_register (feature, tdesc_data,
+	&= tdesc_numbered_register (feature, tdesc_data.get (),
 				    mips_regnum.fp_implementation_revision,
 				    "fir");
 
       if (!valid_p)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
 
       num_regs = mips_regnum.fp_implementation_revision + 1;
 
@@ -8389,27 +8374,24 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	    {
 	      i = 0;
 	      valid_p = 1;
-	      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						  dspacc + i++, "hi1");
-	      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						  dspacc + i++, "lo1");
-	      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						  dspacc + i++, "hi2");
-	      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						  dspacc + i++, "lo2");
-	      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						  dspacc + i++, "hi3");
-	      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						  dspacc + i++, "lo3");
 
-	      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						  dspctl, "dspctl");
 
 	      if (!valid_p)
-		{
-		  tdesc_data_cleanup (tdesc_data);
-		  return NULL;
-		}
+		return NULL;
 
 	      mips_regnum.dspacc = dspacc;
 	      mips_regnum.dspctl = dspctl;
@@ -8445,8 +8427,6 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (MIPS_FPU_TYPE (arches->gdbarch) != fpu_type)
 	continue;
 
-      if (tdesc_data != NULL)
-	tdesc_data_cleanup (tdesc_data);
       return arches->gdbarch;
     }
 
@@ -8743,7 +8723,7 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   mips_register_g_packet_guesses (gdbarch);
 
   /* Hook in OS ABI-specific overrides, if they have been registered.  */
-  info.tdesc_data = tdesc_data;
+  info.tdesc_data = tdesc_data.get ();
   gdbarch_init_osabi (info, gdbarch);
 
   /* The hook may have adjusted num_regs, fetch the final value and
@@ -8764,10 +8744,10 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   frame_base_append_sniffer (gdbarch, mips_micro_frame_base_sniffer);
   frame_base_append_sniffer (gdbarch, mips_insn32_frame_base_sniffer);
 
-  if (tdesc_data)
+  if (tdesc_data != nullptr)
     {
       set_tdesc_pseudo_register_type (gdbarch, mips_pseudo_register_type);
-      tdesc_use_registers (gdbarch, info.target_desc, tdesc_data);
+      tdesc_use_registers (gdbarch, info.target_desc, std::move (tdesc_data));
 
       /* Override the normal target description methods to handle our
 	 dual real and pseudo registers.  */
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index 94ac234d3fb..4305292522e 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -1955,7 +1955,7 @@  nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
   struct gdbarch_list *best_arch;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
   int elf_abi = E_NDS_ABI_AABI;
   int fpu_freg = -1;
@@ -1988,11 +1988,9 @@  nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   tdesc_data = tdesc_data_alloc ();
 
-  if (!nds32_validate_tdesc_p (tdesc, tdesc_data, &fpu_freg, &use_pseudo_fsrs))
-    {
-      tdesc_data_cleanup (tdesc_data);
-      return NULL;
-    }
+  if (!nds32_validate_tdesc_p (tdesc, tdesc_data.get (), &fpu_freg,
+			       &use_pseudo_fsrs))
+    return NULL;
 
   /* Allocate space for the new architecture.  */
   tdep = XCNEW (struct gdbarch_tdep);
@@ -2022,7 +2020,7 @@  nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     num_regs = NDS32_NUM_REGS + num_fdr_map[fpu_freg] + num_fsr_map[fpu_freg];
 
   set_gdbarch_num_regs (gdbarch, num_regs);
-  tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   /* Cache the register number of fs0.  */
   if (fpu_freg != -1)
@@ -2061,7 +2059,7 @@  nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   nds32_add_reggroups (gdbarch);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
-  info.tdesc_data = tdesc_data;
+  info.tdesc_data = tdesc_data.get ();
   gdbarch_init_osabi (info, gdbarch);
 
   /* Override tdesc_register callbacks for system registers.  */
diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c
index acc28735035..09eb6fcb5dd 100644
--- a/gdb/nios2-tdep.c
+++ b/gdb/nios2-tdep.c
@@ -2275,7 +2275,7 @@  nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
   int i;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
 
   if (!tdesc_has_registers (tdesc))
@@ -2297,14 +2297,11 @@  nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       valid_p = 1;
       
       for (i = 0; i < NIOS2_NUM_REGS; i++)
-	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
 					    nios2_reg_names[i]);
 
       if (!valid_p)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
     }
 
   /* Find a candidate among the list of pre-declared architectures.  */
@@ -2384,8 +2381,8 @@  nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Enable inferior call support.  */
   set_gdbarch_push_dummy_call (gdbarch, nios2_push_dummy_call);
 
-  if (tdesc_data)
-    tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+  if (tdesc_data != nullptr)
+    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   return gdbarch;
 }
diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c
index 75df206a2bd..fd067a9c782 100644
--- a/gdb/or1k-tdep.c
+++ b/gdb/or1k-tdep.c
@@ -1113,7 +1113,7 @@  or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
   const struct bfd_arch_info *binfo;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
 
   /* Find a candidate among the list of pre-declared architectures.  */
@@ -1221,14 +1221,11 @@  or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       valid_p = 1;
 
       for (i = 0; i < OR1K_NUM_REGS; i++)
-        valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+        valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
                                             or1k_reg_names[i]);
 
       if (!valid_p)
-        {
-          tdesc_data_cleanup (tdesc_data);
-          return NULL;
-        }
+	return NULL;
     }
 
   if (tdesc_data != NULL)
@@ -1243,7 +1240,7 @@  or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       reggroup_add (gdbarch, save_reggroup);
       reggroup_add (gdbarch, restore_reggroup);
 
-      tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
     }
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index b86ba630540..46ce3674d31 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -3320,10 +3320,10 @@  riscv_gdbarch_init (struct gdbarch_info info,
   if (feature_cpu == NULL)
     return NULL;
 
-  struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();
+  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
   std::vector<riscv_pending_register_alias> pending_aliases;
 
-  bool valid_p = riscv_check_tdesc_feature (tdesc_data,
+  bool valid_p = riscv_check_tdesc_feature (tdesc_data.get (),
                                             feature_cpu, feature_csr,
                                             &riscv_xreg_feature,
                                             &pending_aliases);
@@ -3345,7 +3345,7 @@  riscv_gdbarch_init (struct gdbarch_info info,
 
   if (feature_fpu != NULL)
     {
-      valid_p &= riscv_check_tdesc_feature (tdesc_data, feature_fpu,
+      valid_p &= riscv_check_tdesc_feature (tdesc_data.get (), feature_fpu,
 					    feature_csr,
                                             &riscv_freg_feature,
                                             &pending_aliases);
@@ -3383,12 +3383,12 @@  riscv_gdbarch_init (struct gdbarch_info info,
     }
 
   if (feature_virtual)
-    riscv_check_tdesc_feature (tdesc_data, feature_virtual, feature_csr,
+    riscv_check_tdesc_feature (tdesc_data.get (), feature_virtual, feature_csr,
                                &riscv_virtual_feature,
                                &pending_aliases);
 
   if (feature_csr)
-    riscv_check_tdesc_feature (tdesc_data, feature_csr, nullptr,
+    riscv_check_tdesc_feature (tdesc_data.get (), feature_csr, nullptr,
                                &riscv_csr_feature,
                                &pending_aliases);
 
@@ -3396,7 +3396,6 @@  riscv_gdbarch_init (struct gdbarch_info info,
     {
       if (riscv_debug_gdbarch)
         fprintf_unfiltered (gdb_stdlog, "Target description is not valid\n");
-      tdesc_data_cleanup (tdesc_data);
       return NULL;
     }
 
@@ -3442,10 +3441,7 @@  riscv_gdbarch_init (struct gdbarch_info info,
     }
 
   if (arches != NULL)
-    {
-      tdesc_data_cleanup (tdesc_data);
-      return arches->gdbarch;
-    }
+    return arches->gdbarch;
 
   /* None found, so create a new architecture from the information provided.  */
   tdep = new (struct gdbarch_tdep);
@@ -3511,7 +3507,8 @@  riscv_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_print_registers_info (gdbarch, riscv_print_registers_info);
 
   /* Finalise the target description registers.  */
-  tdesc_use_registers (gdbarch, tdesc, tdesc_data, riscv_tdesc_unknown_reg);
+  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data),
+		       riscv_tdesc_unknown_reg);
 
   /* Override the register type callback setup by the target description
      mechanism.  This allows us to provide special type for floating point
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 84278e708e7..82d4b205796 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -6138,7 +6138,7 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   int have_htm_tar = 0;
   int tdesc_wordsize = -1;
   const struct target_desc *tdesc = info.target_desc;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   int num_pseudoregs = 0;
   int cur_reg;
 
@@ -6235,31 +6235,29 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
       valid_p = 1;
       for (i = 0; i < ppc_num_gprs; i++)
-	valid_p &= tdesc_numbered_register (feature, tdesc_data, i, gprs[i]);
-      valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_PC_REGNUM,
-					  "pc");
-      valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_LR_REGNUM,
-					  "lr");
-      valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_XER_REGNUM,
-					  "xer");
+	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+					    i, gprs[i]);
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+					  PPC_PC_REGNUM, "pc");
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+					  PPC_LR_REGNUM, "lr");
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+					  PPC_XER_REGNUM, "xer");
 
       /* Allow alternate names for these registers, to accomodate GDB's
 	 historic naming.  */
-      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
 						  PPC_MSR_REGNUM, msr_names);
-      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
 						  PPC_CR_REGNUM, cr_names);
-      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+      valid_p &= tdesc_numbered_register_choices (feature, tdesc_data.get (),
 						  PPC_CTR_REGNUM, ctr_names);
 
       if (!valid_p)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
 
-      have_mq = tdesc_numbered_register (feature, tdesc_data, PPC_MQ_REGNUM,
-					 "mq");
+      have_mq = tdesc_numbered_register (feature, tdesc_data.get (),
+					 PPC_MQ_REGNUM, "mq");
 
       tdesc_wordsize = tdesc_register_bitsize (feature, "pc") / 8;
       if (wordsize == -1)
@@ -6277,16 +6275,13 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  };
 	  valid_p = 1;
 	  for (i = 0; i < ppc_num_fprs; i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						PPC_F0_REGNUM + i, fprs[i]);
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_FPSCR_REGNUM, "fpscr");
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_fpu = 1;
 
 	  /* The fpscr register was expanded in isa 2.05 to 64 bits
@@ -6311,19 +6306,16 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
 	  valid_p = 1;
 	  for (i = 0; i < ppc_num_gprs; i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						PPC_VR0_REGNUM + i,
 						vector_regs[i]);
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_VSCR_REGNUM, "vscr");
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_VRSAVE_REGNUM, "vrsave");
 
 	  if (have_spe || !valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_altivec = 1;
 	}
       else
@@ -6347,15 +6339,12 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  valid_p = 1;
 
 	  for (i = 0; i < ppc_num_vshrs; i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						PPC_VSR0_UPPER_REGNUM + i,
 						vsx_regs[i]);
 
 	  if (!valid_p || !have_fpu || !have_altivec)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 
 	  have_vsx = 1;
 	}
@@ -6392,19 +6381,16 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
 	  valid_p = 1;
 	  for (i = 0; i < ppc_num_gprs; i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						PPC_SPE_UPPER_GP0_REGNUM + i,
 						upper_spe[i]);
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_SPE_ACC_REGNUM, "acc");
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_SPE_FSCR_REGNUM, "spefscr");
 
 	  if (have_mq || have_fpu || !valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_spe = 1;
 	}
       else
@@ -6416,14 +6402,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (feature != NULL)
 	{
 	  valid_p = 1;
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_PPR_REGNUM, "ppr");
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_ppr = 1;
 	}
       else
@@ -6435,14 +6418,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (feature != NULL)
 	{
 	  valid_p = 1;
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_DSCR_REGNUM, "dscr");
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_dscr = 1;
 	}
       else
@@ -6454,14 +6434,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (feature != NULL)
 	{
 	  valid_p = 1;
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_TAR_REGNUM, "tar");
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_tar = 1;
 	}
       else
@@ -6478,14 +6455,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
 	  valid_p = 1;
 	  for (i = 0; i < ARRAY_SIZE (ebb_regs); i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						PPC_BESCR_REGNUM + i,
 						ebb_regs[i]);
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_ebb = 1;
 	}
       else
@@ -6499,27 +6473,24 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	{
 	  valid_p = 1;
 
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_MMCR0_REGNUM,
 					      "mmcr0");
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_MMCR2_REGNUM,
 					      "mmcr2");
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_SIAR_REGNUM,
 					      "siar");
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_SDAR_REGNUM,
 					      "sdar");
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 					      PPC_SIER_REGNUM,
 					      "sier");
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_pmu = 1;
 	}
       else
@@ -6536,14 +6507,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
 	  valid_p = 1;
 	  for (i = 0; i < ARRAY_SIZE (tm_spr_regs); i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						PPC_TFHAR_REGNUM + i,
 						tm_spr_regs[i]);
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 
 	  have_htm_spr = 1;
 	}
@@ -6565,14 +6533,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  valid_p = 1;
 
 	  for (i = 0; i < ARRAY_SIZE (cgprs); i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						PPC_CR0_REGNUM + i,
 						cgprs[i]);
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 
 	  have_htm_core = 1;
 	}
@@ -6594,15 +6559,12 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  };
 
 	  for (i = 0; i < ARRAY_SIZE (cfprs); i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						PPC_CF0_REGNUM + i,
 						cfprs[i]);
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_htm_fpu = 1;
 	}
       else
@@ -6624,15 +6586,12 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  };
 
 	  for (i = 0; i < ARRAY_SIZE (cvmx); i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						PPC_CVR0_REGNUM + i,
 						cvmx[i]);
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_htm_altivec = 1;
 	}
       else
@@ -6654,16 +6613,13 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  };
 
 	  for (i = 0; i < ARRAY_SIZE (cvsx); i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data,
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
 						(PPC_CVSR0_UPPER_REGNUM
 						 + i),
 						cvsx[i]);
 
 	  if (!valid_p || !have_htm_fpu || !have_htm_altivec)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_htm_vsx = 1;
 	}
       else
@@ -6673,14 +6629,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 				    "org.gnu.gdb.power.htm.ppr");
       if (feature != NULL)
 	{
-	  valid_p = tdesc_numbered_register (feature, tdesc_data,
+	  valid_p = tdesc_numbered_register (feature, tdesc_data.get (),
 					     PPC_CPPR_REGNUM, "cppr");
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_htm_ppr = 1;
 	}
       else
@@ -6690,14 +6643,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 				    "org.gnu.gdb.power.htm.dscr");
       if (feature != NULL)
 	{
-	  valid_p = tdesc_numbered_register (feature, tdesc_data,
+	  valid_p = tdesc_numbered_register (feature, tdesc_data.get (),
 					     PPC_CDSCR_REGNUM, "cdscr");
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_htm_dscr = 1;
 	}
       else
@@ -6707,14 +6657,11 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 				    "org.gnu.gdb.power.htm.tar");
       if (feature != NULL)
 	{
-	  valid_p = tdesc_numbered_register (feature, tdesc_data,
+	  valid_p = tdesc_numbered_register (feature, tdesc_data.get (),
 					     PPC_CTAR_REGNUM, "ctar");
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	  have_htm_tar = 1;
 	}
       else
@@ -6733,10 +6680,7 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      supplies a 64-bit description while debugging a 32-bit
      binary.  */
   if (tdesc_wordsize != -1 && tdesc_wordsize != wordsize)
-    {
-      tdesc_data_cleanup (tdesc_data);
-      return NULL;
-    }
+    return NULL;
 
 #ifdef HAVE_ELF
   if (from_elf_exec)
@@ -6872,11 +6816,7 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (tdep && tdep->vector_abi != vector_abi)
 	continue;
       if (tdep && tdep->wordsize == wordsize)
-	{
-	  if (tdesc_data != NULL)
-	    tdesc_data_cleanup (tdesc_data);
-	  return arches->gdbarch;
-	}
+	return arches->gdbarch;
     }
 
   /* None found, create a new architecture from INFO, whose bfd_arch_info
@@ -7070,7 +7010,7 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
-  info.tdesc_data = tdesc_data;
+  info.tdesc_data = tdesc_data.get ();
   gdbarch_init_osabi (info, gdbarch);
 
   switch (info.osabi)
@@ -7093,7 +7033,7 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_tdesc_pseudo_register_type (gdbarch, rs6000_pseudo_register_type);
   set_tdesc_pseudo_register_reggroup_p (gdbarch,
 					rs6000_pseudo_register_reggroup_p);
-  tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   /* Override the normal target description method to make the SPE upper
      halves anonymous.  */
diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c
index 1148eeae0e3..9352ff11c23 100644
--- a/gdb/rx-tdep.c
+++ b/gdb/rx-tdep.c
@@ -944,7 +944,7 @@  rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
   int elf_flags;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
 
   /* Extract the elf_flags if available.  */
@@ -982,15 +982,12 @@  rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	{
 	  tdesc_data = tdesc_data_alloc ();
 	  for (int i = 0; i < RX_NUM_REGS; i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
-                                            rx_register_names[i]);
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
+						rx_register_names[i]);
 	}
 
       if (!valid_p)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
     }
 
   gdb_assert(tdesc_data != NULL);
@@ -1000,7 +997,7 @@  rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->elf_flags = elf_flags;
 
   set_gdbarch_num_regs (gdbarch, RX_NUM_REGS);
-  tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
   set_gdbarch_pc_regnum (gdbarch, RX_PC_REGNUM);
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index 0ee7a372563..2a326e38083 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -7020,8 +7020,8 @@  s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   struct gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc ();
   struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
-  struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();
-  info.tdesc_data = tdesc_data;
+  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
+  info.tdesc_data = tdesc_data.get ();
 
   set_gdbarch_believe_pcc_promotion (gdbarch, 0);
   set_gdbarch_char_signed (gdbarch, 0);
@@ -7147,9 +7147,8 @@  s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->tdesc = tdesc;
 
   /* Check any target description for validity.  */
-  if (!s390_tdesc_valid (tdep, tdesc_data))
+  if (!s390_tdesc_valid (tdep, tdesc_data.get ()))
     {
-      tdesc_data_cleanup (tdesc_data);
       xfree (tdep);
       gdbarch_free (gdbarch);
       return NULL;
@@ -7180,13 +7179,12 @@  s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (tmp->vector_abi != tdep->vector_abi)
 	continue;
 
-      tdesc_data_cleanup (tdesc_data);
       xfree (tdep);
       gdbarch_free (gdbarch);
       return arches->gdbarch;
     }
 
-  tdesc_use_registers (gdbarch, tdep->tdesc, tdesc_data);
+  tdesc_use_registers (gdbarch, tdep->tdesc, std::move (tdesc_data));
   set_gdbarch_register_name (gdbarch, s390_register_name);
 
   /* Assign pseudo register numbers.  */
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 9e00a678a19..7ad43d347a8 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -1892,35 +1892,32 @@  sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   if (tdesc_has_registers (tdesc))
     {
-      struct tdesc_arch_data *tdesc_data = tdesc_data_alloc ();
+      tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
 
       /* Validate that the descriptor provides the mandatory registers
          and allocate their numbers. */
-      valid_p &= validate_tdesc_registers (tdesc, tdesc_data,
+      valid_p &= validate_tdesc_registers (tdesc, tdesc_data.get (),
                                            "org.gnu.gdb.sparc.cpu",
                                            sparc_core_register_names,
                                            ARRAY_SIZE (sparc_core_register_names),
                                            SPARC_G0_REGNUM);
-      valid_p &= validate_tdesc_registers (tdesc, tdesc_data,
+      valid_p &= validate_tdesc_registers (tdesc, tdesc_data.get (),
                                            "org.gnu.gdb.sparc.fpu",
                                            tdep->fpu_register_names,
                                            tdep->fpu_registers_num,
                                            SPARC_F0_REGNUM);
-      valid_p &= validate_tdesc_registers (tdesc, tdesc_data,
+      valid_p &= validate_tdesc_registers (tdesc, tdesc_data.get (),
                                            "org.gnu.gdb.sparc.cp0",
                                            tdep->cp0_register_names,
                                            tdep->cp0_registers_num,
                                            SPARC_F0_REGNUM
                                            + tdep->fpu_registers_num);
       if (!valid_p)
-        {
-          tdesc_data_cleanup (tdesc_data);
-          return NULL;
-        }
+	return NULL;
 
       /* Target description may have changed. */
-      info.tdesc_data = tdesc_data;
-      tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+      info.tdesc_data = tdesc_data.get ();
+      tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
     }
 
   /* If we have register sets, enable the generic core file support.  */
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 20d624c0c65..762ab4b8a6a 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -773,10 +773,10 @@  tdesc_data_init (struct obstack *obstack)
 /* Similar, but for the temporary copy used during architecture
    initialization.  */
 
-struct tdesc_arch_data *
+tdesc_arch_data_up
 tdesc_data_alloc (void)
 {
-  return new tdesc_arch_data ();
+  return tdesc_arch_data_up (new tdesc_arch_data ());
 }
 
 /* Free something allocated by tdesc_data_alloc, if it is not going
@@ -784,10 +784,8 @@  tdesc_data_alloc (void)
    architecture).  */
 
 void
-tdesc_data_cleanup (void *data_untyped)
+tdesc_arch_data_deleter::operator() (struct tdesc_arch_data *data) const
 {
-  struct tdesc_arch_data *data = (struct tdesc_arch_data *) data_untyped;
-
   delete data;
 }
 
@@ -1097,7 +1095,7 @@  set_tdesc_pseudo_register_reggroup_p
 void
 tdesc_use_registers (struct gdbarch *gdbarch,
 		     const struct target_desc *target_desc,
-		     struct tdesc_arch_data *early_data,
+		     tdesc_arch_data_up &&early_data,
 		     tdesc_unknown_register_ftype unk_reg_cb)
 {
   int num_regs = gdbarch_num_regs (gdbarch);
@@ -1112,7 +1110,6 @@  tdesc_use_registers (struct gdbarch *gdbarch,
 
   data = (struct tdesc_arch_data *) gdbarch_data (gdbarch, tdesc_data);
   data->arch_regs = early_data->arch_regs;
-  delete early_data;
 
   /* Build up a set of all registers, so that we can assign register
      numbers where needed.  The hash table expands as necessary, so
diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h
index 66a2c213dc2..171ef76379a 100644
--- a/gdb/target-descriptions.h
+++ b/gdb/target-descriptions.h
@@ -104,6 +104,18 @@  typedef int (*tdesc_unknown_register_ftype)
 	(struct gdbarch *gdbarch, tdesc_feature *feature,
 	 const char *reg_name, int possible_regnum);
 
+/* A deleter adapter for a target arch data.  */
+
+struct tdesc_arch_data_deleter
+{
+  void operator() (struct tdesc_arch_data *data) const;
+};
+
+/* A unique pointer specialization that holds a target_desc.  */
+
+typedef std::unique_ptr<tdesc_arch_data, tdesc_arch_data_deleter>
+  tdesc_arch_data_up;
+
 /* Update GDBARCH to use the TARGET_DESC for registers.  TARGET_DESC
    may be GDBARCH's target description or (if GDBARCH does not have
    one which describes registers) another target description
@@ -119,19 +131,13 @@  typedef int (*tdesc_unknown_register_ftype)
 
 void tdesc_use_registers (struct gdbarch *gdbarch,
 			  const struct target_desc *target_desc,
-			  struct tdesc_arch_data *early_data,
+			  tdesc_arch_data_up &&early_data,
 			  tdesc_unknown_register_ftype unk_reg_cb = NULL);
 
 /* Allocate initial data for validation of a target description during
    gdbarch initialization.  */
 
-struct tdesc_arch_data *tdesc_data_alloc (void);
-
-/* Clean up data allocated by tdesc_data_alloc.  This should only
-   be called to discard the data; tdesc_use_registers takes ownership
-   of its EARLY_DATA argument.  */
-
-void tdesc_data_cleanup (void *data_untyped);
+tdesc_arch_data_up tdesc_data_alloc ();
 
 /* Search FEATURE for a register named NAME.  Record REGNO and the
    register in DATA; when tdesc_use_registers is called, REGNO will be
diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c
index 57945d21db7..b78db89b4e2 100644
--- a/gdb/tic6x-tdep.c
+++ b/gdb/tic6x-tdep.c
@@ -1140,7 +1140,7 @@  tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
-  struct tdesc_arch_data *tdesc_data = NULL;
+  tdesc_arch_data_up tdesc_data;
   const struct target_desc *tdesc = info.target_desc;
   int has_gp = 0;
 
@@ -1159,20 +1159,17 @@  tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
       valid_p = 1;
       for (i = 0; i < 32; i++)	/* A0 - A15, B0 - B15 */
-	valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
 					    tic6x_register_names[i]);
 
       /* CSR */
-      valid_p &= tdesc_numbered_register (feature, tdesc_data, i++,
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i++,
 					  tic6x_register_names[TIC6X_CSR_REGNUM]);
-      valid_p &= tdesc_numbered_register (feature, tdesc_data, i++,
+      valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i++,
 					  tic6x_register_names[TIC6X_PC_REGNUM]);
 
       if (!valid_p)
-	{
-	  tdesc_data_cleanup (tdesc_data);
-	  return NULL;
-	}
+	return NULL;
 
       feature = tdesc_find_feature (tdesc, "org.gnu.gdb.tic6x.gp");
       if (feature)
@@ -1189,28 +1186,25 @@  tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	  has_gp = 1;
 	  valid_p = 1;
 	  for (j = 0; j < 32; j++)	/* A16 - A31, B16 - B31 */
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data, i++,
-						gp[j]);
+	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+						i++, gp[j]);
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	}
 
       feature = tdesc_find_feature (tdesc, "org.gnu.gdb.tic6x.c6xp");
       if (feature)
 	{
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data, i++, "TSR");
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data, i++, "ILC");
-	  valid_p &= tdesc_numbered_register (feature, tdesc_data, i++, "RILC");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+					      i++, "TSR");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+					      i++, "ILC");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+					      i++, "RILC");
 
 	  if (!valid_p)
-	    {
-	      tdesc_data_cleanup (tdesc_data);
-	      return NULL;
-	    }
+	    return NULL;
 	}
 
     }
@@ -1295,8 +1289,8 @@  tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
-  if (tdesc_data)
-    tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+  if (tdesc_data != nullptr)
+    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
 
   return gdbarch;
 }