diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 87bfeb9..4a56a1e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,18 @@
 2017-04-07  Tom Tromey  <tom@tromey.com>
 
+	* mi/mi-main.c (exec_direction_forward): Remove.
+	(exec_reverse_continue, mi_execute_command): Use scoped_restore.
+	* guile/scm-ports.c (ioscm_with_output_to_port_worker): Use
+	scoped_restore.
+	* guile/guile.c (guile_repl_command, guile_command)
+	(gdbscm_execute_gdb_command): Use scoped_restore.
+	* go-exp.y (go_parse): Use scoped_restore.
+	* d-exp.y (d_parse): Use scoped_restore.
+	* cli/cli-decode.c (cmd_func): Use scoped_restore.
+	* c-exp.y (c_parse): Use scoped_restore.
+
+2017-04-07  Tom Tromey  <tom@tromey.com>
+
 	* mi/mi-parse.h (struct mi_parse): Add constructor, destructor.
 	(mi_parse): Update return type..
 	(mi_parse_free): Remove.
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index b2fc195..283b737 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -3188,8 +3188,8 @@ c_parse (struct parser_state *par_state)
   gdb_assert (! macro_original_text);
   make_cleanup (scan_macro_cleanup, 0);
 
-  make_cleanup_restore_integer (&yydebug);
-  yydebug = parser_debug;
+  scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
+							parser_debug);
 
   /* Initialize some state used by the lexer.  */
   last_was_structop = 0;
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index fc14465..29a2e04 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -1878,17 +1878,14 @@ cmd_func (struct cmd_list_element *cmd, char *args, int from_tty)
 {
   if (cmd_func_p (cmd))
     {
-      struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
-
-      if (cmd->suppress_notification != NULL)
-	{
-	  make_cleanup_restore_integer (cmd->suppress_notification);
-	  *cmd->suppress_notification = 1;
-	}
+      int dummy = 0;
+      scoped_restore restore_suppress
+	= make_scoped_restore (cmd->suppress_notification
+			       ? cmd->suppress_notification
+			       : &dummy,
+			       1);
 
       (*cmd->func) (cmd, args, from_tty);
-
-      do_cleanups (cleanups);
     }
   else
     error (_("Invalid command"));
diff --git a/gdb/d-exp.y b/gdb/d-exp.y
index 06eef5f..62df737 100644
--- a/gdb/d-exp.y
+++ b/gdb/d-exp.y
@@ -1629,9 +1629,9 @@ d_parse (struct parser_state *par_state)
 
   back_to = make_cleanup (null_cleanup, NULL);
 
-  make_cleanup_restore_integer (&yydebug);
+  scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
+							parser_debug);
   make_cleanup_clear_parser_state (&pstate);
-  yydebug = parser_debug;
 
   /* Initialize some state used by the lexer.  */
   last_was_structop = 0;
diff --git a/gdb/go-exp.y b/gdb/go-exp.y
index 1906e68..057e227 100644
--- a/gdb/go-exp.y
+++ b/gdb/go-exp.y
@@ -1569,9 +1569,9 @@ go_parse (struct parser_state *par_state)
 
   back_to = make_cleanup (null_cleanup, NULL);
 
-  make_cleanup_restore_integer (&yydebug);
+  scoped_restore restore_yydebug = make_scoped_restore (&yydebug,
+							parser_debug);
   make_cleanup_clear_parser_state (&pstate);
-  yydebug = parser_debug;
 
   /* Initialize some state used by the lexer.  */
   last_was_structop = 0;
diff --git a/gdb/guile/guile.c b/gdb/guile/guile.c
index 9bb2487..0dadc3c 100644
--- a/gdb/guile/guile.c
+++ b/gdb/guile/guile.c
@@ -163,10 +163,7 @@ const struct extension_language_ops guile_extension_ops =
 static void
 guile_repl_command (char *arg, int from_tty)
 {
-  struct cleanup *cleanup;
-
-  cleanup = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore restore_async = make_scoped_restore (&current_ui->async, 0);
 
   arg = skip_spaces (arg);
 
@@ -183,8 +180,6 @@ guile_repl_command (char *arg, int from_tty)
       dont_repeat ();
       gdbscm_enter_repl ();
     }
