]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/python/py-value.c
gdb: building inferior strings from within GDB
[thirdparty/binutils-gdb.git] / gdb / python / py-value.c
index 255a30875be5c4df45514e3c2b49189100345349..933af92a664bb73a9c792036696b293d08f660e3 100644 (file)
@@ -1,6 +1,6 @@
 /* Python interface to values.
 
-   Copyright (C) 2008-2021 Free Software Foundation, Inc.
+   Copyright (C) 2008-2023 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -18,6 +18,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "top.h"               /* For quit_force ().  */
 #include "charset.h"
 #include "value.h"
 #include "language.h"
    GDB (which uses target arithmetic).  */
 
 /* Python's integer type corresponds to C's long type.  */
-#define builtin_type_pyint builtin_type (python_gdbarch)->builtin_long
+#define builtin_type_pyint \
+  builtin_type (gdbpy_enter::get_gdbarch ())->builtin_long
 
 /* Python's float type corresponds to C's double type.  */
-#define builtin_type_pyfloat builtin_type (python_gdbarch)->builtin_double
+#define builtin_type_pyfloat \
+  builtin_type (gdbpy_enter::get_gdbarch ())->builtin_double
 
 /* Python's long type corresponds to C's long long type.  */
-#define builtin_type_pylong builtin_type (python_gdbarch)->builtin_long_long
+#define builtin_type_pylong \
+  builtin_type (gdbpy_enter::get_gdbarch ())->builtin_long_long
 
 /* Python's long type corresponds to C's long long type.  Unsigned version.  */
 #define builtin_type_upylong builtin_type \
-  (python_gdbarch)->builtin_unsigned_long_long
+  (gdbpy_enter::get_gdbarch ())->builtin_unsigned_long_long
 
 #define builtin_type_pybool \
-  language_bool_type (python_language, python_gdbarch)
-
-#define builtin_type_pychar \
-  language_string_char_type (python_language, python_gdbarch)
+  language_bool_type (current_language, gdbpy_enter::get_gdbarch ())
 
 struct value_object {
   PyObject_HEAD
@@ -78,7 +79,7 @@ static void
 valpy_clear_value (value_object *self)
 {
   /* Indicate we are no longer interested in the value object.  */
-  value_decref (self->value);
+  self->value->decref ();
   self->value = nullptr;
 
   Py_CLEAR (self->address);
@@ -155,7 +156,7 @@ convert_buffer_and_type_to_value (PyObject *obj, struct type *type)
       return nullptr;
     }
 
-  if (TYPE_LENGTH (type) > py_buf.len)
+  if (type->length () > py_buf.len)
     {
       PyErr_SetString (PyExc_ValueError,
                       _("Size of type is larger than that of buffer object."));
@@ -225,7 +226,7 @@ gdbpy_preserve_values (const struct extension_language_defn *extlang,
   value_object *iter;
 
   for (iter = values_in_python; iter; iter = iter->next)
-    preserve_one_value (iter->value, objfile, copied_types);
+    iter->value->preserve (objfile, copied_types);
 }
 
 /* Given a value of a pointer type, apply the C unary * operator to it.  */
@@ -269,7 +270,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
       scoped_value_mark free_values;
 
       self_val = ((value_object *) self)->value;
-      switch (check_typedef (value_type (self_val))->code ())
+      switch (check_typedef (self_val->type ())->code ())
        {
        case TYPE_CODE_PTR:
          res_val = value_ind (self_val);
@@ -368,6 +369,10 @@ valpy_get_address (PyObject *self, void *closure)
          res_val = value_addr (val_obj->value);
          val_obj->address = value_to_value_object (res_val);
        }
+      catch (const gdb_exception_forced_quit &except)
+       {
+         quit_force (NULL, 0);
+       }
       catch (const gdb_exception &except)
        {
          val_obj->address = Py_None;
@@ -388,7 +393,7 @@ valpy_get_type (PyObject *self, void *closure)
 
   if (!obj->type)
     {
-      obj->type = type_to_type_object (value_type (obj->value));
+      obj->type = type_to_type_object (obj->value->type ());
       if (!obj->type)
        return NULL;
     }
@@ -415,11 +420,11 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
       struct value *val = obj->value;
       scoped_value_mark free_values;
 
-      type = value_type (val);
+      type = val->type ();
       type = check_typedef (type);
 
       if (type->is_pointer_or_reference ()
-         && (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_STRUCT))
+         && (type->target_type ()->code () == TYPE_CODE_STRUCT))
        {
          struct value *target;
          int was_pointer = type->code () == TYPE_CODE_PTR;
@@ -503,7 +508,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
       struct type *type, *realtype;
       CORE_ADDR addr;
 
-      type = value_type (value);
+      type = value->type ();
       realtype = check_typedef (type);
 
       switch (realtype->code ())
@@ -522,7 +527,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
              length = array_length;
            else if (array_length == -1)
              {
-               type = lookup_array_range_type (TYPE_TARGET_TYPE (realtype),
+               type = lookup_array_range_type (realtype->target_type (),
                                                0, length - 1);
              }
            else if (length != array_length)
@@ -531,11 +536,11 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
                   specified length.  */
                if (length > array_length)
                  error (_("Length is larger than array size."));
-               type = lookup_array_range_type (TYPE_TARGET_TYPE (realtype),
+               type = lookup_array_range_type (realtype->target_type (),
                                                low_bound,
                                                low_bound + length - 1);
              }
-           addr = value_address (value);
+           addr = value->address ();
            break;
          }
        case TYPE_CODE_PTR:
@@ -545,7 +550,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
          break;
        default:
          /* Should flag an error here.  PR 20769.  */
-         addr = value_address (value);
+         addr = value->address ();
          break;
        }
 
@@ -594,7 +599,7 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
 
   encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
   return PyUnicode_Decode ((const char *) buffer.get (),
-                          length * TYPE_LENGTH (char_type),
+                          length * char_type->length (),
                           encoding, errors);
 }
 
@@ -636,11 +641,15 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
       "symbols",               /* See set print symbol on|off.  */
       "unions",                        /* See set print union on|off.  */
       "address",               /* See set print address on|off.  */
+      "styling",               /* Should we apply styling.  */
+      "nibbles",               /* See set print nibbles on|off.  */
+      "summary",               /* Summary mode for non-scalars.  */
       /* C++ options.  */
       "deref_refs",            /* No corresponding setting.  */
       "actual_objects",                /* See set print object on|off.  */
       "static_members",                /* See set print static-members on|off.  */
       /* C non-bool options.  */
+      "max_characters",        /* See set print characters N.  */
       "max_elements",          /* See set print elements N.  */
       "max_depth",             /* See set print max-depth N.  */
       "repeat_threshold",      /* See set print repeats.  */
@@ -668,8 +677,8 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
     }
 
   struct value_print_options opts;
