diff options
Diffstat (limited to 'gdb/infcall.c')
-rw-r--r-- | gdb/infcall.c | 66 |
1 files changed, 51 insertions, 15 deletions
diff --git a/gdb/infcall.c b/gdb/infcall.c index 38335a7..d384d16 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -340,6 +340,20 @@ push_dummy_code (struct gdbarch *gdbarch, 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 @@ -530,7 +544,7 @@ call_thread_fsm_should_stop (struct thread_fsm *self, /* Break out of wait_sync_command_done. */ scoped_restore save_ui = make_scoped_restore (¤t_ui, f->waiting_ui); - target_terminal_ours (); + target_terminal::ours (); f->waiting_ui->prompt_state = PROMPT_NEEDED; } @@ -673,9 +687,12 @@ cleanup_delete_std_terminate_breakpoint (void *ignore) /* 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 @@ -698,6 +715,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args) 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) @@ -850,8 +868,16 @@ call_function_by_hand_dummy (struct value *function, } 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); @@ -955,6 +981,21 @@ call_function_by_hand_dummy (struct value *function, 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 @@ -1051,17 +1092,16 @@ call_function_by_hand_dummy (struct value *function, 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); /* set_momentary_breakpoint invalidates FRAME. */ frame = NULL; @@ -1069,7 +1109,7 @@ call_function_by_hand_dummy (struct value *function, 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. */ @@ -1372,10 +1412,6 @@ When the function is done executing, GDB will silently stop."), /* The above code errors out, so ... */ gdb_assert_not_reached ("... should not be here"); } - - -/* Provide a prototype to silence -Wmissing-prototypes. */ -void _initialize_infcall (void); void _initialize_infcall (void) |