diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f7aefaa..7fa5099 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,34 @@
 2017-04-11  Tom Tromey  <tom@tromey.com>
 
+	* tracepoint.c (actions_command): Update.
+	* python/python.c (python_command, python_interactive_command):
+	Update.
+	* mi/mi-cmd-break.c (mi_cmd_break_commands): Update.
+	* guile/guile.c (guile_command): Update.
+	* defs.h (read_command_lines, read_command_lines_1): Return
+	command_line_up.
+	(command_lines_deleter): New struct.
+	(command_line_up): New typedef.
+	* compile/compile.c (compile_code_command)
+	(compile_print_command): Update.
+	* cli/cli-script.h (get_command_line, copy_command_lines): Return
+	command_line_up.
+	(make_cleanup_free_command_lines): Remove.
+	* cli/cli-script.c (get_command_line, read_command_lines_1)
+	(copy_command_lines): Return command_line_up.
+	(while_command, if_command, read_command_lines, define_command)
+	(document_command): Update.
+	(do_free_command_lines_cleanup, make_cleanup_free_command_lines):
+	Remove.
+	* breakpoint.h (breakpoint_set_commands): Change type of
+	"commands".
+	* breakpoint.c (breakpoint_set_commands): Change type of
+	"commands".  Update.
+	(do_map_commands_command, update_dprintf_command_list)
+	(create_tracepoint_from_upload): Update.
+
+2017-04-11  Tom Tromey  <tom@tromey.com>
+
 	* tracepoint.c (scope_info): Update.
 	* spu-tdep.c (spu_catch_start): Update.
 	* python/python.c (gdbpy_decode_line): Update.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 9f7db91..3a3cd80 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -1271,12 +1271,12 @@ static_tracepoints_here (CORE_ADDR addr)
 
 void
 breakpoint_set_commands (struct breakpoint *b, 
-			 struct command_line *commands)
+			 command_line_up &&commands)
 {
-  validate_commands_for_breakpoint (b, commands);
+  validate_commands_for_breakpoint (b, commands.get ());
 
   decref_counted_command_line (&b->commands);
-  b->commands = alloc_counted_command_line (commands);
+  b->commands = alloc_counted_command_line (commands.release ());
   observer_notify_breakpoint_modified (b);
 }
 
@@ -1358,7 +1358,7 @@ do_map_commands_command (struct breakpoint *b, void *data)
 
   if (info->cmd == NULL)
     {
-      struct command_line *l;
+      command_line_up l;
 
       if (info->control != NULL)
 	l = copy_command_lines (info->control->body_list[0]);
@@ -1382,7 +1382,7 @@ do_map_commands_command (struct breakpoint *b, void *data)
 	  do_cleanups (old_chain);
 	}
 
-      info->cmd = alloc_counted_command_line (l);
+      info->cmd = alloc_counted_command_line (l.release ());
     }
 
   /* If a breakpoint was on the list more than once, we don't need to
@@ -9191,7 +9191,7 @@ update_dprintf_command_list (struct breakpoint *b)
     printf_cmd_line->next = NULL;
     printf_cmd_line->line = printf_line;
 
-    breakpoint_set_commands (b, printf_cmd_line);
+    breakpoint_set_commands (b, command_line_up (printf_cmd_line));
   }
 }
 
@@ -15356,14 +15356,14 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
      function.  */
   if (!VEC_empty (char_ptr, utp->cmd_strings))
     {
-      struct command_line *cmd_list;
+      command_line_up cmd_list;
 
       this_utp = utp;
       next_cmd = 0;
 
       cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
 
-      breakpoint_set_commands (&tp->base, cmd_list);
+      breakpoint_set_commands (&tp->base, std::move (cmd_list));
     }
   else if (!VEC_empty (char_ptr, utp->actions)
 	   || !VEC_empty (char_ptr, utp->step_actions))
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index a7f2128..1301fb4 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -1475,7 +1475,7 @@ extern void disable_breakpoint (struct breakpoint *);
 extern void enable_breakpoint (struct breakpoint *);
 
 extern void breakpoint_set_commands (struct breakpoint *b, 
-				     struct command_line *commands);
+				     command_line_up &&commands);
 
 extern void breakpoint_set_silent (struct breakpoint *b, int silent);
 
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 33b657d..e0e27ef 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -165,27 +165,20 @@ build_command_line (enum command_control_type type, const char *args)
 /* Build and return a new command structure for the control commands
    such as "if" and "while".  */
 
