Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA] Function return type checking
@ 2002-02-05  1:36 Klee Dienes
  2002-02-05  3:24 ` Eli Zaretskii
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Klee Dienes @ 2002-02-05  1:36 UTC (permalink / raw)
  To: gdb-patches

(This is basically the same patch I sent last week, just updated
to the latest source base.)

The following patch adds "expected return type" support to the target
function call interface.  The "expected return type" is specified
using cast syntax; it is ignored if actual type information for the
function is available.  If no type information is provided for a
function, the user is now required to provide an expected return type
using the cast syntax, or get an error.

Some examples:

(gdb) print fabs (3.0)                  (no type information present)
Unable to call function at 0x%lx: no return type information available.
To call this function anyway, you can cast the return type explicitly
(e.g. 'print (float) fabs (3.0)').

(gdb) print (float) fabs (-3.12)        (no type information present)
$1 = 3.11999989

(gdb) print (int) fabs (-3.12)          (no type information present)
$2 = 1074329026
(here, the return value of `fabs' has been interpreted as an int
... not cast to one)

(gdb) print (int) fabs (-3.12)          (type information present)
$3 = -3
(since type information was available, the return value was
interpreted as a float, then cast to an int).

(gdb) print (struct stat) fabs (-3.12)  (no type information present)
Cannot access memory at address 0xf5c28f6
(this causes an error, since the struct return convention is being
misused)

   struct s { int i; int j; };
   struct s f (void) { struct s ss = { 3, 1 }; return ss; }

(gdb) print f ()                        (no type information present)
Unable to call function at 0x%lx: no return type information available.
To call this function anyway, you can cast the return type explicitly
(e.g. 'print (float) fabs (3.0)').

(gdb) print (struct s) f (3.0)          (no type information present)
$4 = {i = 3, j = 1}

(gdb) print (float) f (3.0)             (no type information present)
Program received signal SIGSEGV, Segmentation fault.
0x0804841d in f ()
(here we lied to GDB about the return type, causing it to generate
incorrect struct return code).

Compare this to the old behavior:

(gdb) print fabs (3.0)                  (no type information present)
$1 = 1074266112
(GDB has no type information available, so it assumes 'int').

(gdb) print (float) fabs (-3.12)        (no type information present)
$2 = 1.07426611e+09
(GDB still assumes the function returns 'int', then casts the result
to a float).

   struct s { int i; int j; };
   struct s f (void) { struct s ss = { 3, 1 }; return ss; }

(gdb) print f ()
Program received signal SIGSEGV, Segmentation fault.
0x0804841d in f ()
(here there is no way out ... no matter what we pass in as the return
value to f(), GDB will generate the calling convention for a function
returning int)

The reason I suggest 2) might be controversial is that the old
behavior can be convenient in the general case.  A lot of functions
*do* return int, and when debugging programs without symbols, it can
be annoying to have to declare the return type, just to make the rare
case when functions return floats/structs behave correctly.  But I'd
argue that it's not *that* big a deal to cast a return value, and
correctness must always take priority.

2002-02-04  Klee Dienes <kdienes@apple.com>

         * c-valprint.c (c_val_print): print type with typecode 
TYPE_CODE_ERROR
         as "<error type>" and not "<unknown type>".

         * eval.c (evaluate_subexp_standard): when called with
         EVAL_AVOID_SIDE_EFFECTS, return the passed-in `expect_type' if 
the
         type of the evaluated expression is unknown.  Also update to use
         the new `call_function_by_hand_expecting_type' interface.

         * gcore.c (default_derive_heap_segment): update to pass type 
argument
         to find_function_in_inferior.

         * gdbtypes.c, gdbtypes.h: add new type
         builtin_type_voidptrfuncptr.

         * parse.c, parse.h: export msym_{text,data,unknown}_symbol_type.
         Make them of type TYPE_CODE_ERROR instead of TYPE_CODE_INT.

         * parser-defs.h: export msym_{text,data,unknown}_symbol_type.

         * scm-lang.c (scm_lookup_name): update to use new interface to
         find_function_in_inferior.

         * valops.c (find_function_in_inferior): add a default type as 
second
         argument.  This type will be used for the returned value if no
         type information is available for the function (previously, the
         type was assumed to be (char *) (*).
         (hand_function_call): add new `expect_type' parameter.  This type
         will be used as the return type for the function if no type
         information is available.
         (call_function_by_hand_expecting_type): like
         call_function_by_hand, but uses the new `expect_type' interface 
to
         hand_function_call.
         (call_function_by_hand): implement as a wrapper to
         call_function_by_hand_expecting_type.
         (value_allocate_space_in_inferior): use new cached_function
         interface.
         (find_function_addr): if asked the return type of a function with
         type TYPE_CODE_ERROR, return TYPE_CODE_ERROR.

         * value.h (call_function_by_hand_expecting_type): add.
         (find_function_in_inferior) update to new signature.

Index: gdb/c-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-valprint.c,v
retrieving revision 1.12
diff -u -r1.12 c-valprint.c
--- c-valprint.c        2002/02/04 02:14:46     1.12
+++ c-valprint.c        2002/02/05 06:22:27
@@ -453,7 +453,7 @@
        break;

      case TYPE_CODE_ERROR:
-      fprintf_filtered (stream, "<error type>");
+      fprintf_filtered (stream, "<unknown type>");
        break;

      case TYPE_CODE_UNDEF:
Index: gdb/eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.19
diff -u -r1.19 eval.c
--- eval.c      2002/01/04 17:51:38     1.19
+++ eval.c      2002/02/05 06:22:29
@@ -928,15 +928,20 @@
              gdb isn't asked for it's opinion (ie. through "whatis"),
              it won't offer it. */

-         struct type *ftype =
-         TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]));
-
-         if (ftype)
-           return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE 
(argvec[0])));
-         else
-           error ("Expression of type other than \"Function 
returning ...\" used as function");
+         struct type *type =
+           TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]));
+
+         if (type)
+           {
+             if ((TYPE_CODE (type) == TYPE_CODE_ERROR) && expect_type)
+               return allocate_value (expect_type);
+             else
+               return allocate_value (type);
+           }
+         else
+            error ("Expression of type other than \"Function 
returning ...\" used as function");
         }
