diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3520eec..23df636 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,16 @@
+2017-03-29  Yao Qi  <yao.qi@linaro.org>
+
+	* gdbthread.h (struct thread_info): Declare constructor and
+	destructor.  Add some in-class member initializers.
+	* thread.c (free_thread): Remove.
+	(init_thread_list): Call delete instead of free_thread.
+	(new_thread): Call thread_info constructor.
+	(thread_info::thread_info): New function.
+	(thread_info::~thread_info): New function.
+	(delete_thread_1): Call delete instead of free_thread.
+	(make_cleanup_restore_current_thread): Move tp and frame to
+	inner block.
+
 2017-03-28  Anton Kolesov  <anton.kolesov@synopsys.com>
 
 	* arc-tdep.c (arc_frame_cache): Add support for prologue analysis.
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 06ed78f..9a16fe6 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -179,7 +179,11 @@ typedef VEC (value_ptr) value_vec;
 
 struct thread_info
 {
-  struct thread_info *next;
+public:
+  explicit thread_info (inferior *inf, ptid_t ptid);
+  ~thread_info ();
+
+  struct thread_info *next = NULL;
   ptid_t ptid;			/* "Actual process id";
 				    In fact, this may be overloaded with 
 				    kernel thread id, etc.  */
@@ -226,13 +230,13 @@ struct thread_info
 
   /* The name of the thread, as specified by the user.  This is NULL
      if the thread does not have a user-given name.  */
-  char *name;
+  char *name = NULL;
 
   /* Non-zero means the thread is executing.  Note: this is different
      from saying that there is an active target and we are stopped at
      a breakpoint, for instance.  This is a real indicator whether the
      thread is off and running.  */
-  int executing;
+  int executing = 0;
 
   /* Non-zero if this thread is resumed from infrun's perspective.
      Note that a thread can be marked both as not-executing and
@@ -241,30 +245,30 @@ struct thread_info
      thread really run until that wait status has been processed, but
      we should not process that wait status if we didn't try to let
      the thread run.  */
-  int resumed;
+  int resumed = 0;
 
   /* Frontend view of the thread state.  Note that the THREAD_RUNNING/
      THREAD_STOPPED states are different from EXECUTING.  When the
      thread is stopped internally while handling an internal event,
      like a software single-step breakpoint, EXECUTING will be false,
      but STATE will still be THREAD_RUNNING.  */
-  enum thread_state state;
+  enum thread_state state = THREAD_STOPPED;
 
   /* If this is > 0, then it means there's code out there that relies
      on this thread being listed.  Don't delete it from the lists even
      if we detect it exiting.  */
-  int refcount;
+  int refcount = 0;
 
   /* State of GDB control of inferior thread execution.
      See `struct thread_control_state'.  */
-  struct thread_control_state control;
+  thread_control_state control {};
 
   /* State of inferior thread to restore after GDB is done with an inferior
      call.  See `struct thread_suspend_state'.  */
-  struct thread_suspend_state suspend;
+  thread_suspend_state suspend {};
 
-  int current_line;
-  struct symtab *current_symtab;
+  int current_line = 0;
+  struct symtab *current_symtab = NULL;
 
   /* Internal stepping state.  */
 
@@ -274,20 +278,20 @@ struct thread_info
      by proceed and keep_going, and among other things, it's used in
      adjust_pc_after_break to distinguish a hardware single-step
      SIGTRAP from a breakpoint SIGTRAP.  */
-  CORE_ADDR prev_pc;
+  CORE_ADDR prev_pc = 0;
 
   /* Did we set the thread stepping a breakpoint instruction?  This is
      used in conjunction with PREV_PC to decide whether to adjust the
      PC.  */
-  int stepped_breakpoint;
+  int stepped_breakpoint = 0;
 
   /* Should we step over breakpoint next time keep_going is called?  */
-  int stepping_over_breakpoint;
+  int stepping_over_breakpoint = 0;
 
   /* Should we step over a watchpoint next time keep_going is called?
      This is needed on targets with non-continuable, non-steppable
      watchpoints.  */
-  int stepping_over_watchpoint;
+  int stepping_over_watchpoint = 0;
 
   /* Set to TRUE if we should finish single-stepping over a breakpoint
      after hitting the current step-resume breakpoint.  The context here
@@ -298,12 +302,12 @@ struct thread_info
      step_after_step_resume_breakpoint is set to TRUE at this moment in
      order to keep GDB in mind that there is still a breakpoint to step over
      when GDB gets back SIGTRAP from step_resume_breakpoint.  */
-  int step_after_step_resume_breakpoint;
+  int step_after_step_resume_breakpoint = 0;
 
   /* Pointer to the state machine manager object that handles what is
      left to do for the thread's execution command after the target
      stops.  Several execution commands use it.  */
-  struct thread_fsm *thread_fsm;
+  struct thread_fsm *thread_fsm = NULL;
 
   /* This is used to remember when a fork or vfork event was caught by
      a catchpoint, and thus the event is to be followed at the next
@@ -311,37 +315,37 @@ struct thread_info
   struct target_waitstatus pending_follow;
 
   /* True if this thread has been explicitly requested to stop.  */
-  int stop_requested;
+  int stop_requested = 0;
 
   /* The initiating frame of a nexting operation, used for deciding
      which exceptions to intercept.  If it is null_frame_id no
      bp_longjmp or bp_exception but longjmp has been caught just for
      bp_longjmp_call_dummy.  */
-  struct frame_id initiating_frame;
+  struct frame_id initiating_frame = null_frame_id;
 
   /* Private data used by the target vector implementation.  */
-  struct private_thread_info *priv;
+  struct private_thread_info *priv = NULL;
 
   /* Function that is called to free PRIVATE.  If this is NULL, then
      xfree will be called on PRIVATE.  */
-  void (*private_dtor) (struct private_thread_info *);
+  void (*private_dtor) (struct private_thread_info *) = NULL;
 
   /* Branch trace information for this thread.  */
-  struct btrace_thread_info btrace;
+  struct btrace_thread_info btrace {};
 
   /* Flag which indicates that the stack temporaries should be stored while
      evaluating expressions.  */
-  int stack_temporaries_enabled;
+  int stack_temporaries_enabled = 0;
 
   /* Values that are stored as temporaries on stack while evaluating
      expressions.  */
-  value_vec *stack_temporaries;
+  value_vec *stack_temporaries = NULL;
 
   /* Step-over chain.  A thread is in the step-over queue if these are
      non-NULL.  If only a single thread is in the chain, then these
      fields point to self.  */
-  struct thread_info *step_over_prev;
-  struct thread_info *step_over_next;
+  struct thread_info *step_over_prev = NULL;
+  struct thread_info *step_over_next = NULL;
 };
 
 /* Create an empty thread list, or empty the existing one.  */
