diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0daf904f5b..58001dba6a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2003-11-19 Andrew Cagney + + * stack.c (return_command): Handle "void", "legacy" and "unknown + location" return values separatly. + * values.c (using_struct_return): Return 0 for a "void" return + type. Mention "register_value_being_returned". + (register_value_being_returned): Mention "using_struct_return". + 2003-11-19 Daniel Jacobowitz * dwarf2read.c (offreg, basereg, isderef, frame_base_reg) diff --git a/gdb/stack.c b/gdb/stack.c index dc8733ef15..db45284727 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1854,33 +1854,33 @@ return_command (char *retval_exp, int from_tty) if (VALUE_LAZY (return_value)) value_fetch_lazy (return_value); - /* Check that this architecture can handle the function's return - type. In the case of "struct convention", still do the - "return", just also warn the user. */ - if (gdbarch_return_value_p (current_gdbarch)) + if (TYPE_CODE (return_type) == TYPE_CODE_VOID) + /* If the return-type is "void", don't try to find the + return-value's location. However, do still evaluate the + return expression so that, even when the expression result + is discarded, side effects such as "return i++" still + occure. */ + return_value = NULL; + else if (!gdbarch_return_value_p (current_gdbarch) + && (TYPE_CODE (return_type) == TYPE_CODE_STRUCT + || TYPE_CODE (return_type) == TYPE_CODE_UNION)) { - if (gdbarch_return_value (current_gdbarch, return_type, - NULL, NULL, NULL) - == RETURN_VALUE_STRUCT_CONVENTION) - return_value = NULL; + /* NOTE: cagney/2003-10-20: Compatibility hack for legacy + code. Old architectures don't expect STORE_RETURN_VALUE + to be called with with a small struct that needs to be + stored in registers. Don't start doing it now. */ + query_prefix = "\ +A structure or union return type is not supported by this architecture.\n\ +If you continue, the return value that you specified will be ignored.\n"; + return_value = NULL; } - else + else if (using_struct_return (return_type, 0)) { - /* NOTE: cagney/2003-10-20: The double check is to ensure - that the STORE_RETURN_VALUE call, further down, is not - applied to a struct or union return-value. It wasn't - allowed previously, so don't start allowing it now. An - ABI that uses "register convention" to return small - structures and should implement the "return_value" - architecture method. */ - if (using_struct_return (return_type, 0) - || TYPE_CODE (return_type) == TYPE_CODE_STRUCT - || TYPE_CODE (return_type) == TYPE_CODE_UNION) - return_value = NULL; + query_prefix = "\ +The location at which to store the function's return value is unknown.\n\ +If you continue, the return value that you specified will be ignored.\n"; + return_value = NULL; } - if (return_value == NULL) - query_prefix = "\ -The location at which to store the function's return value is unknown.\n"; } /* Does an interactive user really want to do this? Include diff --git a/gdb/values.c b/gdb/values.c index a8d8480871..386e3bfaeb 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -1223,7 +1223,7 @@ register_value_being_returned (struct type *valtype, struct regcache *retbuf) struct value *val = allocate_value (valtype); /* If the function returns void, don't bother fetching the return - value. */ + value. See also "using_struct_return". */ if (TYPE_CODE (valtype) == TYPE_CODE_VOID) return val; @@ -1285,6 +1285,11 @@ using_struct_return (struct type *value_type, int gcc_p) if (code == TYPE_CODE_ERROR) error ("Function return type unknown."); + if (code == TYPE_CODE_VOID) + /* A void return value is never in memory. See also corresponding + code in "register_value_being_returned". */ + return 0; + if (!gdbarch_return_value_p (current_gdbarch)) { /* FIXME: cagney/2003-10-01: The below is dead. Instead an