Mark move constructors as "noexcept"

Message ID 20200410153801.14613-1-tromey@adacore.com
State New
Headers show
Series
  • Mark move constructors as "noexcept"
Related show

Commit Message

Tom Tromey April 10, 2020, 3:38 p.m.
I recently learned that move constructors generally should be marked
"noexcept".  This ensures that standard containers will move objects
when possible, rather than copy them.

This patch fixes the cases I could find.  Note that implicitly-defined
or defaulted move constructors will automatically do what you'd
expect; that is, they are noexcept if all the members have noexcept
move constructors.

While doing this, I noticed a couple of odd cases where the move
constructor seemed to assume that the object being constructed could
have state requiring destruction.  I've fixed these as well.  See
completion_result and scoped_mmap.

gdb/ChangeLog
2020-04-10  Tom Tromey  <tromey@adacore.com>

	* python/python.c (struct gdbpy_event): Mark move constructor as
	noexcept.
	* python/py-tui.c (class gdbpy_tui_window_maker): Mark move
	constructor as noexcept.
	* completer.h (struct completion_result): Mark move constructor as
	noexcept.
	* completer.c (completion_result::completion_result): Use
	initialization style.  Don't call reset_match_list.

gdbsupport/ChangeLog
2020-04-10  Tom Tromey  <tromey@adacore.com>

	* scoped_mmap.h (scoped_mmap): Mark move constructor as noexcept.
	Use initialization style.  Don't call destroy.
	* scoped_fd.h (class scoped_fd): Mark move constructor as
	noexcept.
	* gdb_ref_ptr.h (class ref_ptr): Mark move constructor as
	noexcept.
---
 gdb/ChangeLog            | 11 +++++++++++
 gdb/completer.c          | 10 +++-------
 gdb/completer.h          |  2 +-
 gdb/python/py-tui.c      |  2 +-
 gdb/python/python.c      |  2 +-
 gdbsupport/ChangeLog     |  9 +++++++++
 gdbsupport/gdb_ref_ptr.h |  2 +-
 gdbsupport/scoped_fd.h   |  2 +-
 gdbsupport/scoped_mmap.h |  9 +++------
 9 files changed, 31 insertions(+), 18 deletions(-)

-- 
2.21.1

Comments

Tom Tromey April 20, 2020, 5:44 p.m. | #1
>>>>> "Tom" == Tom Tromey <tromey@adacore.com> writes:


Tom> I recently learned that move constructors generally should be marked
Tom> "noexcept".  This ensures that standard containers will move objects
Tom> when possible, rather than copy them.

Tom> This patch fixes the cases I could find.  Note that implicitly-defined
Tom> or defaulted move constructors will automatically do what you'd
Tom> expect; that is, they are noexcept if all the members have noexcept
Tom> move constructors.

Tom> While doing this, I noticed a couple of odd cases where the move
Tom> constructor seemed to assume that the object being constructed could
Tom> have state requiring destruction.  I've fixed these as well.  See
Tom> completion_result and scoped_mmap.

I'm checking this in.

Tom

Patch

diff --git a/gdb/completer.c b/gdb/completer.c
index 67dce30fbe3..3bbcc978713 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -2311,15 +2311,11 @@  completion_result::~completion_result ()
 
 /* See completer.h  */
 
-completion_result::completion_result (completion_result &&rhs)
+completion_result::completion_result (completion_result &&rhs) noexcept
+  : match_list (rhs.match_list),
+    number_matches (rhs.number_matches)
 {
-  if (this == &rhs)
-    return;
-
-  reset_match_list ();
-  match_list = rhs.match_list;
   rhs.match_list = NULL;
-  number_matches = rhs.number_matches;
   rhs.number_matches = 0;
 }
 
diff --git a/gdb/completer.h b/gdb/completer.h
index fd0d47b206b..d3afa5fe3ec 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -242,7 +242,7 @@  struct completion_result
   DISABLE_COPY_AND_ASSIGN (completion_result);
 
   /* Move a result.  */
-  completion_result (completion_result &&rhs);
+  completion_result (completion_result &&rhs) noexcept;
 
   /* Release ownership of the match list array.  */
   char **release_match_list ();
diff --git a/gdb/python/py-tui.c b/gdb/python/py-tui.c
index de7c396be9f..ca88f85eb9f 100644
--- a/gdb/python/py-tui.c
+++ b/gdb/python/py-tui.c
@@ -233,7 +233,7 @@  class gdbpy_tui_window_maker
 
   ~gdbpy_tui_window_maker ();
 
-  gdbpy_tui_window_maker (gdbpy_tui_window_maker &&other)
+  gdbpy_tui_window_maker (gdbpy_tui_window_maker &&other) noexcept
     : m_constr (std::move (other.m_constr))
   {
   }
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 6e243c1a07b..ee4256c6328 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -975,7 +975,7 @@  struct gdbpy_event
   {
   }
 
-  gdbpy_event (gdbpy_event &&other)
+  gdbpy_event (gdbpy_event &&other) noexcept
     : m_func (other.m_func)
   {
     other.m_func = nullptr;
diff --git a/gdbsupport/gdb_ref_ptr.h b/gdbsupport/gdb_ref_ptr.h
index c5ef13f3dfa..de387f598de 100644
--- a/gdbsupport/gdb_ref_ptr.h
+++ b/gdbsupport/gdb_ref_ptr.h
@@ -78,7 +78,7 @@  class ref_ptr
   }
 
   /* Transfer ownership from OTHER.  */
-  ref_ptr (ref_ptr &&other)
+  ref_ptr (ref_ptr &&other) noexcept
     : m_obj (other.m_obj)
   {
     other.m_obj = NULL;
diff --git a/gdbsupport/scoped_fd.h b/gdbsupport/scoped_fd.h
index f40ce8b0b50..ec654df5246 100644
--- a/gdbsupport/scoped_fd.h
+++ b/gdbsupport/scoped_fd.h
@@ -30,7 +30,7 @@  class scoped_fd
 public:
   explicit scoped_fd (int fd = -1) noexcept : m_fd (fd) {}
 
-  scoped_fd (scoped_fd &&other)
+  scoped_fd (scoped_fd &&other) noexcept
     : m_fd (other.m_fd)
   {
     other.m_fd = -1;
diff --git a/gdbsupport/scoped_mmap.h b/gdbsupport/scoped_mmap.h
index bab988f364c..9b74383fc50 100644
--- a/gdbsupport/scoped_mmap.h
+++ b/gdbsupport/scoped_mmap.h
@@ -42,13 +42,10 @@  class scoped_mmap
     destroy ();
   }
 
-  scoped_mmap (scoped_mmap &&rhs)
+  scoped_mmap (scoped_mmap &&rhs) noexcept
+    : m_mem (rhs.m_mem),
+      m_length (rhs.m_length)
   {
-    destroy ();
-
-    m_mem = rhs.m_mem;
-    m_length = rhs.m_length;
-
     rhs.m_mem = MAP_FAILED;
     rhs.m_length = 0;
   }