diff --git a/gdb/thread.c b/gdb/thread.c
index 99fe424..fd9022f 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -192,21 +192,6 @@ clear_thread_inferior_resources (struct thread_info *tp)
   thread_cancel_execution_command (tp);
 }
 
-static void
-free_thread (struct thread_info *tp)
-{
-  if (tp->priv)
-    {
-      if (tp->private_dtor)
-	tp->private_dtor (tp->priv);
-      else
-	xfree (tp->priv);
-    }
-
-  xfree (tp->name);
-  xfree (tp);
-}
-
 void
 init_thread_list (void)
 {
@@ -220,7 +205,7 @@ init_thread_list (void)
   for (tp = thread_list; tp; tp = tpnext)
     {
       tpnext = tp->next;
-      free_thread (tp);
+      delete tp;
     }
 
   thread_list = NULL;
@@ -233,16 +218,7 @@ init_thread_list (void)
 static struct thread_info *
 new_thread (struct inferior *inf, ptid_t ptid)
 {
-  struct thread_info *tp;
-
-  gdb_assert (inf != NULL);
-
-  tp = XCNEW (struct thread_info);
-
-  tp->ptid = ptid;
-  tp->global_num = ++highest_thread_num;
-  tp->inf = inf;
-  tp->per_inf_num = ++inf->highest_thread_num;
+  thread_info *tp = new thread_info (inf, ptid);
 
   if (thread_list == NULL)
     thread_list = tp;
@@ -255,11 +231,6 @@ new_thread (struct inferior *inf, ptid_t ptid)
       last->next = tp;
     }
 
-  /* Nothing to follow yet.  */
-  tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
-  tp->state = THREAD_STOPPED;
-  tp->suspend.waitstatus.kind = TARGET_WAITKIND_IGNORE;
-
   return tp;
 }
 
@@ -336,6 +307,33 @@ add_thread (ptid_t ptid)
   return add_thread_with_info (ptid, NULL);
 }
 
+thread_info::thread_info (struct inferior *inf_, ptid_t ptid_)
+  : ptid (ptid_), inf (inf_)
+{
+  gdb_assert (inf_ != NULL);
+
+  this->global_num = ++highest_thread_num;
+  this->per_inf_num = ++inf_->highest_thread_num;
+
+  /* Nothing to follow yet.  */
+  memset (&this->pending_follow, 0, sizeof (this->pending_follow));
+  this->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
+  this->suspend.waitstatus.kind = TARGET_WAITKIND_IGNORE;
+}
+
+thread_info::~thread_info ()
+{
+  if (this->priv)
+    {
+      if (this->private_dtor)
+	this->private_dtor (this->priv);
+      else
+	xfree (this->priv);
+    }
+
+  xfree (this->name);
+}
+
 /* Add TP to the end of the step-over chain LIST_P.  */
 
 static void
@@ -470,7 +468,7 @@ delete_thread_1 (ptid_t ptid, int silent)
   else
     thread_list = tp->next;
 
-  free_thread (tp);
+  delete tp;
 }
 
 /* Delete thread PTID and notify of thread exit.  If this is
@@ -1655,8 +1653,6 @@ set_thread_refcount (void *data)
 struct cleanup *
 make_cleanup_restore_current_thread (void)
 {
-  struct thread_info *tp;
-  struct frame_info *frame;
   struct current_thread_cleanup *old = XNEW (struct current_thread_cleanup);
 
   old->inferior_ptid = inferior_ptid;
@@ -1668,6 +1664,8 @@ make_cleanup_restore_current_thread (void)
 
   if (!ptid_equal (inferior_ptid, null_ptid))
     {
+      struct frame_info *frame;
+
       old->was_stopped = is_stopped (inferior_ptid);
       if (old->was_stopped
 	  && target_has_registers
@@ -1687,7 +1685,8 @@ make_cleanup_restore_current_thread (void)
       old->selected_frame_id = get_frame_id (frame);
       old->selected_frame_level = frame_relative_level (frame);
 
-      tp = find_thread_ptid (inferior_ptid);
+      struct thread_info *tp = find_thread_ptid (inferior_ptid);
+
       if (tp)
 	tp->refcount++;
     }