-      return call_function_by_hand (argvec[0], nargs, argvec + 1);
+      return call_function_by_hand_expecting_type (argvec[0], 
expect_type, nargs, argvec + 1);
        /* pai: FIXME save value from call_function_by_hand, then adjust 
pc by adjust_fn_pc if +ve  */

      case OP_F77_UNDETERMINED_ARGLIST:
Index: gdb/gcore.c
===================================================================
RCS file: /cvs/src/src/gdb/gcore.c,v
retrieving revision 1.3
diff -u -r1.3 gcore.c
--- gcore.c     2002/01/14 20:00:48     1.3
+++ gcore.c     2002/02/05 06:22:30
@@ -274,7 +274,7 @@
         }
      }
    /* Now get the top-of-heap by calling sbrk in the inferior.  */
-  if ((sbrk = find_function_in_inferior ("sbrk")) == NULL)
+  if ((sbrk = find_function_in_inferior ("sbrk", 
builtin_type_voidptrfuncptr)) == NULL)
      return 0;
    if ((zero = value_from_longest (builtin_type_int, (LONGEST) 0)) == 
NULL)
      return 0;
Index: gdb/gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.40
diff -u -r1.40 gdbtypes.c
--- gdbtypes.c  2002/02/03 23:18:11     1.40
+++ gdbtypes.c  2002/02/05 06:22:33
@@ -99,6 +99,7 @@
  struct type *builtin_type_void_func_ptr;
  struct type *builtin_type_CORE_ADDR;
  struct type *builtin_type_bfd_vma;
+struct type *builtin_type_voidptrfuncptr;

  int opaque_type_resolution = 1;
  int overload_debug = 0;
@@ -3290,6 +3291,8 @@
      init_type (TYPE_CODE_INT, TARGET_BFD_VMA_BIT / 8,
                TYPE_FLAG_UNSIGNED,
                "__bfd_vma", (struct objfile *) NULL);
+  builtin_type_voidptrfuncptr =
+    lookup_pointer_type (lookup_function_type (lookup_pointer_type 
(builtin_type_void)));
  }


Index: gdb/gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.26
diff -u -r1.26 gdbtypes.h
--- gdbtypes.h  2002/02/03 22:57:56     1.26
+++ gdbtypes.h  2002/02/05 06:22:35
@@ -934,6 +934,7 @@
     bit address type even though the TARGET has a 64 bit pointer type
     (cf MIPS). */
  extern struct type *builtin_type_bfd_vma;
+extern struct type *builtin_type_voidptrfuncptr;

  /* Explicit sizes - see C9X <intypes.h> for naming scheme */
  extern struct type *builtin_type_int8;
Index: gdb/parse.c
===================================================================
RCS file: /cvs/src/src/gdb/parse.c,v
retrieving revision 1.19
diff -u -r1.19 parse.c
--- parse.c     2002/01/31 02:13:56     1.19
+++ parse.c     2002/02/05 06:22:37
@@ -382,9 +382,9 @@
     based on the language, but they no longer have names like "int", so
     the initial rationale is gone.  */