-  get_user_print_options (&opts);
-  opts.deref_ref = 0;
+  gdbpy_get_print_options (&opts);
+  opts.deref_ref = false;
 
   /* We need objects for booleans as the "p" flag for bools is new in
      Python 3.3.  */
@@ -680,13 +689,16 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
   PyObject *symbols_obj = NULL;
   PyObject *unions_obj = NULL;
   PyObject *address_obj = NULL;
+  PyObject *styling_obj = Py_False;
+  PyObject *nibbles_obj = NULL;
   PyObject *deref_refs_obj = NULL;
   PyObject *actual_objects_obj = NULL;
   PyObject *static_members_obj = NULL;
+  PyObject *summary_obj = NULL;
   char *format = NULL;
   if (!gdb_PyArg_ParseTupleAndKeywords (args,
                                        kw,
-                                       "|O!O!O!O!O!O!O!O!O!O!IIIs",
+                                       "|O!O!O!O!O!O!O!O!O!O!O!O!O!IIIIs",
                                        keywords,
                                        &PyBool_Type, &raw_obj,
                                        &PyBool_Type, &pretty_arrays_obj,
@@ -695,9 +707,13 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
                                        &PyBool_Type, &symbols_obj,
                                        &PyBool_Type, &unions_obj,
                                        &PyBool_Type, &address_obj,
+                                       &PyBool_Type, &styling_obj,
+                                       &PyBool_Type, &nibbles_obj,
+                                       &PyBool_Type, &summary_obj,
                                        &PyBool_Type, &deref_refs_obj,
                                        &PyBool_Type, &actual_objects_obj,
                                        &PyBool_Type, &static_members_obj,
+                                       &opts.print_max_chars,
                                        &opts.print_max,
                                        &opts.max_depth,
                                        &opts.repeat_count_threshold,
@@ -719,12 +735,16 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
     return NULL;
   if (!copy_py_bool_obj (&opts.addressprint, address_obj))
     return NULL;
+  if (!copy_py_bool_obj (&opts.nibblesprint, nibbles_obj))
+    return NULL;
   if (!copy_py_bool_obj (&opts.deref_ref, deref_refs_obj))
     return NULL;
   if (!copy_py_bool_obj (&opts.objectprint, actual_objects_obj))
     return NULL;
   if (!copy_py_bool_obj (&opts.static_field_print, static_members_obj))
     return NULL;
+  if (!copy_py_bool_obj (&opts.summary, summary_obj))
+    return nullptr;
 
   /* Numeric arguments for which 0 means unlimited (which we represent as
      UINT_MAX).  Note that the max-depth numeric argument uses -1 as
@@ -749,12 +769,12 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
        }
     }
 
-  string_file stb;
+  string_file stb (PyObject_IsTrue (styling_obj));
 
   try
     {
       common_val_print (((value_object *) self)->value, &stb, 0,
-                       &opts, python_language);
+                       &opts, current_language);
     }
   catch (const gdb_exception &except)
     {
@@ -867,10 +887,10 @@ value_has_field (struct value *v, PyObject *field)
 
   try
     {
-      val_type = value_type (v);
+      val_type = v->type ();
       val_type = check_typedef (val_type);
       if (val_type->is_pointer_or_reference ())
-       val_type = check_typedef (TYPE_TARGET_TYPE (val_type));
+       val_type = check_typedef (val_type->target_type ());
 
       type_code = val_type->code ();
       if ((type_code == TYPE_CODE_STRUCT || type_code == TYPE_CODE_UNION)
@@ -1019,7 +1039,7 @@ valpy_getitem (PyObject *self, PyObject *key)
        {
          struct type *val_type;
 
-         val_type = check_typedef (value_type (tmp));
+         val_type = check_typedef (tmp->type ());
          if (val_type->code () == TYPE_CODE_PTR)
            res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
          else if (val_type->code () == TYPE_CODE_REF)
@@ -1045,7 +1065,7 @@ valpy_getitem (PyObject *self, PyObject *key)
              struct type *type;
 
              tmp = coerce_ref (tmp);
-             type = check_typedef (value_type (tmp));
+             type = check_typedef (tmp->type ());
              if (type->code () != TYPE_CODE_ARRAY
                  && type->code () != TYPE_CODE_PTR)
                  error (_("Cannot subscript requested type."));
@@ -1088,7 +1108,7 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
 
   try
     {
-      ftype = check_typedef (value_type (function));
+      ftype = check_typedef (function->type ());
     }
   catch (const gdb_exception &except)
     {
@@ -1152,15 +1172,15 @@ valpy_str (PyObject *self)
 {
   struct value_print_options opts;
 
-  get_user_print_options (&opts);
-  opts.deref_ref = 0;
+  gdbpy_get_print_options (&opts);
+  opts.deref_ref = false;
 
   string_file stb;
 
   try
     {
       common_val_print (((value_object *) self)->value, &stb, 0,
-                       &opts, python_language);
+                       &opts, current_language);
     }
   catch (const gdb_exception &except)
     {
@@ -1179,7 +1199,7 @@ valpy_get_is_optimized_out (PyObject *self, void *closure)
 
   try
     {
-      opt = value_optimized_out (value);
+      opt = value->optimized_out ();
     }
   catch (const gdb_exception &except)
     {
@@ -1201,7 +1221,7 @@ valpy_get_is_lazy (PyObject *self, void *closure)
 
   try
     {
-      opt = value_lazy (value);
+      opt = value->lazy ();
     }
   catch (const gdb_exception &except)
     {
@@ -1222,8 +1242,8 @@ valpy_fetch_lazy (PyObject *self, PyObject *args)
 
   try
     {
-      if (value_lazy (value))
-       value_fetch_lazy (value);
+      if (value->lazy ())
+       value->fetch_lazy ();
     }
   catch (const gdb_exception &except)
     {
@@ -1258,7 +1278,7 @@ enum valpy_opcode
 
 /* If TYPE is a reference, return the target; otherwise return TYPE.  */
 #define STRIP_REFERENCE(TYPE) \
-  (TYPE_IS_REFERENCE (TYPE) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+  (TYPE_IS_REFERENCE (TYPE) ? ((TYPE)->target_type ()) : (TYPE))
 
 /* Helper for valpy_binop.  Returns a value object which is the result
    of applying the operation specified by OPCODE to the given
@@ -1293,8 +1313,8 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
     {
     case VALPY_ADD:
       {
-       struct type *ltype = value_type (arg1);
-       struct type *rtype = value_type (arg2);
+       struct type *ltype = arg1->type ();
+       struct type *rtype = arg2->type ();
 
        ltype = check_typedef (ltype);
        ltype = STRIP_REFERENCE (ltype);
@@ -1317,8 +1337,8 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
       break;
     case VALPY_SUB:
       {
-       struct type *ltype = value_type (arg1);
-       struct type *rtype = value_type (arg2);
+       struct type *ltype = arg1->type ();
+       struct type *rtype = arg2->type ();
 
        ltype = check_typedef (ltype);
        ltype = STRIP_REFERENCE (ltype);
@@ -1488,7 +1508,7 @@ valpy_absolute (PyObject *self)
     {
       scoped_value_mark free_values;
 
-      if (value_less (value, value_zero (value_type (value), not_lval)))
+      if (value_less (value, value::zero (value->type (), not_lval)))
        isabs = 0;
     }
   catch (const gdb_exception &except)
@@ -1513,13 +1533,13 @@ valpy_nonzero (PyObject *self)
 
   try
     {
-      type = check_typedef (value_type (self_value->value));
+      type = check_typedef (self_value->value->type ());
 
       if (is_integral_type (type) || type->code () == TYPE_CODE_PTR)
        nonzero = !!value_as_long (self_value->value);
       else if (is_floating_value (self_value->value))
        nonzero = !target_float_is_zero
-         (value_contents (self_value->value).data (), type);
+         (self_value->value->contents ().data (), type);
       else
        /* All other values are True.  */
        nonzero = 1;
@@ -1541,18 +1561,20 @@ valpy_nonzero (PyObject *self)
 static PyObject *
 valpy_invert (PyObject *self)
 {
-  struct value *val = NULL;
+  PyObject *result = nullptr;
 
   try
     {
-      val = value_complement (((value_object *) self)->value);
+      scoped_value_mark free_values;
+      struct value *val = value_complement (((value_object *) self)->value);
+      result = value_to_value_object (val);
     }
   catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  return value_to_value_object (val);
+  return result;
 }
 
 /* Implements left shift for value objects.  */
@@ -1689,47 +1711,12 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
   Py_RETURN_FALSE;
 }
 
-#ifndef IS_PY3K
-/* Implements conversion to int.  */
-static PyObject *
-valpy_int (PyObject *self)
-{
-  struct value *value = ((value_object *) self)->value;
-  struct type *type = value_type (value);
-  LONGEST l = 0;
-
-  try
-    {
-      if (is_floating_value (value))
-       {
-         type = builtin_type_pylong;
-         value = value_cast (type, value);
-       }
-
-      if (!is_integral_type (type)
-         && type->code () != TYPE_CODE_PTR)
-       error (_("Cannot convert value to int."));
-
-      l = value_as_long (value);
-    }
-  catch (const gdb_exception &except)
-    {
-      GDB_PY_HANDLE_EXCEPTION (except);
-    }
-
-  if (type->is_unsigned ())
-    return gdb_py_object_from_ulongest (l).release ();
-  else
-    return gdb_py_object_from_longest (l).release ();
-}
-#endif
-
 /* Implements conversion to long.  */
 static PyObject *
 valpy_long (PyObject *self)
 {
   struct value *value = ((value_object *) self)->value;
-  struct type *type = value_type (value);
+  struct type *type = value->type ();
   LONGEST l = 0;
 
   try
@@ -1764,7 +1751,7 @@ static PyObject *
 valpy_float (PyObject *self)
 {
   struct value *value = ((value_object *) self)->value;
-  struct type *type = value_type (value);
+  struct type *type = value->type ();
   double d = 0;
 
   try
@@ -1772,7 +1759,7 @@ valpy_float (PyObject *self)
       type = check_typedef (type);
 
       if (type->code () == TYPE_CODE_FLT && is_floating_value (value))
-       d = target_float_to_host_double (value_contents (value).data (), type);
+       d = target_float_to_host_double (value->contents ().data (), type);
       else if (type->code () == TYPE_CODE_INT)
        {
          /* Note that valpy_long accepts TYPE_CODE_PTR and some
@@ -1791,39 +1778,17 @@ valpy_float (PyObject *self)
   return PyFloat_FromDouble (d);
 }
 
-/* Returns an object for a value which is released from the all_values chain,
-   so its lifetime is not bound to the execution of a command.  */
-PyObject *
-value_to_value_object (struct value *val)
-{
-  value_object *val_obj;
-
-  val_obj = PyObject_New (value_object, &value_object_type);
-  if (val_obj != NULL)
-    {
-      val_obj->value = release_value (val).release ();
-      val_obj->next = nullptr;
-      val_obj->prev = nullptr;
-      val_obj->address = NULL;
-      val_obj->type = NULL;
-      val_obj->dynamic_type = NULL;
-      note_value (val_obj);
-    }
-
-  return (PyObject *) val_obj;
-}
-
-/* Returns an object for a value, but without releasing it from the
+/* Returns an object for a value, without releasing it from the
    all_values chain.  */
 PyObject *
-value_to_value_object_no_release (struct value *val)
+value_to_value_object (struct value *val)
 {
   value_object *val_obj;
 
   val_obj = PyObject_New (value_object, &value_object_type);
   if (val_obj != NULL)
     {
-      value_incref (val);
+      val->incref ();
       val_obj->value = val;
       val_obj->next = nullptr;
       val_obj->prev = nullptr;
@@ -1869,13 +1834,6 @@ convert_value_from_python (PyObject *obj)
          if (cmp >= 0)
            value = value_from_longest (builtin_type_pybool, cmp);
        }
-      /* Make a long logic check first.  In Python 3.x, internally,
-        all integers are represented as longs.  In Python 2.x, there
-        is still a differentiation internally between a PyInt and a
-        PyLong.  Explicitly do this long check conversion first. In
-        GDB, for Python 3.x, we #ifdef PyInt = PyLong.  This check has
-        to be done first to ensure we do not lose information in the
-        conversion process.  */
       else if (PyLong_Check (obj))
        {
          LONGEST l = PyLong_AsLongLong (obj);
@@ -1908,15 +1866,6 @@ convert_value_from_python (PyObject *obj)
          else
            value = value_from_longest (builtin_type_pylong, l);
        }
-#if PY_MAJOR_VERSION == 2
-      else if (PyInt_Check (obj))
-       {
-         long l = PyInt_AsLong (obj);
-
-         if (! PyErr_Occurred ())
-           value = value_from_longest (builtin_type_pyint, l);
-       }
-#endif
       else if (PyFloat_Check (obj))
        {
          double d = PyFloat_AsDouble (obj);
@@ -1929,27 +1878,22 @@ convert_value_from_python (PyObject *obj)
          gdb::unique_xmalloc_ptr<char> s
            = python_string_to_target_string (obj);
          if (s != NULL)
-           value = value_cstring (s.get (), strlen (s.get ()),
-                                  builtin_type_pychar);
+           value
+             = current_language->value_string (gdbpy_enter::get_gdbarch (),
+                                               s.get (), strlen (s.get ()));
        }
       else if (PyObject_TypeCheck (obj, &value_object_type))
-       value = value_copy (((value_object *) obj)->value);
+       value = ((value_object *) obj)->value->copy ();
       else if (gdbpy_is_lazy_string (obj))
        {
          PyObject *result;
 
          result = PyObject_CallMethodObjArgs (obj, gdbpy_value_cst,  NULL);
-         value = value_copy (((value_object *) result)->value);
+         value = ((value_object *) result)->value->copy ();
        }
       else
-#ifdef IS_PY3K
        PyErr_Format (PyExc_TypeError,
                      _("Could not convert Python object: %S."), obj);
-#else
-       PyErr_Format (PyExc_TypeError,
-                     _("Could not convert Python object: %s."),
-                     PyString_AsString (PyObject_Str (obj)));
-#endif
     }
   catch (const gdb_exception &except)
     {
@@ -1965,21 +1909,23 @@ PyObject *
 gdbpy_history (PyObject *self, PyObject *args)
 {
   int i;
-  struct value *res_val = NULL;          /* Initialize to appease gcc warning.  */
 
   if (!PyArg_ParseTuple (args, "i", &i))
     return NULL;
 
+  PyObject *result = nullptr;
   try
     {
-      res_val = access_value_history (i);
+      scoped_value_mark free_values;
+      struct value *res_val = access_value_history (i);
+      result = value_to_value_object (res_val);
     }
   catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  return value_to_value_object (res_val);
+  return result;
 }
 
 /* Add a gdb.Value into GDB's history, and return (as an integer) the
@@ -1998,7 +1944,7 @@ gdbpy_add_history (PyObject *self, PyObject *args)
 
   try
     {
-      int idx = record_latest_value (value);
+      int idx = value->record_latest ();
       return gdb_py_object_from_longest (idx).release ();
     }
   catch (const gdb_exception &except)
@@ -2009,6 +1955,14 @@ gdbpy_add_history (PyObject *self, PyObject *args)
   return nullptr;
 }
 
+/* Return an integer, the number of items in GDB's history.  */
+
+PyObject *
+gdbpy_history_count (PyObject *self, PyObject *args)
+{
+  return gdb_py_object_from_ulongest (value_history_count ()).release ();
+}
+
 /* Return the value of a convenience variable.  */
 PyObject *
 gdbpy_convenience_variable (PyObject *self, PyObject *args)
@@ -2019,15 +1973,23 @@ gdbpy_convenience_variable (PyObject *self, PyObject *args)
   if (!PyArg_ParseTuple (args, "s", &varname))
     return NULL;
 
+  PyObject *result = nullptr;
+  bool found = false;
   try
     {
       struct internalvar *var = lookup_only_internalvar (varname);
 
       if (var != NULL)
        {
-         res_val = value_of_internalvar (python_gdbarch, var);
-         if (value_type (res_val)->code () == TYPE_CODE_VOID)
+         scoped_value_mark free_values;
+         res_val = value_of_internalvar (gdbpy_enter::get_gdbarch (), var);
+         if (res_val->type ()->code () == TYPE_CODE_VOID)
            res_val = NULL;
+         else
+           {
+             found = true;
+             result = value_to_value_object (res_val);
+           }
        }
     }
   catch (const gdb_exception &except)
@@ -2035,10 +1997,10 @@ gdbpy_convenience_variable (PyObject *self, PyObject *args)
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
-  if (res_val == NULL)
+  if (result == nullptr && !found)
     Py_RETURN_NONE;
 
-  return value_to_value_object (res_val);
+  return result;
 }
 
 /* Set the value of a convenience variable.  */
@@ -2092,7 +2054,7 @@ gdbpy_is_value_object (PyObject *obj)
   return PyObject_TypeCheck (obj, &value_object_type);
 }
 
-int
+static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
 gdbpy_initialize_values (void)
 {
   if (PyType_Ready (&value_object_type) < 0)
@@ -2102,6 +2064,8 @@ gdbpy_initialize_values (void)
                                 (PyObject *) &value_object_type);
 }
 
+GDBPY_INITIALIZE_FILE (gdbpy_initialize_values);
+
 \f
 
 static gdb_PyGetSetDef value_object_getset[] = {
@@ -2140,7 +2104,7 @@ reinterpret_cast operator."
   { "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS,
     "Return a value of type TYPE_CODE_RVALUE_REF referencing this value." },
   { "const_value", valpy_const_value, METH_NOARGS,
-    "Return a 'const' qualied version of the same value." },
+    "Return a 'const' qualified version of the same value." },
   { "lazy_string", (PyCFunction) valpy_lazy_string,
     METH_VARARGS | METH_KEYWORDS,
     "lazy_string ([encoding]  [, length]) -> lazy_string\n\
@@ -2162,9 +2126,6 @@ static PyNumberMethods value_object_as_number = {
   valpy_add,
   valpy_subtract,
   valpy_multiply,
-#ifndef IS_PY3K
-  valpy_divide,
-#endif
   valpy_remainder,
   NULL,                              /* nb_divmod */
   valpy_power,               /* nb_power */
@@ -2178,25 +2139,12 @@ static PyNumberMethods value_object_as_number = {
   valpy_and,                 /* nb_and */
   valpy_xor,                 /* nb_xor */
   valpy_or,                  /* nb_or */
-#ifdef IS_PY3K
   valpy_long,                /* nb_int */
   NULL,                              /* reserved */
-#else
-  NULL,                              /* nb_coerce */
-  valpy_int,                 /* nb_int */
-  valpy_long,                /* nb_long */
-#endif
   valpy_float,               /* nb_float */
-#ifndef IS_PY3K
-  NULL,                              /* nb_oct */
-  NULL,                       /* nb_hex */
-#endif
   NULL,                       /* nb_inplace_add */
   NULL,                       /* nb_inplace_subtract */
   NULL,                       /* nb_inplace_multiply */
-#ifndef IS_PY3K
-  NULL,                       /* nb_inplace_divide */
-#endif
   NULL,                       /* nb_inplace_remainder */
   NULL,                       /* nb_inplace_power */
   NULL,                       /* nb_inplace_lshift */