-struct command_line *
+command_line_up
 get_command_line (enum command_control_type type, const char *arg)
 {
-  struct command_line *cmd;
-  struct cleanup *old_chain = NULL;
-
   /* Allocate and build a new command line structure.  */
-  cmd = build_command_line (type, arg);
-
-  old_chain = make_cleanup_free_command_lines (&cmd);
+  command_line_up cmd (build_command_line (type, arg));
 
   /* Read in the body of this command.  */
-  if (recurse_read_control_structure (read_next_line, cmd, 0, 0)
+  if (recurse_read_control_structure (read_next_line, cmd.get (), 0, 0)
       == invalid_control)
     {
       warning (_("Error reading in canned sequence of commands."));
-      do_cleanups (old_chain);
       return NULL;
     }
 
-  discard_cleanups (old_chain);
   return cmd;
 }
 
@@ -677,18 +670,15 @@ execute_control_command_untraced (struct command_line *cmd)
 static void
 while_command (char *arg, int from_tty)
 {
-  struct command_line *command = NULL;
-
   control_level = 1;
-  command = get_command_line (while_control, arg);
+  command_line_up command = get_command_line (while_control, arg);
 
   if (command == NULL)
     return;
 
   scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
-  execute_control_command_untraced (command);
-  free_command_lines (&command);
+  execute_control_command_untraced (command.get ());
 }
 
 /* "if" command support.  Execute either the true or false arm depending
@@ -697,19 +687,15 @@ while_command (char *arg, int from_tty)
 static void
 if_command (char *arg, int from_tty)
 {
-  struct command_line *command = NULL;
-  struct cleanup *old_chain;
-
   control_level = 1;
-  command = get_command_line (if_control, arg);
+  command_line_up command = get_command_line (if_control, arg);
 
   if (command == NULL)
     return;
 
   scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
 
-  execute_control_command_untraced (command);
-  free_command_lines (&command);
+  execute_control_command_untraced (command.get ());
 }
 
 /* Bind the incoming arguments for a user defined command to $arg0,
@@ -1208,12 +1194,10 @@ restore_interp (void *arg)
 
 #define END_MESSAGE "End with a line saying just \"end\"."
 
-struct command_line *
+command_line_up
 read_command_lines (char *prompt_arg, int from_tty, int parse_commands,
 		    void (*validator)(char *, void *), void *closure)
 {
-  struct command_line *head;
-
   if (from_tty && input_interactive_p (current_ui))
     {
       if (deprecated_readline_begin_hook)
@@ -1232,6 +1216,7 @@ read_command_lines (char *prompt_arg, int from_tty, int parse_commands,
 
   /* Reading commands assumes the CLI behavior, so temporarily
      override the current interpreter with CLI.  */
+  command_line_up head;
   if (current_interp_named_p (INTERP_CONSOLE))
     head = read_command_lines_1 (read_next_line, parse_commands,
 				 validator, closure);
@@ -1256,17 +1241,17 @@ read_command_lines (char *prompt_arg, int from_tty, int parse_commands,
 /* Act the same way as read_command_lines, except that each new line is
    obtained using READ_NEXT_LINE_FUNC.  */
 
-struct command_line *
+command_line_up
 read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands,
 		      void (*validator)(char *, void *), void *closure)
 {
-  struct command_line *head, *tail, *next;
-  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+  struct command_line *tail, *next;
+  command_line_up head;
   enum command_control_type ret;
   enum misc_command_type val;
 
   control_level = 0;
-  head = tail = NULL;
+  tail = NULL;
 
   while (1)
     {
@@ -1307,18 +1292,15 @@ read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands,
 	}
       else
 	{
-	  head = next;
-	  make_cleanup_free_command_lines (&head);
+	  head.reset (next);
 	}
       tail = next;
     }
 
   dont_repeat ();
 
-  if (ret != invalid_control)
-    discard_cleanups (old_chain);
-  else
-    do_cleanups (old_chain);
+  if (ret == invalid_control)
+    return NULL;
 
   return head;
 }