-static struct type *msym_text_symbol_type;
-static struct type *msym_data_symbol_type;
-static struct type *msym_unknown_symbol_type;
+struct type *msym_text_symbol_type;
+struct type *msym_data_symbol_type;
+struct type *msym_unknown_symbol_type;

  void
  write_exp_msymbol (struct minimal_symbol *msymbol,
@@ -1341,16 +1341,15 @@
  {
    int i;

-  msym_text_symbol_type =
-    init_type (TYPE_CODE_FUNC, 1, 0, "<text variable, no debug info>", 
NULL);
-  TYPE_TARGET_TYPE (msym_text_symbol_type) = builtin_type_int;
-  msym_data_symbol_type =
-    init_type (TYPE_CODE_INT, TARGET_INT_BIT / HOST_CHAR_BIT, 0,
-              "<data variable, no debug info>", NULL);
-  msym_unknown_symbol_type =
-    init_type (TYPE_CODE_INT, 1, 0,
-              "<variable (not text or data), no debug info>",
-              NULL);
+   msym_text_symbol_type =
+    init_type (TYPE_CODE_FUNC, 0, 0, "<text variable, no debug info>", 
NULL);
+   TYPE_TARGET_TYPE (msym_text_symbol_type) = builtin_type_error;
+   msym_data_symbol_type =
+     init_type (TYPE_CODE_ERROR, 0, 0,
+               "<data variable, no debug info>", NULL);
+   msym_unknown_symbol_type =
+     init_type (TYPE_CODE_ERROR, 0, 0,
+               "<variable (not text or data), no debug info>", NULL);

    /* create the std_regs table */

Index: gdb/parser-defs.h
===================================================================
RCS file: /cvs/src/src/gdb/parser-defs.h,v
retrieving revision 1.6
diff -u -r1.6 parser-defs.h
--- parser-defs.h       2001/11/15 01:55:59     1.6
+++ parser-defs.h       2002/02/05 06:22:37
@@ -39,6 +39,10 @@
  extern int expout_size;
  extern int expout_ptr;

+extern struct type *msym_text_symbol_type;
+extern struct type *msym_data_symbol_type;
+extern struct type *msym_unknown_symbol_type;
+
  /* If this is nonzero, this block is used as the lexical context
     for symbol names.  */

Index: gdb/scm-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/scm-lang.c,v
retrieving revision 1.7
diff -u -r1.7 scm-lang.c
--- scm-lang.c  2002/01/04 05:20:08     1.7
+++ scm-lang.c  2002/02/05 06:22:37
@@ -169,7 +169,7 @@
      /* FIXME in this case, we should try lookup_symbol first */
      args[2] = value_from_longest (builtin_type_scm, SCM_EOL);

-  func = find_function_in_inferior ("scm_lookup_cstr");
+  func = find_function_in_inferior ("scm_lookup_cstr", 
builtin_type_voidptrfuncptr);
    val = call_function_by_hand (func, 3, args);
    if (!value_logical_not (val))
      return value_ind (val);
@@ -192,7 +192,7 @@
    write_memory (iaddr, str, len);
    /* FIXME - should find and pass env */
    write_memory (iaddr + len, "", 1);
-  func = find_function_in_inferior ("scm_evstr");
+  func = find_function_in_inferior ("scm_evstr", 
builtin_type_voidptrfuncptr);
    return call_function_by_hand (func, 1, &addr);
  }

Index: gdb/valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.50
diff -u -r1.50 valops.c
--- valops.c    2002/02/04 02:14:46     1.50
+++ valops.c    2002/02/05 06:22:41
@@ -32,6 +32,7 @@
  #include "language.h"
  #include "gdbcmd.h"
  #include "regcache.h"
+#include "parser-defs.h"
  #include "cp-abi.h"

  #include <errno.h>
@@ -46,7 +47,7 @@

  static int typecmp (int staticp, struct type *t1[], struct value *t2[]);

-static CORE_ADDR find_function_addr (struct value *, struct type **);
+CORE_ADDR find_function_addr (struct value *, struct type **);
  static struct value *value_arg_coerce (struct value *, struct type *, 
int);


@@ -89,11 +90,13 @@
  int unwind_on_signal_p = 0;



-
-/* Find the address of function name NAME in the inferior.  */
-
-struct value *
-find_function_in_inferior (char *name)
+/* Find the address of function name NAME in the inferior.  If no type
+   information is available for NAME, use `type' as the type for the
+   resulting value.
+*/
+
+struct value *
+find_function_in_inferior (char *name, struct type *type)
  {
    register struct symbol *sym;
    sym = lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
@@ -111,20 +114,18 @@
        struct minimal_symbol *msymbol = lookup_minimal_symbol (name, 
NULL, NULL);
        if (msymbol != NULL)
         {
-         struct type *type;
-         CORE_ADDR maddr;
-         type = lookup_pointer_type (builtin_type_char);
-         type = lookup_function_type (type);
-         type = lookup_pointer_type (type);
-         maddr = SYMBOL_VALUE_ADDRESS (msymbol);
-         return value_from_pointer (type, maddr);
+         if (type != NULL)
+           return value_from_longest (type, (LONGEST) 
SYMBOL_VALUE_ADDRESS (msymbol));
+         else
+           return value_from_longest (lookup_pointer_type 
(msym_text_symbol_type),
+                                      (LONGEST) SYMBOL_VALUE_ADDRESS 
(msymbol));
         }
        else
         {
           if (!target_has_execution)
             error ("evaluation of this expression requires the target 
program to be active");
           else
-           error ("evaluation of this expression requires the program 
to have a function \"%s\".", name);
+           error ("evaluation of this expression requires the program 
to have a function named \"%s\".", name);
         }
      }
  }
@@ -136,10 +137,10 @@
  value_allocate_space_in_inferior (int len)
  {
    struct value *blocklen;
-  struct value *val = find_function_in_inferior ("malloc");
+  struct value *val = find_function_in_inferior ("malloc", 
builtin_type_voidptrfuncptr);

    blocklen = value_from_longest (builtin_type_int, (LONGEST) len);
-  val = call_function_by_hand (val, 1, &blocklen);
+  val = call_function_by_hand (val, 1, &blocklen);
    if (value_logical_not (val))
      {
        if (!target_has_execution)
@@ -1261,6 +1262,11 @@

        value_type = builtin_type_int;
      }
+  else if (code == TYPE_CODE_ERROR)
+    {
+      value_type = builtin_type_error;
+      funaddr = (CORE_ADDR) -1;
+    }
    else
      error ("Invalid data type for function to be called.");

@@ -1287,7 +1293,8 @@
     ARGS is modified to contain coerced values. */

  static struct value *
-hand_function_call (struct value *function, int nargs, struct value 
**args)
+hand_function_call (struct value *function,
+                   struct type *expect_type, int nargs, struct value 
**args)
  {
    register CORE_ADDR sp;
    register int i;
@@ -1334,6 +1341,33 @@
    inf_status = save_inferior_status (1);
    old_chain = make_cleanup_restore_inferior_status (inf_status);

+  funaddr = find_function_addr (function, &value_type);
+  CHECK_TYPEDEF (value_type);
+
+  if ((value_type == NULL) || (value_type->code == TYPE_CODE_ERROR))
+    value_type = expect_type;
+
+  if ((value_type == NULL) || (value_type->code == TYPE_CODE_ERROR))
+    error ("Unable to call function at 0x%lx: no return type 
information available.\n"
+           "To call this function anyway, you can cast the return type 
explicitly\n"
+          "(e.g. 'print (float) fabs (3.0)')",
+           (unsigned long) funaddr);
+
+  CHECK_TYPEDEF (value_type);
+
+  {
+    struct block *b = block_for_pc (funaddr);
+    /* If compiled without -g, assume GCC 2.  */
+    using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
+  }
+
+  /* Are we returning a value using a structure return or a normal
+     value return? */
+
+  struct_return = using_struct_return (function, funaddr, value_type,
+                                      using_gcc);
+
+
    /* PUSH_DUMMY_FRAME is responsible for saving the inferior registers
       (and POP_FRAME for restoring them).  (At least on most machines)
       they are saved on the stack in the inferior.  */
@@ -1354,21 +1388,6 @@
        sp += sizeof_dummy1;
      }

-  funaddr = find_function_addr (function, &value_type);
-  CHECK_TYPEDEF (value_type);
-
-  {
-    struct block *b = block_for_pc (funaddr);
-    /* If compiled without -g, assume GCC 2.  */
-    using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
-  }
-
-  /* Are we returning a value using a structure return or a normal
-     value return? */
-
-  struct_return = using_struct_return (function, funaddr, value_type,
-                                      using_gcc);
-
    /* Create a call sequence customized for this function
       and the number of arguments for it.  */
    for (i = 0; i < (int) (SIZEOF_CALL_DUMMY_WORDS / sizeof (dummy[0])); 
i++)
@@ -1786,16 +1805,24 @@
  }

  struct value *
-call_function_by_hand (struct value *function, int nargs, struct value 
**args)
+call_function_by_hand_expecting_type (struct value *function,
+                                     struct type *expect_type,
+                                     int nargs, struct value **args)
  {
    if (CALL_DUMMY_P)
      {
-      return hand_function_call (function, nargs, args);
+      return hand_function_call (function, expect_type, nargs, args);
      }
    else
      {
        error ("Cannot invoke functions on this machine.");
      }
+}
+
+struct value *
+call_function_by_hand (struct value *function, int nargs, struct value 
**args)
+{
+  return call_function_by_hand_expecting_type (function, NULL, nargs, 
args);
  }



Index: gdb/value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.26
diff -u -r1.26 value.h
--- value.h     2002/01/04 23:21:38     1.26
+++ value.h     2002/02/05 06:22:42
@@ -551,6 +551,11 @@

  extern struct value *value_slice (struct value *, int, int);

+extern struct value *
+call_function_by_hand_expecting_type (struct value *,
+                                     struct type *, int,
+                                     struct value **);
+
  extern struct value *call_function_by_hand (struct value *, int,
                                             struct value **);

@@ -564,7 +569,9 @@
  extern void find_rt_vbase_offset (struct type *, struct type *, char *, 
int,
                                   int *, int *);

-extern struct value *find_function_in_inferior (char *);
+extern CORE_ADDR find_function_addr (struct value *, struct type **);
+
+extern struct value *find_function_in_inferior (char *, struct type *);

  extern struct value *value_allocate_space_in_inferior (int);

Index: gdb/testsuite/gdb.asm/asm-source.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.asm/asm-source.exp,v
retrieving revision 1.17
diff -u -r1.17 asm-source.exp
--- asm-source.exp      2002/01/18 00:13:00     1.17
+++ asm-source.exp      2002/02/05 06:22:44
@@ -220,10 +220,12 @@
         "Make selected stack frame return now\?.*" "y"

  # See if we can look at a global variable
-gdb_test "print globalvar" ".* = 11" "look at global variable"
+gdb_test "print globalvar" ".* = (11|<unknown type>)" "look at global 
variable"
+gdb_test "print (int) globalvar" ".* = 11" "look at global variable"

  # See if we can look at a static variable
-gdb_test "print staticvar" ".* = 5" "look at static variable"
+gdb_test "print staticvar" ".* = (5|<unknown type>)" "look at static 
variable"
+gdb_test "print (int) staticvar" ".* = 5" "look at static variable"

  # See if we can look at a static function
  gdb_test "disassem foostatic" ".*<foostatic>:.*End of assembler dump." \
Index: gdb/testsuite/gdb.base/nodebug.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/nodebug.exp,v
retrieving revision 1.2
diff -u -r1.2 nodebug.exp
--- nodebug.exp 2001/03/06 08:21:50     1.2
+++ nodebug.exp 2002/02/05 06:22:47
@@ -77,23 +77,24 @@
      gdb_test "whatis top" \
         "(<(text variable|function), no debug info>|short 
\\(int\\)|short \\(\\))"
      if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
