From e71585ffe2e1394858f0fcf809e86f1b324fe4e6 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 21 Nov 2018 11:55:11 +0000 Subject: [PATCH] Use gdb:array_view in call_function_by_hand & friends This replaces a few uses of pointer+length with gdb::array_view, in call_function_by_hand and related code. Unfortunately, due to -Wnarrowing, there are places where we can't brace-initialize an gdb::array_view without an ugly-ish cast. To avoid the cast, this patch introduces a gdb::make_array_view function. Unit tests included. This patch in isolation may not look so interesting, due to gdb::make_array_view uses, but I think it's still worth it. Some of the gdb::make_array_view calls disappear down the series, and others could be eliminated with more (non-trivial) gdb::array_view detangling/conversion (e.g. code around eval_call). See this as a "we have to start somewhere" patch. gdb/ChangeLog: 2018-11-21 Pedro Alves * ada-lang.c (ada_evaluate_subexp): Adjust to pass an array_view. * common/array-view.h (make_array_view): New. * compile/compile-object-run.c (compile_object_run): Adjust to pass an array_view. * elfread.c (elf_gnu_ifunc_resolve_addr): Adjust. * eval.c (eval_call): Adjust to pass an array_view. (evaluate_subexp_standard): Adjust to pass an array_view. * gcore.c (call_target_sbrk): Adjust to pass an array_view. * guile/scm-value.c (gdbscm_value_call): Likewise. * infcall.c (push_dummy_code): Replace pointer + size parameters with an array_view parameter. (call_function_by_hand, call_function_by_hand_dummy): Likewise and adjust. * infcall.h: Include "common/array-view.h". (call_function_by_hand, call_function_by_hand_dummy): Replace pointer + size parameters with an array_view parameter. * linux-fork.c (inferior_call_waitpid): Adjust to use array_view. * linux-tdep.c (linux_infcall_mmap): Likewise. * objc-lang.c (lookup_objc_class, lookup_child_selector) (value_nsstring, print_object_command): Likewise. * python/py-value.c (valpy_call): Likewise. * rust-lang.c (rust_evaluate_funcall): Likewise. * spu-tdep.c (flush_ea_cache): Likewise. * valarith.c (value_x_binop, value_x_unop): Likewise. * valops.c (value_allocate_space_in_inferior): Likewise. * unittests/array-view-selftests.c (run_tests): Add gdb::make_array_view test. --- gdb/ChangeLog | 30 ++++++++++++++++++++++++++ gdb/ada-lang.c | 4 +++- gdb/common/array-view.h | 42 ++++++++++++++++++++++++++++++++++++ gdb/compile/compile-object-run.c | 4 ++-- gdb/elfread.c | 2 +- gdb/eval.c | 18 ++++++++-------- gdb/gcore.c | 2 +- gdb/guile/scm-value.c | 4 ++-- gdb/infcall.c | 29 +++++++++++++------------ gdb/infcall.h | 15 ++++++------- gdb/linux-fork.c | 7 +++--- gdb/linux-tdep.c | 4 ++-- gdb/objc-lang.c | 13 ++++++----- gdb/python/py-value.c | 6 +++--- gdb/rust-lang.c | 2 +- gdb/spu-tdep.c | 2 +- gdb/unittests/array-view-selftests.c | 13 +++++++++++ gdb/valarith.c | 7 +++--- gdb/valops.c | 2 +- 19 files changed, 146 insertions(+), 60 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ddd93f2..e315f34 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,33 @@ +2018-11-21 Pedro Alves + + * ada-lang.c (ada_evaluate_subexp): Adjust to pass an array_view. + * common/array-view.h (make_array_view): New. + * compile/compile-object-run.c (compile_object_run): Adjust to + pass an array_view. + * elfread.c (elf_gnu_ifunc_resolve_addr): Adjust. + * eval.c (eval_call): Adjust to pass an array_view. + (evaluate_subexp_standard): Adjust to pass an array_view. + * gcore.c (call_target_sbrk): Adjust to pass an array_view. + * guile/scm-value.c (gdbscm_value_call): Likewise. + * infcall.c (push_dummy_code): Replace pointer + size parameters + with an array_view parameter. + (call_function_by_hand, call_function_by_hand_dummy): Likewise and + adjust. + * infcall.h: Include "common/array-view.h". + (call_function_by_hand, call_function_by_hand_dummy): Replace + pointer + size parameters with an array_view parameter. + * linux-fork.c (inferior_call_waitpid): Adjust to use array_view. + * linux-tdep.c (linux_infcall_mmap): Likewise. + * objc-lang.c (lookup_objc_class, lookup_child_selector) + (value_nsstring, print_object_command): Likewise. + * python/py-value.c (valpy_call): Likewise. + * rust-lang.c (rust_evaluate_funcall): Likewise. + * spu-tdep.c (flush_ea_cache): Likewise. + * valarith.c (value_x_binop, value_x_unop): Likewise. + * valops.c (value_allocate_space_in_inferior): Likewise. + * unittests/array-view-selftests.c (run_tests): Add + gdb::make_array_view test. + 2018-11-20 Andrew Burgess * cli-out.c (cli_ui_out::do_field_int): Use string_printf rather diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 8967cf1..95bf670 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -10928,7 +10928,9 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, error_call_unknown_return_type (NULL); return allocate_value (TYPE_TARGET_TYPE (type)); } - return call_function_by_hand (argvec[0], NULL, nargs, argvec + 1); + return call_function_by_hand (argvec[0], NULL, + gdb::make_array_view (argvec + 1, + nargs)); case TYPE_CODE_INTERNAL_FUNCTION: if (noside == EVAL_AVOID_SIDE_EFFECTS) /* We don't know anything about what the internal diff --git a/gdb/common/array-view.h b/gdb/common/array-view.h index 319ea99..9c5fa2a 100644 --- a/gdb/common/array-view.h +++ b/gdb/common/array-view.h @@ -201,6 +201,48 @@ operator!= (const gdb::array_view &lhs, const gdb::array_view &rhs) return !(lhs == rhs); } +/* Create an array view from a pointer to an array and an element + count. + + This is useful as alternative to constructing an array_view using + brace initialization when the size variable you have handy is of + signed type, since otherwise without an explicit cast the code + would be ill-formed. + + For example, with: + + extern void foo (int, int, gdb::array_view); + + value *args[2]; + int nargs; + foo (1, 2, {values, nargs}); + + You'd get: + + source.c:10: error: narrowing conversion of ‘nargs’ from ‘int’ to + ‘size_t {aka long unsigned int}’ inside { } [-Werror=narrowing] + + You could fix it by writing the somewhat distracting explicit cast: + + foo (1, 2, {values, (size_t) nargs}); + + Or by instantiating an array_view explicitly: + + foo (1, 2, gdb::array_view(values, nargs)); + + Or, better, using make_array_view, which has the advantage of + inferring the arrav_view element's type: + + foo (1, 2, gdb::make_array_view (values, nargs)); +*/ + +template +constexpr inline array_view +make_array_view (U *array, size_t size) noexcept +{ + return {array, size}; +} + } /* namespace gdb */ #endif diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c index f3ec932..e891e77 100644 --- a/gdb/compile/compile-object-run.c +++ b/gdb/compile/compile-object-run.c @@ -170,8 +170,8 @@ compile_object_run (struct compile_module *module) ++current_arg; } gdb_assert (current_arg == TYPE_NFIELDS (func_type)); - call_function_by_hand_dummy (func_val, - NULL, TYPE_NFIELDS (func_type), vargs, + auto args = gdb::make_array_view (vargs, TYPE_NFIELDS (func_type)); + call_function_by_hand_dummy (func_val, NULL, args, do_module_cleanup, data); } CATCH (ex, RETURN_MASK_ERROR) diff --git a/gdb/elfread.c b/gdb/elfread.c index 9f1fa2b..71e6fcc 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -904,7 +904,7 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc) target_auxv_search (current_top_target (), AT_HWCAP, &hwcap); hwcap_val = value_from_longest (builtin_type (gdbarch) ->builtin_unsigned_long, hwcap); - address_val = call_function_by_hand (function, NULL, 1, &hwcap_val); + address_val = call_function_by_hand (function, NULL, hwcap_val); address = value_as_address (address_val); address = gdbarch_convert_from_func_ptr_addr (gdbarch, address, current_top_target ()); address = gdbarch_addr_bits_remove (gdbarch, address); diff --git a/gdb/eval.c b/gdb/eval.c index 047aba5..6eb210d 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -830,7 +830,7 @@ eval_call (expression *exp, enum noside noside, return call_xmethod (argvec[0], nargs, argvec + 1); default: return call_function_by_hand (argvec[0], default_return_type, - nargs, argvec + 1); + gdb::make_array_view (argvec + 1, nargs)); } } @@ -1728,12 +1728,12 @@ evaluate_subexp_standard (struct type *expect_type, argvec[3] = value_from_longest (long_type, selector); argvec[4] = 0; - ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); + ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3}); if (gnu_runtime) { /* Function objc_msg_lookup returns a pointer. */ argvec[0] = ret; - ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); + ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3}); } if (value_as_long (ret) == 0) error (_("Target does not respond to this message selector.")); @@ -1750,11 +1750,11 @@ evaluate_subexp_standard (struct type *expect_type, argvec[3] = value_from_longest (long_type, selector); argvec[4] = 0; - ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); + ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3}); if (gnu_runtime) { argvec[0] = ret; - ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); + ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3}); } /* ret should now be the selector. */ @@ -1890,17 +1890,17 @@ evaluate_subexp_standard (struct type *expect_type, argvec[tem + 3] = evaluate_subexp_with_coercion (exp, pos, noside); argvec[tem + 3] = 0; + auto call_args = gdb::make_array_view (argvec + 1, nargs + 2); + if (gnu_runtime && (method != NULL)) { /* Function objc_msg_lookup returns a pointer. */ deprecated_set_value_type (argvec[0], lookup_pointer_type (lookup_function_type (value_type (argvec[0])))); - argvec[0] - = call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1); + argvec[0] = call_function_by_hand (argvec[0], NULL, call_args); } - ret = call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1); - return ret; + return call_function_by_hand (argvec[0], NULL, call_args); } break; diff --git a/gdb/gcore.c b/gdb/gcore.c index fbebb6a..24810a7 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -300,7 +300,7 @@ call_target_sbrk (int sbrk_arg) target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int, sbrk_arg); gdb_assert (target_sbrk_arg); - ret = call_function_by_hand (sbrk_fn, NULL, 1, &target_sbrk_arg); + ret = call_function_by_hand (sbrk_fn, NULL, target_sbrk_arg); if (ret == NULL) return (bfd_vma) 0; diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c index ca0c075..42afd60 100644 --- a/gdb/guile/scm-value.c +++ b/gdb/guile/scm-value.c @@ -730,8 +730,8 @@ gdbscm_value_call (SCM self, SCM args) { scoped_value_mark free_values; - value *return_value = call_function_by_hand (function, NULL, - args_count, vargs); + auto av = gdb::make_array_view (vargs, args_count); + value *return_value = call_function_by_hand (function, NULL, av); return vlscm_scm_from_value (return_value); }); } diff --git a/gdb/infcall.c b/gdb/infcall.c index 1b1e7da..82595a4 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -334,7 +334,7 @@ find_function_addr (struct value *function, static CORE_ADDR push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, - struct value **args, int nargs, + gdb::array_view args, struct type *value_type, CORE_ADDR *real_pc, CORE_ADDR *bp_addr, struct regcache *regcache) @@ -342,7 +342,8 @@ push_dummy_code (struct gdbarch *gdbarch, gdb_assert (gdbarch_push_dummy_code_p (gdbarch)); return gdbarch_push_dummy_code (gdbarch, sp, funaddr, - args, nargs, value_type, real_pc, bp_addr, + args.data (), args.size (), + value_type, real_pc, bp_addr, regcache); } @@ -686,10 +687,10 @@ cleanup_delete_std_terminate_breakpoint (void *ignore) struct value * call_function_by_hand (struct value *function, type *default_return_type, - int nargs, struct value **args) + gdb::array_view args) { return call_function_by_hand_dummy (function, default_return_type, - nargs, args, NULL, NULL); + args, NULL, NULL); } /* All this stuff with a dummy frame may seem unnecessarily complicated @@ -713,7 +714,7 @@ call_function_by_hand (struct value *function, struct value * call_function_by_hand_dummy (struct value *function, type *default_return_type, - int nargs, struct value **args, + gdb::array_view args, dummy_frame_dtor_ftype *dummy_dtor, void *dummy_dtor_data) { @@ -912,7 +913,7 @@ call_function_by_hand_dummy (struct value *function, /* Be careful BP_ADDR is in inferior PC encoding while BP_ADDR_AS_ADDRESS is a plain memory address. */ - sp = push_dummy_code (gdbarch, sp, funaddr, args, nargs, + sp = push_dummy_code (gdbarch, sp, funaddr, args, target_values_type, &real_pc, &bp_addr, get_current_regcache ()); @@ -953,14 +954,14 @@ call_function_by_hand_dummy (struct value *function, internal_error (__FILE__, __LINE__, _("bad switch")); } - if (nargs < TYPE_NFIELDS (ftype)) + if (args.size () < TYPE_NFIELDS (ftype)) error (_("Too few arguments in function call.")); - for (int i = nargs - 1; i >= 0; i--) + for (int i = args.size () - 1; i >= 0; i--) { int prototyped; struct type *param_type; - + /* FIXME drow/2002-05-31: Should just always mark methods as prototyped. Can we respect TYPE_VARARGS? Probably not. */ if (TYPE_CODE (ftype) == TYPE_CODE_METHOD) @@ -1041,19 +1042,19 @@ call_function_by_hand_dummy (struct value *function, if (return_method == return_method_hidden_param) { /* Add the new argument to the front of the argument list. */ + new_args.reserve (args.size ()); new_args.push_back (value_from_pointer (lookup_pointer_type (values_type), struct_addr)); - std::copy (&args[0], &args[nargs], std::back_inserter (new_args)); - args = new_args.data (); - nargs++; + new_args.insert (new_args.end (), args.begin (), args.end ()); + args = new_args; } /* Create the dummy stack frame. Pass in the call dummy address as, presumably, the ABI code knows where, in the call dummy, the return address should be pointed. */ sp = gdbarch_push_dummy_call (gdbarch, function, get_current_regcache (), - bp_addr, nargs, args, sp, return_method, - struct_addr); + bp_addr, args.size (), args.data (), + sp, return_method, struct_addr); /* Set up a frame ID for the dummy frame so we can pass it to set_momentary_breakpoint. We need to give the breakpoint a frame diff --git a/gdb/infcall.h b/gdb/infcall.h index 8b21950..c6b451c 100644 --- a/gdb/infcall.h +++ b/gdb/infcall.h @@ -21,6 +21,7 @@ #define INFCALL_H #include "dummy-frame.h" +#include "common/array-view.h" struct value; struct type; @@ -37,10 +38,10 @@ extern CORE_ADDR find_function_addr (struct value *function, /* Perform a function call in the inferior. - ARGS is a vector of values of arguments (NARGS of them). FUNCTION - is a value, the function to be called. Returns a value - representing what the function returned. May fail to return, if a - breakpoint or signal is hit during the execution of the function. + ARGS is a vector of values of arguments. FUNCTION is a value, the + function to be called. Returns a value representing what the + function returned. May fail to return, if a breakpoint or signal + is hit during the execution of the function. DFEAULT_RETURN_TYPE is used as function return type if the return type is unknown. This is used when calling functions with no debug @@ -50,8 +51,7 @@ extern CORE_ADDR find_function_addr (struct value *function, extern struct value *call_function_by_hand (struct value *function, type *default_return_type, - int nargs, - struct value **args); + gdb::array_view args); /* Similar to call_function_by_hand and additional call register_dummy_frame_dtor with DUMMY_DTOR and DUMMY_DTOR_DATA for the @@ -60,8 +60,7 @@ extern struct value *call_function_by_hand (struct value *function, extern struct value * call_function_by_hand_dummy (struct value *function, type *default_return_type, - int nargs, - struct value **args, + gdb::array_view args, dummy_frame_dtor_ftype *dummy_dtor, void *dummy_dtor_data); diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c index 74d5c19..0f87d97 100644 --- a/gdb/linux-fork.c +++ b/gdb/linux-fork.c @@ -456,7 +456,7 @@ inferior_call_waitpid (ptid_t pptid, int pid) { struct objfile *waitpid_objf; struct value *waitpid_fn = NULL; - struct value *argv[4], *retv; + struct value *argv[3], *retv; struct gdbarch *gdbarch = get_current_arch (); struct fork_info *oldfp = NULL, *newfp = NULL; struct cleanup *old_cleanup; @@ -490,9 +490,8 @@ inferior_call_waitpid (ptid_t pptid, int pid) argv[0] = value_from_longest (builtin_type (gdbarch)->builtin_int, pid); argv[1] = value_from_pointer (builtin_type (gdbarch)->builtin_data_ptr, 0); argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0); - argv[3] = 0; - retv = call_function_by_hand (waitpid_fn, NULL, 3, argv); + retv = call_function_by_hand (waitpid_fn, NULL, argv); if (value_as_long (retv) < 0) goto out; @@ -704,7 +703,7 @@ checkpoint_command (const char *args, int from_tty) scoped_restore save_pid = make_scoped_restore (&checkpointing_pid, inferior_ptid.pid ()); - ret = call_function_by_hand (fork_fn, NULL, 0, &ret); + ret = call_function_by_hand (fork_fn, NULL, {}); } if (!ret) /* Probably can't happen. */ diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 2c766808..ecdb928 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -2400,7 +2400,7 @@ linux_infcall_mmap (CORE_ADDR size, unsigned prot) arg[ARG_FD] = value_from_longest (builtin_type (gdbarch)->builtin_int, -1); arg[ARG_OFFSET] = value_from_longest (builtin_type (gdbarch)->builtin_int64, 0); - addr_val = call_function_by_hand (mmap_val, NULL, ARG_LAST, arg); + addr_val = call_function_by_hand (mmap_val, NULL, arg); retval = value_as_address (addr_val); if (retval == (CORE_ADDR) -1) error (_("Failed inferior mmap call for %s bytes, errno is changed."), @@ -2429,7 +2429,7 @@ linux_infcall_munmap (CORE_ADDR addr, CORE_ADDR size) /* Assuming sizeof (unsigned long) == sizeof (size_t). */ arg[ARG_LENGTH] = value_from_ulongest (builtin_type (gdbarch)->builtin_unsigned_long, size); - retval_val = call_function_by_hand (munmap_val, NULL, ARG_LAST, arg); + retval_val = call_function_by_hand (munmap_val, NULL, arg); retval = value_as_long (retval_val); if (retval != 0) warning (_("Failed inferior munmap call at %s for %s bytes, " diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c index 6da8af1..d51362a 100644 --- a/gdb/objc-lang.c +++ b/gdb/objc-lang.c @@ -132,7 +132,7 @@ lookup_objc_class (struct gdbarch *gdbarch, const char *classname) classval = value_coerce_array (classval); return (CORE_ADDR) value_as_long (call_function_by_hand (function, NULL, - 1, &classval)); + classval)); } CORE_ADDR @@ -160,7 +160,7 @@ lookup_child_selector (struct gdbarch *gdbarch, const char *selname) selstring = value_coerce_array (value_string (selname, strlen (selname) + 1, char_type)); - return value_as_long (call_function_by_hand (function, NULL, 1, &selstring)); + return value_as_long (call_function_by_hand (function, NULL, selstring)); } struct value * @@ -181,13 +181,12 @@ value_nsstring (struct gdbarch *gdbarch, char *ptr, int len) if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0).minsym) { function = find_function_in_inferior("_NSNewStringFromCString", NULL); - nsstringValue = call_function_by_hand(function, - NULL, 1, &stringValue[2]); + nsstringValue = call_function_by_hand(function, NULL, stringValue[2]); } else if (lookup_minimal_symbol("istr", 0, 0).minsym) { function = find_function_in_inferior("istr", NULL); - nsstringValue = call_function_by_hand(function, NULL, 1, &stringValue[2]); + nsstringValue = call_function_by_hand(function, NULL, stringValue[2]); } else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym) { @@ -199,7 +198,7 @@ value_nsstring (struct gdbarch *gdbarch, char *ptr, int len) (type, lookup_objc_class (gdbarch, "NSString")); stringValue[1] = value_from_longest (type, lookup_child_selector (gdbarch, "stringWithCString:")); - nsstringValue = call_function_by_hand(function, NULL, 3, &stringValue[0]); + nsstringValue = call_function_by_hand(function, NULL, stringValue); } else error (_("NSString: internal error -- no way to create new NSString")); @@ -1189,7 +1188,7 @@ print_object_command (const char *args, int from_tty) if (function == NULL) error (_("Unable to locate _NSPrintForDebugger in child process")); - description = call_function_by_hand (function, NULL, 1, &object); + description = call_function_by_hand (function, NULL, object); string_addr = value_as_long (description); if (string_addr == 0) diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index fe2adcc..d21c2fa 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -917,10 +917,10 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords) TRY { scoped_value_mark free_values; - struct value *return_value; - return_value = call_function_by_hand (function, NULL, - args_count, vargs); + value *return_value + = call_function_by_hand (function, NULL, + gdb::make_array_view (vargs, args_count)); result = value_to_value_object (return_value); } CATCH (except, RETURN_MASK_ALL) diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index 0a327ee..5099185 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -1172,7 +1172,7 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside) if (noside == EVAL_AVOID_SIDE_EFFECTS) result = value_zero (TYPE_TARGET_TYPE (fn_type), not_lval); else - result = call_function_by_hand (function, NULL, num_args + 1, args.data ()); + result = call_function_by_hand (function, NULL, args); return result; } diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index 1020167..78a93e3 100644 --- a/gdb/spu-tdep.c +++ b/gdb/spu-tdep.c @@ -2041,7 +2041,7 @@ flush_ea_cache (void) type = lookup_pointer_type (type); addr = BMSYMBOL_VALUE_ADDRESS (msymbol); - call_function_by_hand (value_from_pointer (type, addr), NULL, 0, NULL); + call_function_by_hand (value_from_pointer (type, addr), NULL, {}); } } diff --git a/gdb/unittests/array-view-selftests.c b/gdb/unittests/array-view-selftests.c index 3116ab2..74defa1 100644 --- a/gdb/unittests/array-view-selftests.c +++ b/gdb/unittests/array-view-selftests.c @@ -483,6 +483,19 @@ run_tests () gdb::array_view view_elem = elem; SELF_CHECK (view_elem.size () == 1); } + + /* gdb::make_array_view, int length. */ + { + gdb_byte data[] = {0x55, 0x66, 0x77, 0x88}; + int len = sizeof (data) / sizeof (data[0]); + auto view = gdb::make_array_view (data, len); + + SELF_CHECK (view.data () == data); + SELF_CHECK (view.size () == len); + + for (size_t i = 0; i < len; i++) + SELF_CHECK (view[i] == data[i]); + } } } /* namespace array_view_tests */ diff --git a/gdb/valarith.c b/gdb/valarith.c index 807cdd5..875f547 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -502,8 +502,8 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op, = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0]))); return value_zero (return_type, VALUE_LVAL (arg1)); } - return call_function_by_hand (argvec[0], NULL, 2 - static_memfuncp, - argvec + 1); + return call_function_by_hand (argvec[0], NULL, + {argvec + 1, 2u - static_memfuncp}); } throw_error (NOT_FOUND_ERROR, _("member function %s not found"), tstr); @@ -618,7 +618,8 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside) = TYPE_TARGET_TYPE (check_typedef (value_type (argvec[0]))); return value_zero (return_type, VALUE_LVAL (arg1)); } - return call_function_by_hand (argvec[0], NULL, nargs, argvec + 1); + return call_function_by_hand (argvec[0], NULL, + gdb::make_array_view (argvec + 1, nargs)); } throw_error (NOT_FOUND_ERROR, _("member function %s not found"), tstr); diff --git a/gdb/valops.c b/gdb/valops.c index c45caef..4758b5c 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -184,7 +184,7 @@ value_allocate_space_in_inferior (int len) struct value *blocklen; blocklen = value_from_longest (builtin_type (gdbarch)->builtin_int, len); - val = call_function_by_hand (val, NULL, 1, &blocklen); + val = call_function_by_hand (val, NULL, blocklen); if (value_logical_not (val)) { if (!target_has_execution) -- 2.7.4