@@ -1349,19 +1331,7 @@ free_command_lines (struct command_line **lptr)
   *lptr = NULL;
 }
 
-static void
-do_free_command_lines_cleanup (void *arg)
-{
-  free_command_lines ((struct command_line **) arg);
-}
-
-struct cleanup *
-make_cleanup_free_command_lines (struct command_line **arg)
-{
-  return make_cleanup (do_free_command_lines_cleanup, arg);
-}
-
-struct command_line *
+command_line_up
 copy_command_lines (struct command_line *cmds)
 {
   struct command_line *result = NULL;
@@ -1370,7 +1340,7 @@ copy_command_lines (struct command_line *cmds)
     {
       result = XNEW (struct command_line);
 
-      result->next = copy_command_lines (cmds->next);
+      result->next = copy_command_lines (cmds->next).release ();
       result->line = xstrdup (cmds->line);
       result->control_type = cmds->control_type;
       result->body_count = cmds->body_count;
@@ -1381,13 +1351,14 @@ copy_command_lines (struct command_line *cmds)
           result->body_list = XNEWVEC (struct command_line *, cmds->body_count);
 
           for (i = 0; i < cmds->body_count; i++)
-            result->body_list[i] = copy_command_lines (cmds->body_list[i]);
+            result->body_list[i]
+	      = copy_command_lines (cmds->body_list[i]).release ();
         }
       else
         result->body_list = NULL;
     }
 
-  return result;
+  return command_line_up (result);
 }
 
 /* Validate that *COMNAME is a valid name for a command.  Return the
@@ -1460,7 +1431,6 @@ define_command (char *comname, int from_tty)
       CMD_PRE_HOOK,
       CMD_POST_HOOK
     };
-  struct command_line *cmds;
   struct cmd_list_element *c, *newc, *hookc = 0, **list;
   char *tem, *comfull;
   const char *tem_c;
@@ -1536,7 +1506,7 @@ define_command (char *comname, int from_tty)
 
   xsnprintf (tmpbuf, sizeof (tmpbuf),
 	     "Type commands for definition of \"%s\".", comfull);
-  cmds = read_command_lines (tmpbuf, from_tty, 1, 0, 0);
+  command_line_up cmds = read_command_lines (tmpbuf, from_tty, 1, 0, 0);
 
   if (c && c->theclass == class_user)
     free_command_lines (&c->user_commands);
@@ -1544,7 +1514,7 @@ define_command (char *comname, int from_tty)
   newc = add_cmd (comname, class_user, user_defined_command,
 		  (c && c->theclass == class_user)
 		  ? c->doc : xstrdup ("User-defined."), list);
-  newc->user_commands = cmds;
+  newc->user_commands = cmds.release ();
 
   /* If this new command is a hook, then mark both commands as being
      tied.  */