-    gdb_test "ptype top" "(short|int) \\((|void|int|<non-float 
parameter>|<non-float parameter>, <non-float parameter>)\\)"
+    gdb_test "ptype top" "(short|int|<unknown type>) 
\\((|void|int|<non-float parameter>|<non-float parameter>, <non-float 
parameter>)\\)"

      if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix5*" }
      setup_xfail "mips-sgi-irix6*"
      gdb_test "p middle" \
-       "\{(<(text variable|function), no debug info>|short 
\\(int\\)|short \\(\\))\} \[0-9a-fx]* <middle(\\(int\\)|)>"
+       "\{(<(text variable|function), no debug info>|short|<unknown 
type> \\(int\\)|short \\(\\))\} \[0-9a-fx]* <middle(\\(int\\)|)>"
      if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix5*" }
      setup_xfail "mips-sgi-irix6*"
      gdb_test "whatis middle" \
-       "(<(text variable|function), no debug info>|short 
\\(int\\)|short \\(\\))"
+       "(<(text variable|function), no debug info>|short|<unknown type> 
\\(int\\)|short \\(\\))"
      setup_xfail "mips-sgi-irix6*"
-    gdb_test "ptype middle" "(short|int) \\((|void|int|<non-float 
parameter>|<non-float parameter>, <non-float parameter>)\\)"
+    gdb_test "ptype middle" "(short|int|<unknown type>) 
\\((|void|int|<non-float parameter>|<non-float parameter>, <non-float 
parameter>)\\)"

-    gdb_test "p dataglobal" "= 3"
+    gdb_test "p dataglobal" "(= 3|<unknown type>)"
+    gdb_test "p (int) dataglobal" "= 3"
      gdb_test "whatis dataglobal" \
-       "<(data variable|variable), no debug info>|int"
-    gdb_test "ptype dataglobal" "<(data variable|variable), no debug 
info>|int"
+       "<(data variable|variable), no debug info>|int|<unknown type>"
+    gdb_test "ptype dataglobal" "<(data variable|variable), no debug 
info>|int|<unknown type>"

      # The only symbol xcoff puts out for statics is for the TOC entry.
      # Possible, but hairy, for gdb to deal.  Right now it doesn't, it
@@ -102,37 +103,40 @@
      setup_xfail "powerpc*-*-aix*"
      if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
      if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
-    gdb_test "p datalocal" "= 4"
+    gdb_test "p datalocal" "(= 4|<unknown type>)"
+    gdb_test "p (int) datalocal" "4"
      setup_xfail "rs6000*-*-aix*"
      setup_xfail "powerpc*-*-aix*"
      if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
      if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
-    gdb_test "whatis datalocal" "<(data variable|variable), no debug 
info>"
+    gdb_test "whatis datalocal" "<(data variable|variable), no debug 
info>|<unknown type>"
      setup_xfail "rs6000*-*-aix*"
      setup_xfail "powerpc*-*-aix*"
      if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
      if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
-    gdb_test "ptype datalocal" "<(data variable|variable), no debug 
info>"
+    gdb_test "ptype datalocal" "<(data variable|variable), no debug 
info>|<unknown type>"

-    gdb_test "p bssglobal" "= 0"
-    gdb_test "whatis bssglobal" "<(data variable|variable), no debug 
info>|int"
-    gdb_test "ptype bssglobal" "<(data variable|variable), no debug 
info>|int"
+    gdb_test "p bssglobal" "(= 0|<unknown type>)"
+    gdb_test "p (int) bssglobal" "= 0"
+    gdb_test "whatis bssglobal" "<(data variable|variable), no debug 
info>|<unknown type>|int"
+    gdb_test "ptype bssglobal" "<(data variable|variable), no debug 
info>|<unknown type>|int"

      setup_xfail "rs6000*-*-aix*"
      setup_xfail "powerpc*-*-aix*"
      if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
      if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