-
-  do_cleanups (cleanup);
 }
 
 /* Implementation of the gdb "guile" command.
@@ -196,10 +191,7 @@ guile_repl_command (char *arg, int from_tty)
 static void
 guile_command (char *arg, int from_tty)
 {
-  struct cleanup *cleanup;
-
-  cleanup = make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore restore_async = make_scoped_restore (&current_ui->async, 0);
 
   arg = skip_spaces (arg);
 
@@ -209,6 +201,8 @@ guile_command (char *arg, int from_tty)
 
       if (msg != NULL)
 	{
+	  /* It is ok that this is a "dangling cleanup" because we
+	     throw immediately.  */
 	  make_cleanup (xfree, msg);
 	  error ("%s", msg);
 	}
@@ -219,8 +213,6 @@ guile_command (char *arg, int from_tty)
 
       execute_control_command_untraced (l.get ());
     }
-
-  do_cleanups (cleanup);
 }
 
 /* Given a command_line, return a command string suitable for passing
@@ -326,10 +318,8 @@ gdbscm_execute_gdb_command (SCM command_scm, SCM rest)
 
   TRY
     {
-      struct cleanup *inner_cleanups;
-
-      inner_cleanups = make_cleanup_restore_integer (&current_ui->async);
-      current_ui->async = 0;
+      scoped_restore restore_async = make_scoped_restore (&current_ui->async,
+							  0);
 
       scoped_restore preventer = prevent_dont_repeat ();
       if (to_string)
@@ -339,8 +329,6 @@ gdbscm_execute_gdb_command (SCM command_scm, SCM rest)
 
       /* Do any commands attached to breakpoint we stopped at.  */
       bpstat_do_actions ();
-
-      do_cleanups (inner_cleanups);
     }
   CATCH (ex, RETURN_MASK_ALL)
     {
diff --git a/gdb/guile/scm-ports.c b/gdb/guile/scm-ports.c
index fb3a47b..735abc2 100644
--- a/gdb/guile/scm-ports.c
+++ b/gdb/guile/scm-ports.c
@@ -470,8 +470,7 @@ ioscm_with_output_to_port_worker (SCM port, SCM thunk, enum oport oport,
 
   cleanups = set_batch_flag_and_make_cleanup_restore_page_info ();
 
-  make_cleanup_restore_integer (&current_ui->async);
-  current_ui->async = 0;
+  scoped_restore restore_async = make_scoped_restore (&current_ui->async, 0);
 
   ui_file_up port_file (new ioscm_file_port (port));
 
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index d99c40e..3d61de1 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -312,16 +312,9 @@ exec_continue (char **argv, int argc)
 }
 
 static void
-exec_direction_forward (void *notused)
-{
-  execution_direction = EXEC_FORWARD;
-}
-
-static void
 exec_reverse_continue (char **argv, int argc)
 {
   enum exec_direction_kind dir = execution_direction;
-  struct cleanup *old_chain;
 
   if (dir == EXEC_REVERSE)
     error (_("Already in reverse mode."));
@@ -329,10 +322,9 @@ exec_reverse_continue (char **argv, int argc)
   if (!target_can_execute_reverse)
     error (_("Target %s does not support this command."), target_shortname);
 
-  old_chain = make_cleanup (exec_direction_forward, NULL);
-  execution_direction = EXEC_REVERSE;
+  scoped_restore save_exec_dir = make_scoped_restore (&execution_direction,
+						      EXEC_REVERSE);
   exec_continue (argv, argc);
-  do_cleanups (old_chain);
 }
 
 void
@@ -2140,15 +2132,16 @@ mi_execute_command (const char *cmd, int from_tty)
   if (command != NULL)
     {
       ptid_t previous_ptid = inferior_ptid;
-      struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
 
-      command->token = token;
+      int dummy = 0;
+      scoped_restore restore_suppress
+	= make_scoped_restore ((command->cmd != NULL
+				&& command->cmd->suppress_notification != NULL)
+			       ? command->cmd->suppress_notification
+			       : &dummy,
+			       1);
 
-      if (command->cmd != NULL && command->cmd->suppress_notification != NULL)
-        {
-          make_cleanup_restore_integer (command->cmd->suppress_notification);
-          *command->cmd->suppress_notification = 1;
-        }
+      command->token = token;
 
       if (do_timings)
 	{
@@ -2210,8 +2203,6 @@ mi_execute_command (const char *cmd, int from_tty)
 		  (USER_SELECTED_THREAD | USER_SELECTED_FRAME);
 	    }
 	}
-
-      do_cleanups (cleanup);
     }
 }
 
