gdbsupport: add debug assertions in gdb::optional::get
authorSimon Marchi <simon.marchi@polymtl.ca>
Thu, 29 Jul 2021 18:42:04 +0000 (14:42 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Tue, 3 Aug 2021 12:50:56 +0000 (08:50 -0400)
The libstdc++ version of optional contains some runtime checks enabled
when _GLIBCXX_DEBUG is defined.  I think it would be useful if our
version contained similar checks.

Add checks in the two `get` methods, also conditional on _GLIBCXX_DEBUG.
I think it's simpler to use that macro rather than introducing a new
GDB-specific one, as I think that if somebody is interested in enabling
these runtime checks, they'll also be interested in enabling the
libstdc++ runtime checks (and vice-versa).

I implemented these checks using gdb_assert.  Note that gdb_assert
throws (after querying the user), and we are in noexcept methods.  That
means that std::terminate / abort will immediately be called.  I think
this is ok, since if those were "real" _GLIBCXX_DEBUG checks, abort
would be called straight away.

If I add a dummy failure, it looks like so:

    $ ./gdb -q -nx --data-directory=data-directory
    /home/simark/src/binutils-gdb/gdb/../gdbsupport/gdb_optional.h:206: internal-error: T& gdb::optional<T>::get() [with T = int]: Assertion `this->has_value ()' failed.
    A problem internal to GDB has been detected,
    further debugging may prove unreliable.
    Quit this debugging session? (y or n) n
    [1]    658767 abort (core dumped)  ./gdb -q -nx --data-directory=data-directory

Change-Id: Iadfdcd131425bd2ca6a2de30d7b22e9b3cc67793

gdbsupport/gdb_optional.h

index e79ba2c52e61832c60cbd38ec2bf2f13d6014060..745b2ba74886595c40f6e0bbeec4964c5d33fc49 100644 (file)
@@ -200,8 +200,20 @@ private:
   }
 
   /* The get operations have m_instantiated as a precondition.  */
-  T &get () noexcept { return m_item; }
-  constexpr const T &get () const noexcept { return m_item; }
+  T &get () noexcept
+  {
+#if defined(_GLIBCXX_DEBUG)
+    gdb_assert (this->has_value ());
+#endif
+    return m_item;
+  }
+  constexpr const T &get () const noexcept
+  {
+#if defined(_GLIBCXX_DEBUG)
+    gdb_assert (this->has_value ());
+#endif
+    return m_item;
+  }
 
   /* The object.  */
   union