-    gdb_test "p bsslocal" "= 0"
+    gdb_test "p bsslocal" "(= 0|<unknown type>)"
+    gdb_test "p (int) bsslocal" "= 0"
      setup_xfail "rs6000*-*-aix*"
      setup_xfail "powerpc*-*-aix*"
      if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
      if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
-    gdb_test "whatis bsslocal" "<(data variable|variable), no debug 
info>"
+    gdb_test "whatis bsslocal" "<(data variable|variable), no debug 
info>|<unknown type>"
      setup_xfail "rs6000*-*-aix*"
      setup_xfail "powerpc*-*-aix*"
      if {!$gcc_compiled} then { setup_xfail "hppa*-*-hpux*" }
      if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
-    gdb_test "ptype bsslocal" "<(data variable|variable), no debug 
info>"
+    gdb_test "ptype bsslocal" "<(data variable|variable), no debug 
info>|<unknown type>"

      if {$gcc_compiled} then { setup_xfail "mips-sgi-irix6*" }
      gdb_test "backtrace 10" 
"#0.*inner.*#1.*middle.*#2.*top.*#3.*main.*" \
@@ -167,7 +171,9 @@
             # We need to up this because this can be really slow on some 
boards.
             # (malloc() is called as part of the test).
             set timeout 60;
-           gdb_test {p/c array_index("abcdef",2)} " = 99 'c'"
+            gdb_test {p/c (int) array_index("abcdef",2)} " = 99 'c'"
+            gdb_test {p/c array_index("abcdef",2)} \
+               "Unable to call function .* no return type information 
available.*"
         }
      }


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-02-05  1:36 [RFA] Function return type checking Klee Dienes
@ 2002-02-05  3:24 ` Eli Zaretskii
  2002-02-05  8:07 ` Daniel Jacobowitz
  2002-02-08 13:41 ` Kevin Buettner
  2 siblings, 0 replies; 11+ messages in thread
From: Eli Zaretskii @ 2002-02-05  3:24 UTC (permalink / raw)
  To: Klee Dienes; +Cc: gdb-patches


On Tue, 5 Feb 2002, Klee Dienes wrote:

> The following patch adds "expected return type" support to the target
> function call interface.  The "expected return type" is specified
> using cast syntax; it is ignored if actual type information for the
> function is available.  If no type information is provided for a
> function, the user is now required to provide an expected return type
> using the cast syntax, or get an error.

I don't know whether we want this behavior, but if this patch is 
accepted, these subtleties surely need to be documented in the user's 
manual.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-02-05  1:36 [RFA] Function return type checking Klee Dienes
  2002-02-05  3:24 ` Eli Zaretskii
@ 2002-02-05  8:07 ` Daniel Jacobowitz
  2002-02-06 13:43   ` Klee Dienes
  2002-02-08 13:41 ` Kevin Buettner
  2 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2002-02-05  8:07 UTC (permalink / raw)
  To: Klee Dienes; +Cc: gdb-patches

On Tue, Feb 05, 2002 at 01:36:41AM -0800, Klee Dienes wrote:
> (This is basically the same patch I sent last week, just updated
> to the latest source base.)
> 
> The following patch adds "expected return type" support to the target
> function call interface.  The "expected return type" is specified
> using cast syntax; it is ignored if actual type information for the
> function is available.  If no type information is provided for a
> function, the user is now required to provide an expected return type
> using the cast syntax, or get an error.

Having thought about this since you last posted it, I don't really like
it.  What you do by overloading the cast syntax for this operation is
very ``cute'', but exceedingly unintuitive.

> Some examples:
> 
> (gdb) print fabs (3.0)                  (no type information present)
> Unable to call function at 0x%lx: no return type information available.
> To call this function anyway, you can cast the return type explicitly
> (e.g. 'print (float) fabs (3.0)').

Except for the syntax of the example, I like this message.  This is a
good message.  We need more warnings about doing things like this.

Fabs is a bad example, though - can I suggest you look over the list of
what GCC defines as builtin functions, and not choose one?

> The reason I suggest 2) might be controversial is that the old
> behavior can be convenient in the general case.  A lot of functions
> *do* return int, and when debugging programs without symbols, it can
> be annoying to have to declare the return type, just to make the rare
> case when functions return floats/structs behave correctly.  But I'd
> argue that it's not *that* big a deal to cast a return value, and
> correctness must always take priority.

Losing the implicit int doesn't bother me especially.

Have you considered casting the function itself?  Something like:
(gdb) print ((float (*)(float)) fabs) (3.0)
$1 = 3.0
(gdb) set fabs

Which, I will note, already works except for the fact that we neglect
the argument types on function pointers.  Or
(gdb) set $fabs = (float (*)(float)) fabs
(gdb) p $fabs(4.0)
$2 = 4.0

Which works with the same caveat.

Specifying just the return type of the function is not useful in the
general case.  If we do not understand the argument types, it will
still crash.  I was trying to find an example where float vs. double
would cause a problem too, but I can't think of one at the moment. 
There's one in the testsuite though, for some targets.

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-02-05  8:07 ` Daniel Jacobowitz
@ 2002-02-06 13:43   ` Klee Dienes
  2002-02-06 14:14     ` Daniel Jacobowitz
  2002-03-09 20:30     ` Andrew Cagney
  0 siblings, 2 replies; 11+ messages in thread
From: Klee Dienes @ 2002-02-06 13:43 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Klee Dienes, gdb-patches

On Tuesday, February 5, 2002, at 08:07 AM, Daniel Jacobowitz wrote:

> Have you considered casting the function itself?  Something like:
> (gdb) print ((float (*)(float)) fabs) (3.0)
> $1 = 3.0
> (gdb) set fabs
>
> Which, I will note, already works except for the fact that we neglect
> the argument types on function pointers.  Or
> (gdb) set $fabs = (float (*)(float)) fabs
> (gdb) p $fabs(4.0)
> $2 = 4.0

We have; for a long time that was the answer we gave to people who were 
running into this problem.  Our experience was that it was a nightmare 
to explain to people how this mechanism worked, and that even for folks 
who did undertand it, they found it a major mental burden to use in 
practice.  C function casting syntax is neither intuitive nor pleasant 
to type.

The reason we chose the "cast" syntax wasn't so much to be cute, but 
because it was the first thing everyone tried when they were trying to 
get this to work.  People would try 'print (float) fabs (3.0)', followed 
by 'print {float} fabs (3.0)', usually followed by several unsuccessful 
attemtps to remember the correct syntax to cast the function pointer.

I also think there's a pretty solid rationale behind the syntax, and one 
that generalizes to argument-passing.  The theory goes:

All symbols without debugging information are assumed to be of type 
'unknown' (previously, they were assumed to be 'int', or (int (*) ())).  
When you cast an expression of type 'unknown' to anything else, GDB does 
no conversion, but simply interprets the data (or generates the data) 
according to the specified type.  So if you have 'f' with no symbols,

   print (long long) f ((long long) 7, (float) 3.0)

will generate a function call as if 'f' had been declared as

   long long f (long long, float)

For function arguments, I claim this is both intuitive and matches the 
behavior of the C compiler.  For function return values, wee have to 
choose something for what 'print (type) f ()' is to mean, and I claim 
that it's the best of the two alternatives (the other being "assume 
'int', then cast the 'int' to the specified type).


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-02-06 13:43   ` Klee Dienes
@ 2002-02-06 14:14     ` Daniel Jacobowitz
  2002-03-09 20:30     ` Andrew Cagney
  1 sibling, 0 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2002-02-06 14:14 UTC (permalink / raw)
  To: Klee Dienes; +Cc: Klee Dienes, gdb-patches