@@ -1571,7 +1541,6 @@ define_command (char *comname, int from_tty)
 static void
 document_command (char *comname, int from_tty)
 {
-  struct command_line *doclines;
   struct cmd_list_element *c, **list;
   const char *tem;
   char *comfull;
@@ -1588,7 +1557,7 @@ document_command (char *comname, int from_tty)
 
   xsnprintf (tmpbuf, sizeof (tmpbuf), "Type documentation for \"%s\".",
 	     comfull);
-  doclines = read_command_lines (tmpbuf, from_tty, 0, 0, 0);
+  command_line_up doclines = read_command_lines (tmpbuf, from_tty, 0, 0, 0);
 
   if (c->doc)
     xfree ((char *) c->doc);
@@ -1598,13 +1567,13 @@ document_command (char *comname, int from_tty)
     int len = 0;
     char *doc;
 
-    for (cl1 = doclines; cl1; cl1 = cl1->next)
+    for (cl1 = doclines.get (); cl1; cl1 = cl1->next)
       len += strlen (cl1->line) + 1;
 
     doc = (char *) xmalloc (len + 1);
     *doc = 0;
 
-    for (cl1 = doclines; cl1; cl1 = cl1->next)
+    for (cl1 = doclines.get (); cl1; cl1 = cl1->next)
       {
 	strcat (doc, cl1->line);
 	if (cl1->next)
@@ -1613,8 +1582,6 @@ document_command (char *comname, int from_tty)
 
     c->doc = doc;
   }
-
-  free_command_lines (&doclines);
 }
 
 struct source_cleanup_lines_args
diff --git a/gdb/cli/cli-script.h b/gdb/cli/cli-script.h
index c885976..9514938 100644
--- a/gdb/cli/cli-script.h
+++ b/gdb/cli/cli-script.h
@@ -38,16 +38,13 @@ extern enum command_control_type
 extern enum command_control_type
 	execute_control_command_untraced (struct command_line *cmd);
 
-extern struct command_line *get_command_line (enum command_control_type,
-					      const char *);
+extern command_line_up get_command_line (enum command_control_type,
+					 const char *);
 
 extern void print_command_lines (struct ui_out *,
 				 struct command_line *, unsigned int);
 
-extern struct command_line * copy_command_lines (struct command_line *cmds);
-
-extern struct cleanup *
-  make_cleanup_free_command_lines (struct command_line **arg);
+extern command_line_up copy_command_lines (struct command_line *cmds);
 
 /* Exported to gdb/infrun.c */
 
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index b525f61..1771692 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -151,12 +151,10 @@ compile_code_command (char *arg, int from_tty)
     eval_compile_command (NULL, arg, scope, NULL);
   else
     {
-      struct command_line *l = get_command_line (compile_control, "");
-      struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
+      command_line_up l = get_command_line (compile_control, "");
 
       l->control_u.compile.scope = scope;
-      execute_control_command_untraced (l);
-      do_cleanups (cleanup);
+      execute_control_command_untraced (l.get ());
     }
 }
 
@@ -192,13 +190,11 @@ compile_print_command (char *arg_param, int from_tty)
     eval_compile_command (NULL, arg, scope, &fmt);
   else
     {
-      struct command_line *l = get_command_line (compile_control, "");
-      struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
+      command_line_up l = get_command_line (compile_control, "");
 
       l->control_u.compile.scope = scope;
       l->control_u.compile.scope_data = &fmt;
-      execute_control_command_untraced (l);
-      do_cleanups (cleanup);
+      execute_control_command_untraced (l.get ());
     }
 }
 
diff --git a/gdb/defs.h b/gdb/defs.h
index f689ec5..a0b586f 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -445,15 +445,29 @@ struct command_line
     struct command_line **body_list;
   };
 
-extern struct command_line *read_command_lines (char *, int, int,
-						void (*)(char *, void *),
-						void *);
-extern struct command_line *read_command_lines_1 (char * (*) (void), int,
-						  void (*)(char *, void *),
-						  void *);
-
 extern void free_command_lines (struct command_line **);
 
+/* A deleter for command_line that calls free_command_lines.  */
+
+struct command_lines_deleter
+{
+  void operator() (command_line *lines) const
+  {
+    free_command_lines (&lines);
+  }
+};
+
+/* A unique pointer to a command_line.  */
+
+typedef std::unique_ptr<command_line, command_lines_deleter> command_line_up;
+
+extern command_line_up read_command_lines (char *, int, int,
+					   void (*)(char *, void *),
+					   void *);
+extern command_line_up read_command_lines_1 (char * (*) (void), int,
+					     void (*)(char *, void *),
+					     void *);
+
 /* * Parameters of the "info proc" command.  */
 
 enum info_proc_what
diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c
index 27c0a58..9bb2487 100644
--- a/gdb/guile/guile.c
+++ b/gdb/guile/guile.c
@@ -215,10 +215,9 @@ guile_command (char *arg, int from_tty)
     }
   else
     {
-      struct command_line *l = get_command_line (guile_control, "");
+      command_line_up l = get_command_line (guile_control, "");
 
-      make_cleanup_free_command_lines (&l);
-      execute_control_command_untraced (l);
+      execute_control_command_untraced (l.get ());
     }
 
   do_cleanups (cleanup);
@@ -421,11 +420,9 @@ guile_command (char *arg, int from_tty)
     {
       /* Even if Guile isn't enabled, we still have to slurp the
 	 command list to the corresponding "end".  */
-      struct command_line *l = get_command_line (guile_control, "");
-      struct cleanup *cleanups = make_cleanup_free_command_lines (&l);
+      command_line_up l = get_command_line (guile_control, "");
 
-      execute_control_command_untraced (l);
-      do_cleanups (cleanups);
+      execute_control_command_untraced (l.get ());
     }
 }
 
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c
index 0780f7b..cfe2d34 100644
--- a/gdb/mi/mi-cmd-break.c
+++ b/gdb/mi/mi-cmd-break.c
@@ -493,7 +493,7 @@ mi_read_next_line (void)
 void
 mi_cmd_break_commands (const char *command, char **argv, int argc)
 {
-  struct command_line *break_command;
+  command_line_up break_command;
   char *endptr;
   int bnum;
   struct breakpoint *b;
@@ -523,6 +523,6 @@ mi_cmd_break_commands (const char *command, char **argv, int argc)
   else
     break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
 
-  breakpoint_set_commands (b, break_command);
+  breakpoint_set_commands (b, std::move (break_command));
 }
 
diff --git a/gdb/python/python.c b/gdb/python/python.c
index ec202de..7e0c507 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -433,11 +433,9 @@ python_command (char *arg, int from_tty)
     }
   else
     {
-      struct command_line *l = get_command_line (python_control, "");
-      struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
+      command_line_up l = get_command_line (python_control, "");
 
-      execute_control_command_untraced (l);
-      do_cleanups (cleanup);
+      execute_control_command_untraced (l.get ());
     }
 }
 
@@ -1452,11 +1450,9 @@ python_interactive_command (char *arg, int from_tty)
     error (_("Python scripting is not supported in this copy of GDB."));
   else
     {
-      struct command_line *l = get_command_line (python_control, "");
-      struct cleanup *cleanups = make_cleanup_free_command_lines (&l);
+      command_line_up l = get_command_line (python_control, "");
 
-      execute_control_command_untraced (l);
-      do_cleanups (cleanups);
+      execute_control_command_untraced (l.get ());
     }
 }
 
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index dac1657..c947c95 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -647,20 +647,17 @@ static void
 actions_command (char *args, int from_tty)
 {
   struct tracepoint *t;
-  struct command_line *l;
 
   t = get_tracepoint_by_number (&args, NULL);
   if (t)
     {
-      char *tmpbuf =
-	xstrprintf ("Enter actions for tracepoint %d, one per line.",
-		    t->base.number);
-      struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
-
-      l = read_command_lines (tmpbuf, from_tty, 1,
-			      check_tracepoint_command, t);
-      do_cleanups (cleanups);
-      breakpoint_set_commands (&t->base, l);
+      std::string tmpbuf =
+	string_printf ("Enter actions for tracepoint %d, one per line.",
+		       t->base.number);
+
+      command_line_up l = read_command_lines (&tmpbuf[0], from_tty, 1,
+					      check_tracepoint_command, t);
+      breakpoint_set_commands (&t->base, std::move (l));
     }
   /* else just return */
 }
