aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/eval.c19
-rw-r--r--gdb/testsuite/ChangeLog8
-rw-r--r--gdb/testsuite/gdb.cp/method-call-in-c.cc10
-rw-r--r--gdb/testsuite/gdb.cp/method-call-in-c.exp4
-rw-r--r--gdb/valarith.c2
-rw-r--r--gdb/valops.c58
-rw-r--r--gdb/value.h2
8 files changed, 70 insertions, 45 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 04ea77f..9396aad 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,6 +1,18 @@
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
PR gdb/27994
+ * eval.c (structop_base_operation::evaluate_funcall): Pass
+ array_view instead of array to value_struct_elt.
+ * valarith.c (value_user_defined_op): Likewise.
+ * valops.c (typecmp): Change parameter type from array pointer to
+ array_view. Update header comment, and update body accordingly.
+ (search_struct_method): Likewise.
+ (value_struct_elt): Likewise.
+ * value.h (value_struct_elt): Update declaration.
+
+2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ PR gdb/27994
* eval.c (structop_base_operation::evaluate_funcall): Add a
nullptr to the end of the args array, which should not be included
in the argument array_view. Pass all the arguments through to
diff --git a/gdb/eval.c b/gdb/eval.c
index ab070a3..5a72bf1 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -872,9 +872,9 @@ structop_base_operation::evaluate_funcall
(struct type *expect_type, struct expression *exp, enum noside noside,
const std::vector<operation_up> &args)
{
- /* Allocate space for the function call arguments. Include space for a
- `this' pointer at the start, and a trailing nullptr. */
- std::vector<value *> vals (args.size () + 2);
+ /* Allocate space for the function call arguments, Including space for a
+ `this' pointer at the start. */
+ std::vector<value *> vals (args.size () + 1);
/* First, evaluate the structure into vals[0]. */
enum exp_opcode op = opcode ();
if (op == STRUCTOP_STRUCT)
@@ -920,16 +920,13 @@ structop_base_operation::evaluate_funcall
}
}
- /* Evaluate the arguments, and add the trailing nullptr. The '+ 1' here
- is to allow for the `this' pointer we placed into vals[0]. */
+ /* Evaluate the arguments. The '+ 1' here is to allow for the `this'
+ pointer we placed into vals[0]. */
for (int i = 0; i < args.size (); ++i)
vals[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
- vals[args.size () + 1] = nullptr;
- /* The array view includes the `this' pointer, but not the trailing
- nullptr. */
- gdb::array_view<value *> arg_view
- = gdb::make_array_view (&vals[0], args.size () + 1);
+ /* The array view includes the `this' pointer. */
+ gdb::array_view<value *> arg_view (vals);
int static_memfuncp;
value *callee;
@@ -950,7 +947,7 @@ structop_base_operation::evaluate_funcall
{
struct value *temp = vals[0];
- callee = value_struct_elt (&temp, &vals[0], tstr,
+ callee = value_struct_elt (&temp, &arg_view, tstr,
&static_memfuncp,
op == STRUCTOP_STRUCT
? "structure" : "structure pointer");
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 878921d..b155c71 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,6 +1,14 @@
2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
PR gdb/27994
+ * gdb.cp/method-call-in-c.cc (struct foo_type): Add operator+=,
+ change initial value of var member variable.
+ (main): Make use of foo_type's operator+=.
+ * gdb.cp/method-call-in-c.exp: Test use of operator+=.
+
+2021-06-25 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ PR gdb/27994
* gdb.cp/method-call-in-c.cc: New file.
* gdb.cp/method-call-in-c.exp: New file.
diff --git a/gdb/testsuite/gdb.cp/method-call-in-c.cc b/gdb/testsuite/gdb.cp/method-call-in-c.cc
index 09e4285..95f3f3c 100644
--- a/gdb/testsuite/gdb.cp/method-call-in-c.cc
+++ b/gdb/testsuite/gdb.cp/method-call-in-c.cc
@@ -29,7 +29,13 @@ struct foo_type
return var++;
}
- int var = 123;
+ foo_type &operator+= (const baz_type &rhs)
+ {
+ var += (rhs.a + rhs.b + rhs.c);
+ return *this;
+ }
+
+ int var = 120;
};
int
@@ -40,5 +46,7 @@ main (void)
foo_type foo;
+ foo += b;
+
return foo.func (b, f); /* Break here. */
}
diff --git a/gdb/testsuite/gdb.cp/method-call-in-c.exp b/gdb/testsuite/gdb.cp/method-call-in-c.exp
index 0e6851b..411ba67 100644
--- a/gdb/testsuite/gdb.cp/method-call-in-c.exp
+++ b/gdb/testsuite/gdb.cp/method-call-in-c.exp
@@ -39,5 +39,9 @@ foreach_with_prefix lang { c++ c } {
gdb_test "print foo.func (b, f)" " = ${result}"
incr result
+
+ set result [expr $result + 3]
+ gdb_test "print foo += b" \
+ " = \\((?:struct )?foo_type &\\) @${hex}: \\\{var = ${result}\\\}"
}
}
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 299a99f..d61ad91 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -344,7 +344,7 @@ value_user_defined_op (struct value **argp, gdb::array_view<value *> args,
noside);
}
else
- result = value_struct_elt (argp, args.data (), name, static_memfuncp,
+ result = value_struct_elt (argp, &args, name, static_memfuncp,
"structure");
return result;
diff --git a/gdb/valops.c b/gdb/valops.c
index 2b57930..0af7a6c 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -44,14 +44,14 @@
/* Local functions. */
-static int typecmp (int staticp, int varargs, int nargs,
- struct field t1[], struct value *t2[]);
+static int typecmp (bool staticp, bool varargs, int nargs,
+ struct field t1[], const gdb::array_view<value *> t2);
static struct value *search_struct_field (const char *, struct value *,
struct type *, int);
static struct value *search_struct_method (const char *, struct value **,
- struct value **,
+ gdb::array_view<value *> *,
LONGEST, int *, struct type *);
static int find_oload_champ_namespace (gdb::array_view<value *> args,
@@ -1785,15 +1785,15 @@ value_string (const char *ptr, ssize_t len, struct type *char_type)
}
-/* See if we can pass arguments in T2 to a function which takes
- arguments of types T1. T1 is a list of NARGS arguments, and T2 is
- a NULL-terminated vector. If some arguments need coercion of some
- sort, then the coerced values are written into T2. Return value is
+/* See if we can pass arguments in T2 to a function which takes arguments
+ of types T1. T1 is a list of NARGS arguments, and T2 is an array_view
+ of the values we're trying to pass. If some arguments need coercion of
+ some sort, then the coerced values are written into T2. Return value is
0 if the arguments could be matched, or the position at which they
differ if not.
STATICP is nonzero if the T1 argument list came from a static
- member function. T2 will still include the ``this'' pointer, but
+ member function. T2 must still include the ``this'' pointer, but
it will be skipped.
For non-static member functions, we ignore the first argument,
@@ -1803,19 +1803,15 @@ value_string (const char *ptr, ssize_t len, struct type *char_type)
requested operation is type secure, shouldn't we? FIXME. */
static int
-typecmp (int staticp, int varargs, int nargs,
- struct field t1[], struct value *t2[])
+typecmp (bool staticp, bool varargs, int nargs,
+ struct field t1[], gdb::array_view<value *> t2)
{
int i;
- if (t2 == 0)
- internal_error (__FILE__, __LINE__,
- _("typecmp: no argument list"));
-
/* Skip ``this'' argument if applicable. T2 will always include
THIS. */
if (staticp)
- t2 ++;
+ t2 = t2.slice (1);
for (i = 0;
(i < nargs) && t1[i].type ()->code () != TYPE_CODE_VOID;
@@ -1823,7 +1819,7 @@ typecmp (int staticp, int varargs, int nargs,
{
struct type *tt1, *tt2;
- if (!t2[i])
+ if (i == t2.size ())
return i + 1;
tt1 = check_typedef (t1[i].type ());
@@ -1868,7 +1864,7 @@ typecmp (int staticp, int varargs, int nargs,
if (t1[i].type ()->code () != value_type (t2[i])->code ())
return i + 1;
}
- if (varargs || t2[i] == NULL)
+ if (varargs || i == t2.size ())
return 0;
return i + 1;
}
@@ -2181,16 +2177,16 @@ search_struct_field (const char *name, struct value *arg1,
ARG1 by OFFSET bytes, and search in it assuming it has (class) type
TYPE.
- The ARGS array is a list of argument values used to help finding NAME,
- though ARGS can be nullptr. If ARGS is not nullptr then the list itself
- must have a NULL at the end.
+ The ARGS array pointer is to a list of argument values used to help
+ finding NAME, though ARGS can be nullptr. The contents of ARGS can be
+ adjusted if type coercion is required in order to find a matching NAME.
If found, return value, else if name matched and args not return
(value) -1, else return NULL. */
static struct value *
search_struct_method (const char *name, struct value **arg1p,
- struct value **args, LONGEST offset,
+ gdb::array_view<value *> *args, LONGEST offset,
int *static_memfuncp, struct type *type)
{
int i;
@@ -2209,10 +2205,10 @@ search_struct_method (const char *name, struct value **arg1p,
name_matched = 1;
check_stub_method_group (type, i);
- if (j > 0 && args == 0)
+ if (j > 0 && args == nullptr)
error (_("cannot resolve overloaded method "
"`%s': no arguments supplied"), name);
- else if (j == 0 && args == 0)
+ else if (j == 0 && args == nullptr)
{
v = value_fn_field (arg1p, f, j, type, offset);
if (v != NULL)
@@ -2221,10 +2217,11 @@ search_struct_method (const char *name, struct value **arg1p,
else
while (j >= 0)
{
+ gdb_assert (args != nullptr);
if (!typecmp (TYPE_FN_FIELD_STATIC_P (f, j),
TYPE_FN_FIELD_TYPE (f, j)->has_varargs (),
TYPE_FN_FIELD_TYPE (f, j)->num_fields (),
- TYPE_FN_FIELD_ARGS (f, j), args))
+ TYPE_FN_FIELD_ARGS (f, j), *args))
{
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
return value_virtual_fn_field (arg1p, f, j,
@@ -2313,8 +2310,7 @@ search_struct_method (const char *name, struct value **arg1p,
ERR is used in the error message if *ARGP's type is wrong.
C++: ARGS is a list of argument types to aid in the selection of
- an appropriate method. Also, handle derived types. The array ARGS must
- have a NULL at the end.
+ an appropriate method. Also, handle derived types.
STATIC_MEMFUNCP, if non-NULL, points to a caller-supplied location
where the truthvalue of whether the function that was resolved was
@@ -2324,7 +2320,7 @@ search_struct_method (const char *name, struct value **arg1p,
found. */
struct value *
-value_struct_elt (struct value **argp, struct value **args,
+value_struct_elt (struct value **argp, gdb::array_view<value *> *args,
const char *name, int *static_memfuncp, const char *err)
{
struct type *t;
@@ -2354,7 +2350,7 @@ value_struct_elt (struct value **argp, struct value **args,
if (static_memfuncp)
*static_memfuncp = 0;
- if (!args)
+ if (args == nullptr)
{
/* if there are no arguments ...do this... */
@@ -2366,7 +2362,7 @@ value_struct_elt (struct value **argp, struct value **args,
/* C++: If it was not found as a data field, then try to
return it as a pointer to a method. */
- v = search_struct_method (name, argp, args, 0,
+ v = search_struct_method (name, argp, args, 0,
static_memfuncp, t);
if (v == (struct value *) - 1)
@@ -2381,9 +2377,9 @@ value_struct_elt (struct value **argp, struct value **args,
return v;
}
- v = search_struct_method (name, argp, args, 0,
+ v = search_struct_method (name, argp, args, 0,
static_memfuncp, t);
-
+
if (v == (struct value *) - 1)
{
error (_("One of the arguments you tried to pass to %s could not "
diff --git a/gdb/value.h b/gdb/value.h
index a691f3c..40ad28e 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -826,7 +826,7 @@ extern struct value *value_neg (struct value *arg1);
extern struct value *value_complement (struct value *arg1);
extern struct value *value_struct_elt (struct value **argp,
- struct value **args,
+ gdb::array_view <value *> *args,
const char *name, int *static_memfuncp,
const char *err);