On Wed, Feb 06, 2002 at 01:43:45PM -0800, Klee Dienes wrote:
> On Tuesday, February 5, 2002, at 08:07 AM, Daniel Jacobowitz wrote:
> 
> >Have you considered casting the function itself?  Something like:
> >(gdb) print ((float (*)(float)) fabs) (3.0)
> >$1 = 3.0
> >(gdb) set fabs
> >
> >Which, I will note, already works except for the fact that we neglect
> >the argument types on function pointers.  Or
> >(gdb) set $fabs = (float (*)(float)) fabs
> >(gdb) p $fabs(4.0)
> >$2 = 4.0
> 
> We have; for a long time that was the answer we gave to people who were 
> running into this problem.  Our experience was that it was a nightmare 
> to explain to people how this mechanism worked, and that even for folks 
> who did undertand it, they found it a major mental burden to use in 
> practice.  C function casting syntax is neither intuitive nor pleasant 
> to type.
> 
> The reason we chose the "cast" syntax wasn't so much to be cute, but 
> because it was the first thing everyone tried when they were trying to 
> get this to work.  People would try 'print (float) fabs (3.0)', followed 
> by 'print {float} fabs (3.0)', usually followed by several unsuccessful 
> attemtps to remember the correct syntax to cast the function pointer.
> 
> I also think there's a pretty solid rationale behind the syntax, and one 
> that generalizes to argument-passing.  The theory goes:

OK, I buy that.  I'm still a little unhappy about the two possible
meanings of (int) fabs(3.0) - but it seems like a good compromise to
allow this syntax too.  Thanks for the clarification.

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-02-05  1:36 [RFA] Function return type checking Klee Dienes
  2002-02-05  3:24 ` Eli Zaretskii
  2002-02-05  8:07 ` Daniel Jacobowitz
@ 2002-02-08 13:41 ` Kevin Buettner
  2 siblings, 0 replies; 11+ messages in thread
From: Kevin Buettner @ 2002-02-08 13:41 UTC (permalink / raw)
  To: Klee Dienes, gdb-patches

On Feb 5,  1:36am, Klee Dienes wrote:

> The following patch adds "expected return type" support to the target
> function call interface.  The "expected return type" is specified
> using cast syntax; it is ignored if actual type information for the
> function is available.  If no type information is provided for a
> function, the user is now required to provide an expected return type
> using the cast syntax, or get an error.

I've read through your explanation and the ensuing discussion to date. 
Though I haven't reviewed the actual patch, I think this idea makes
sense and recommend that the maintainers give it serious
consideration.

Kevin


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-02-06 13:43   ` Klee Dienes
  2002-02-06 14:14     ` Daniel Jacobowitz
@ 2002-03-09 20:30     ` Andrew Cagney
  2002-03-12  2:38       ` Klee Dienes
  1 sibling, 1 reply; 11+ messages in thread
From: Andrew Cagney @ 2002-03-09 20:30 UTC (permalink / raw)
  To: Klee Dienes; +Cc: Daniel Jacobowitz, gdb-patches

> On Tuesday, February 5, 2002, at 08:07 AM, Daniel Jacobowitz wrote:
> 
> Have you considered casting the function itself?  Something like:
> (gdb) print ((float (*)(float)) fabs) (3.0)
> $1 = 3.0
> (gdb) set fabs

Only:

	print ((float(*)()) fabs) (3.0)

should be necessary.  GDB will then attempt to pass the arguments 
according to GDB's interpretation of traditional K&R parameter passing 
rules.

> We have; for a long time that was the answer we gave to people who were running into this problem.  Our experience was that it was a nightmare to explain to people how this mechanism worked, and that even for folks who did undertand it, they found it a major mental burden to use in practice.  C function casting syntax is neither intuitive nor pleasant to type.
> 
> The reason we chose the "cast" syntax wasn't so much to be cute, but because it was the first thing everyone tried when they were trying to get this to work.  People would try 'print (float) fabs (3.0)', followed by 'print {float} fabs (3.0)', usually followed by several unsuccessful attemtps to remember the correct syntax to cast the function pointer.
> 
> I also think there's a pretty solid rationale behind the syntax, and one that generalizes to argument-passing.  The theory goes:
> 
> All symbols without debugging information are assumed to be of type 'unknown' (previously, they were assumed to be 'int', or (int (*) ())).  When you cast an expression of type 'unknown' to anything else, GDB does no conversion, but simply interprets the data (or generates the data) according to the specified type.  So if you have 'f' with no symbols,
> 
>   print (long long) f ((long long) 7, (float) 3.0)
> 
> will generate a function call as if 'f' had been declared as
> 
>   long long f (long long, float)
> 
> For function arguments, I claim this is both intuitive and matches the behavior of the C compiler.  For function return values, wee have to choose something for what 'print (type) f ()' is to mean, and I claim that it's the best of the two alternatives (the other being "assume 'int', then cast the 'int' to the specified type).

I've personally got reservations over introducing a change that, given a 
file like:

void
b(void)
{
   double d;
   d = (double) bar ((float) 3);
}

radically alters gdb's behavour given:

	print (double) bar((float) 3)

and rejects (?)

	print bar((float) 3)

However, I do see your point that even calling bar() (when bar() has no 
debug info) is dangerous.

Is this feature intended for C or ObjectiveC developers?

Andrew



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-03-09 20:30     ` Andrew Cagney
@ 2002-03-12  2:38       ` Klee Dienes
  2002-03-12  7:56         ` Andrew Cagney
  0 siblings, 1 reply; 11+ messages in thread
