/* Perform an inferior function call, for GDB, the GNU debugger.
- Copyright (C) 1986-2016 Free Software Foundation, Inc.
+ Copyright (C) 1986-2018 Free Software Foundation, Inc.
This file is part of GDB.
switch (TYPE_CODE (type))
{
case TYPE_CODE_REF:
+ case TYPE_CODE_RVALUE_REF:
{
struct value *new_value;
- if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
+ if (TYPE_IS_REFERENCE (arg_type))
return value_cast_pointers (type, arg, 0);
/* Cast the value to the reference's target type, and then
if the value was not previously in memory - in some cases
we should clearly be allowing this, but how? */
new_value = value_cast (TYPE_TARGET_TYPE (type), arg);
- new_value = value_ref (new_value);
+ new_value = value_ref (new_value, TYPE_CODE (type));
return new_value;
}
case TYPE_CODE_INT:
regcache);
}
+/* See infcall.h. */
+
+void
+error_call_unknown_return_type (const char *func_name)
+{
+ if (func_name != NULL)
+ error (_("'%s' has unknown return type; "
+ "cast the call to its declared return type"),
+ func_name);
+ else
+ error (_("function has unknown return type; "
+ "cast the call to its declared return type"));
+}
+
/* Fetch the name of the function at FUNADDR.
This is used in printing an error message for call_function_by_hand.
BUF is used to print FUNADDR in hex if the function name cannot be
if (stop_stack_dummy == STOP_STACK_DUMMY)
{
- struct cleanup *old_chain;
-
/* Done. */
thread_fsm_set_finished (self);
f->return_value = get_call_return_value (&f->return_meta_info);
/* Break out of wait_sync_command_done. */
- old_chain = make_cleanup_restore_current_ui ();
- current_ui = f->waiting_ui;
- target_terminal_ours ();
+ scoped_restore save_ui = make_scoped_restore (¤t_ui, f->waiting_ui);
+ target_terminal::ours ();
f->waiting_ui->prompt_state = PROMPT_NEEDED;
-
- /* This restores the previous UI. */
- do_cleanups (old_chain);
}
return 1;
/* See infcall.h. */
struct value *
-call_function_by_hand (struct value *function, int nargs, struct value **args)
+call_function_by_hand (struct value *function,
+ type *default_return_type,
+ int nargs, struct value **args)
{
- return call_function_by_hand_dummy (function, nargs, args, NULL, NULL);
+ return call_function_by_hand_dummy (function, default_return_type,
+ nargs, args, NULL, NULL);
}
/* All this stuff with a dummy frame may seem unnecessarily complicated
struct value *
call_function_by_hand_dummy (struct value *function,
+ type *default_return_type,
int nargs, struct value **args,
dummy_frame_dtor_ftype *dummy_dtor,
void *dummy_dtor_data)
}
funaddr = find_function_addr (function, &values_type);
- if (!values_type)
- values_type = builtin_type (gdbarch)->builtin_int;
+ if (values_type == NULL)
+ values_type = default_return_type;
+ if (values_type == NULL)
+ {
+ const char *name = get_function_name (funaddr,
+ name_buf, sizeof (name_buf));
+ error (_("'%s' has unknown return type; "
+ "cast the call to its declared return type"),
+ name);
+ }
values_type = check_typedef (values_type);
prototyped. Can we respect TYPE_VARARGS? Probably not. */
if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
prototyped = 1;
+ if (TYPE_TARGET_TYPE (ftype) == NULL && TYPE_NFIELDS (ftype) == 0
+ && default_return_type != NULL)
+ {
+ /* Calling a no-debug function with the return type
+ explicitly cast. Assume the function is prototyped,
+ with a prototype matching the types of the arguments.
+ E.g., with:
+ float mult (float v1, float v2) { return v1 * v2; }
+ This:
+ (gdb) p (float) mult (2.0f, 3.0f)
+ Is a simpler alternative to:
+ (gdb) p ((float (*) (float, float)) mult) (2.0f, 3.0f)
+ */
+ prototyped = 1;
+ }
else if (i < TYPE_NFIELDS (ftype))
prototyped = TYPE_PROTOTYPED (ftype);
else
inferior. That way it breaks when it returns. */
{
- struct breakpoint *bpt, *longjmp_b;
- struct symtab_and_line sal;
-
- init_sal (&sal); /* initialize to zeroes */
+ symtab_and_line sal;
sal.pspace = current_program_space;
sal.pc = bp_addr;
sal.section = find_pc_overlay (sal.pc);
+
/* Sanity. The exact same SP value is returned by
PUSH_DUMMY_CALL, saved as the dummy-frame TOS, and used by
dummy_id to form the frame ID's stack address. */
- bpt = set_momentary_breakpoint (gdbarch, sal, dummy_id, bp_call_dummy);
+ breakpoint *bpt
+ = set_momentary_breakpoint (gdbarch, sal,
+ dummy_id, bp_call_dummy).release ();
/* set_momentary_breakpoint invalidates FRAME. */
frame = NULL;
bpt->disposition = disp_del;
gdb_assert (bpt->related_breakpoint == bpt);
- longjmp_b = set_longjmp_breakpoint_for_call_dummy ();
+ breakpoint *longjmp_b = set_longjmp_breakpoint_for_call_dummy ();
if (longjmp_b)
{
/* Link BPT into the chain of LONGJMP_B. */
{
/* Make a copy as NAME may be in an objfile freed by dummy_frame_pop. */
- char *name = xstrdup (get_function_name (funaddr,
- name_buf, sizeof (name_buf)));
- make_cleanup (xfree, name);
-
+ std::string name = get_function_name (funaddr, name_buf,
+ sizeof (name_buf));
if (stopped_by_random_signal)
{
To change this behavior use \"set unwindonsignal off\".\n\
Evaluation of the expression containing the function\n\
(%s) will be abandoned."),
- name);
+ name.c_str ());
}
else
{
Evaluation of the expression containing the function\n\
(%s) will be abandoned.\n\
When the function is done executing, GDB will silently stop."),
- name);
+ name.c_str ());
}
}
To change this behaviour use \"set unwind-on-terminating-exception off\".\n\
Evaluation of the expression containing the function (%s)\n\
will be abandoned."),
- name);
+ name.c_str ());
}
else if (stop_stack_dummy == STOP_NONE)
{
Evaluation of the expression containing the function\n\
(%s) will be abandoned.\n\
When the function is done executing, GDB will silently stop."),
- name);
+ name.c_str ());
}
}
/* The above code errors out, so ... */
gdb_assert_not_reached ("... should not be here");
}
-\f
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-void _initialize_infcall (void);
void
_initialize_infcall (void)