From: Klee Dienes @ 2002-03-12  2:38 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: Klee Dienes, Daniel Jacobowitz, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 3091 bytes --]

On Saturday, March 9, 2002, at 08:30 PM, Andrew Cagney wrote:

> I've personally got reservations over introducing a change that, given 
> a file like:
>
> void
> b(void)
> {
>   double d;
>   d = (double) bar ((float) 3);
> }
>
> radically alters gdb's behavour given:
>
> 	print (double) bar((float) 3)
>
> and rejects (?)
>
> 	print bar((float) 3)

I think that's a very valid reservation.  But let me expand the example 
a bit:

$ cat a.c
double foo (float f)
{
   return (f + 1.0);
}

double bar (float f)
{
   return (f + 1.0);
}

$ cat b.c
double foo (float);

int main ()
{
   double d1, d2;

   d1 = (double) foo ((float) 3);
   d2 = (double) bar ((float) 3);
}

$ cc -c a.c
$ cc -g -c b.c
$ cc a.o b.o -o a

In "standard" GDB, you get the following results:

(gdb) print d1
$1 = 4
(gdb) print d2
$2 = 1 							/* generic bogus value */
(gdb) print (double) foo ((float) 3)
$3 = 1 							/* generic bogus value */
(gdb) print (double) bar ((float) 3)
$4 = 1 							/* generic bogus value */

In GDB as patched, you get:

(gdb) print d1
$1 = 4
(gdb) print d2
$2 = 1074266112 					/* generic bogus value */
(gdb) print (double) foo ((float) 3)
$3 = 4
(gdb) print (double) bar ((float) 3)
$4 = 4

I'd argue that the real problem here is that the calling conventions for 
a function call are determined for GCC and for GDB in two very different 
ways.  In the case of GCC, it's based on what signature GCC has seen for 
the function.  In the case of GDB, it's based on what debugging 
information is available for the function being called.  This means that 
it's always going to be possible for there to be a mismatch between 
behavior of GCC and GDB when evaluating expressions, and my patch does 
not try to address that.  My patch only changes the default behavior 
from two "incorrect" results (only one of which matches the behavior of 
GCC), to two "correct" results (only one of which matches the behavior 
of GCC).  I'd argue that it's better to err on the side of returning the 
correct result, if you have to err at all, and that in the case where 
you do want the exact behavior of GCC,

print (float) (int) bar ((float) 3)

is much more intuitive and easy to type than

print ((float (*) ()) bar) ((float) 3)

> and rejects (?)
>
> 	print bar((float) 3)

Correct; this would print:

Unable to call function at 0x1df8: no return type information available.
To call this function anyway, you can cast the return type explicitly 
(e.g. 'print (float) fabs (3.0)')

> Is this feature intended for C or ObjectiveC developers?

I'd intend for this to be used by everyone. We specifically added it in 
response to bug reports from people making heavy use of the system math 
libraries; as well as from Cocoa (Objective-C) developers making heavy 
use of functions returning NSRect objects.  The reason it's of interest 
to me in preparing the Objective-C patches is that much of the 
Objective-C GDB code makes use of  being able to pass 'expected_type' 
arguments to the modified functions, and I'd rather not have to 
re-architect all those calls before submitting the patches.

[-- Attachment #2: Type: text/enriched, Size: 3211 bytes --]

On Saturday, March 9, 2002, at 08:30 PM, Andrew Cagney wrote:


<excerpt>I've personally got reservations over introducing a change
that, given a file like:


void

b(void)

{

  double d;

  d = (double) bar ((float) 3);

}


radically alters gdb's behavour given:


	print (double) bar((float) 3)


and rejects (?)


	print bar((float) 3)

</excerpt>

I think that's a very valid reservation.  But let me expand the
example a bit:


$ cat a.c

double foo (float f)

{

  return (f + 1.0);

}


double bar (float f)

{

  return (f + 1.0);

}


$ cat b.c

double foo (float);


int main ()

{

  double d1, d2;


  d1 = (double) foo ((float) 3);

  d2 = (double) bar ((float) 3);

}


$ cc -c a.c

$ cc -g -c b.c

$ cc a.o b.o -o a


In "standard" GDB, you get the following results:


(gdb) print d1

$1 = 4

(gdb) print d2

$2 = 1 							/* generic bogus value */

(gdb) print (double) foo ((float) 3)

$3 = 1 							/* generic bogus value */

(gdb) print (double) bar ((float) 3)

$4 = 1 							/* generic bogus value */


In GDB as patched, you get:


(gdb) print d1

$1 = 4

(gdb) print d2

$2 = 1074266112 					/* generic bogus value */

(gdb) print (double) foo ((float) 3)

$3 = 4

(gdb) print (double) bar ((float) 3)

$4 = 4


I'd argue that the real problem here is that the calling conventions
for a function call are determined for GCC and for GDB in two very
different ways.  In the case of GCC, it's based on what signature GCC
has seen for the function.  In the case of GDB, it's based on what
debugging information is available for the function being called. 
This means that it's always going to be possible for there to be a
mismatch between behavior of GCC and GDB when evaluating expressions,
and my patch does not try to address that.  My patch only changes the
default behavior from two "incorrect" results (only one of which
matches the behavior of GCC), to two "correct" results (only one of
which matches the behavior of GCC).  I'd argue that it's better to err
on the side of returning the correct result, if you have to err at
all, and that in the case where you <italic>do</italic> want the exact
behavior of GCC,


print (float) (int) bar ((float) 3)


is much more intuitive and easy to type than


print ((float (*) ()) bar) ((float) 3)


<excerpt><color><param>0000,0000,DEDE</param>and rejects (?)


	print bar((float) 3)</color>

</excerpt>

Correct; this would print:


Unable to call function at 0x1df8: no return type information
available.

To call this function anyway, you can cast the return type explicitly
(e.g. 'print (float) fabs (3.0)')


<excerpt>Is this feature intended for C or ObjectiveC developers?

</excerpt>

I'd intend for this to be used by everyone. We specifically added it
in response to bug reports from people making heavy use of the system
math libraries; as well as from Cocoa (Objective-C) developers making
heavy use of functions returning NSRect objects.  The reason it's of
interest to me in preparing the Objective-C patches is that much of
the Objective-C GDB code makes use of  being able to pass
'expected_type' arguments to the modified functions, and I'd rather
not have to re-architect all those calls before submitting the patches.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-03-12  2:38       ` Klee Dienes
@ 2002-03-12  7:56         ` Andrew Cagney
  2002-03-12 10:08           ` Klee Dienes
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Cagney @ 2002-03-12  7:56 UTC (permalink / raw)
  To: Klee Dienes; +Cc: Daniel Jacobowitz, gdb-patches


>> Is this feature intended for C or ObjectiveC developers?

> 
> I'd intend for this to be used by everyone. We specifically added it in response to bug reports from people making heavy use of the system math libraries; as well as from Cocoa (Objective-C) developers making heavy use of functions returning NSRect objects. The reason it's of interest to me in preparing the Objective-C patches is that much of the Objective-C GDB code makes use of being able to pass 'expected_type' arguments to the modified functions, and I'd rather not have to re-architect all those calls before submitting the patches.

So there are two reasons for the change?  The infrastructure you need 
for objective C and a user visible interface change.  Can you expand a 
little on the objective C problems.  If objective C has good reason for 
this infrastructure than I can't see why that part shouldn't go in.

enjoy,
Andrew



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-03-12  7:56         ` Andrew Cagney
@ 2002-03-12 10:08           ` Klee Dienes
  2002-03-12 10:34             ` Andrew Cagney
  0 siblings, 1 reply; 11+ messages in thread
From: Klee Dienes @ 2002-03-12 10:08 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: Klee Dienes, Daniel Jacobowitz, gdb-patches

Saying that I "need" the infrastructure change for Objective-C would 
probably be a bit strong.

The basic issue arises when evaluating Objective-C expressions like the 
following:

call [[window boundingBox] print]

Here 'window' is of type NSWindow, an opaque type defined in a system 
library, and 'boundingBox' is a method of NSWindow that returns a 
NSRect.  The issue arises because '[window boundingBox]' is really a 
function call to 'objc_msgSend_stret (window, selector)'.  There 
generally isn't symbol information available for 'objc_msgSend_stret', 
but there often is for '[NSWindow boundingBox]'.  So it's nice for 
Objective-C to be able to pass the correct return type information to 
'call_function_by_hand' so that the result returns with the correct 
type, rather than have to cons up a fake function value with fake return 
type to pass to 'call_function_by_hand'.

On Tuesday, March 12, 2002, at 07:55 AM, Andrew Cagney wrote:

> So there are two reasons for the change?  The infrastructure you need 
> for objective C and a user visible interface change.  Can you expand a 
> little on the objective C problems.  If objective C has good reason for 
> this infrastructure than I can't see why that part shouldn't go in.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFA] Function return type checking
  2002-03-12 10:08           ` Klee Dienes
@ 2002-03-12 10:34             ` Andrew Cagney
  0 siblings, 0 replies; 11+ messages in thread
From: Andrew Cagney @ 2002-03-12 10:34 UTC (permalink / raw)
  To: Klee Dienes; +Cc: Klee Dienes, Daniel Jacobowitz, gdb-patches

> Saying that I "need" the infrastructure change for Objective-C would probably be a bit strong.

> The basic issue arises when evaluating Objective-C expressions like the following:
> 
> call [[window boundingBox] print]
> 
> Here 'window' is of type NSWindow, an opaque type defined in a system library, and 'boundingBox' is a method of NSWindow that returns a NSRect.  The issue arises because '[window boundingBox]' is really a function call to 'objc_msgSend_stret (window, selector)'.  There generally isn't symbol information available for 'objc_msgSend_stret', but there often is for '[NSWindow boundingBox]'.  So it's nice for Objective-C to be able to pass the correct return type information to 'call_function_by_hand' so that the result returns with the correct type, rather than have to cons up a fake function value with fake return type to pass to 'call_function_by_hand'.

One of the things I've been puzzled by is how a user could get 
themselves in a situtation where the feature was needed.  I was thinking 
that a well written program, having including all relevant headers, 
would have all the relevant information available.

The above is starting to explain why there is a problem.  Can you, humor 
me a little and express it in slightly more concret terms (bits of 
code).  Does C++ have a similar problem?

Keep in mind that Objective C doesn't have the same entrenched 
conventions that normal C suffers from - you've more freedom to define 
its behavour.

> On Tuesday, March 12, 2002, at 07:55 AM, Andrew Cagney wrote:
> 
> So there are two reasons for the change?  The infrastructure you need for objective C and a user visible interface change.  Can you expand a little on the objective C problems.  If objective C has good reason for this infrastructure than I can't see why that part shouldn't go in.

Andrew



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2002-03-12 18:34 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-02-05  1:36 [RFA] Function return type checking Klee Dienes
2002-02-05  3:24 ` Eli Zaretskii
2002-02-05  8:07 ` Daniel Jacobowitz
2002-02-06 13:43   ` Klee Dienes
2002-02-06 14:14     ` Daniel Jacobowitz
2002-03-09 20:30     ` Andrew Cagney
2002-03-12  2:38       ` Klee Dienes
2002-03-12  7:56         ` Andrew Cagney
2002-03-12 10:08           ` Klee Dienes
2002-03-12 10:34             ` Andrew Cagney
2002-02-08 13:41 ` Kevin Buettner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox