Bug 13225

Summary: GDB fails to find non-overloaded C++ function
Product: gdb Reporter: Jim Blandy <jimb>
Component: c++Assignee: Keith Seitz <keiths>
Status: RESOLVED FIXED    
Severity: normal CC: keiths, rguenth
Priority: P2    
Version: unknown   
Target Milestone: 7.4   
Host: Target:
Build: Last reconfirmed:

Description Jim Blandy 2011-09-26 15:36:37 UTC
When I try to call JS_CompileFunction in the following test program, GDB says:

Cannot resolve function JS_CompileFunction to any overloaded instance

However, if I cast one of the zeros to "const char **", GDB can find the function.

$ cat archer-bug.cpp
#include <stdlib.h>

typedef unsigned uintN;

struct JSContext;
struct JSFunction;
struct JSObject;

JSFunction *
JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
                   uintN nargs, const char **argnames,
                   const char *bytes, size_t length,
                   const char *filename, uintN lineno) { }


int main(int argc, char **argv) {
  JSContext *cx = NULL;
  JSObject *global = NULL;
  JS_CompileFunction(cx, global, "f", 0, 0, "1", 1, "foo.js", 1);
  return 0;
}
$ g++ -g archer-bug.cpp -o archer-bug$ ~/gdb/bin/gdb archer-bug
GNU gdb (GDB) 7.3.50.20110925-cvs
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/jimb/play/archer-bug...done.
(gdb) start
Temporary breakpoint 1 at 0x4005a1: file archer-bug.cpp, line 17.
Starting program: /home/jimb/play/archer-bug 

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe738) at archer-bug.cpp:17
17	  JSContext *cx = NULL;
(gdb) next
18	  JSObject *global = NULL;
(gdb) 
19	  JS_CompileFunction(cx, global, "f", 0, 0, "1", 1, "foo.js", 1);
(gdb) 
20	  return 0;
(gdb) p JS_CompileFunction(cx, global, "f", 0, 0, "1", 1, "foo.js", 1)
Cannot resolve function JS_CompileFunction to any overloaded instance
(gdb) p JS_CompileFunction(cx, global, "f", 0, (const char **) 0, "1", 1, "foo.js", 1)
$1 = NULL
(gdb)
Comment 1 Keith Seitz 2011-10-11 18:53:23 UTC
There are actually two problems mentioned here. First, the fact that the parser is seeing the NULL ("0") char const** parameter as an INT, but the evaluator will not allow that conversion. I don't see why we couldn't permit that. I can imagine scenarios where the user might want to pass an address this way. While a real source file would require the cast, there is no reason why we cannot be a little more permissive in the debugger.

Second, there is a bug alluded to by the OP: casting the first "0" to some other type will get gdb to "work." This is happening because when the function's overload suitability is calculated, the code is currently early returning on the very first non-STANDARD rank that it sees, instead of returning the worst one that it sees.

Patch/tests pending.
Comment 2 Keith Seitz 2011-10-11 19:24:27 UTC
Patch submitted:
http://sourceware.org/ml/gdb-patches/2011-10/msg00327.html
Comment 3 Jim Blandy 2011-10-11 19:30:21 UTC
Thanks for the patch, Keith!

You say:

While a real source file would require the cast, there is no reason why we cannot be a little more permissive in the debugger.

I don't think that's correct. The transcript (with its missing newline after the g++ command...) shows that the expression I try to evaluate in GDB is identical to the expression appearing in the source code, which the compiler accepts without complaint. The C++ language does not require that cast.
Comment 4 cvs-commit@gcc.gnu.org 2011-10-14 20:22:26 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	kseitz@sourceware.org	2011-10-14 20:22:17

Modified files:
	gdb            : ChangeLog eval.c gdbtypes.h gdbtypes.c 
	                 valarith.c valops.c value.h 

Log message:
	PR c++/13225
	* eval.c (evaluate_subexp_standard): Do not construct
	an array of types; pass the value array directly to
	find_overload_match.
	* gdbtypes.h (NULL_POINTER_CONVERSION_BADNESS): Declare.
	(rank_function): Take an array of values instead of types.
	(rank_one_type): Add struct value * parameter.
	* gdbtypes.c (NULL_POINTER_CONVERSION_BADNESS): Define.
	(rank_function): For each argument, pass the argument's
	value to rank_one_type.
	(rank_one_type): Add VALUE parameter.
	If the parameter type is a pointer and the argument type
	is an integer, return NULL_POINTER_CONVERSION_BADNESS if
	VALUE is zero.
	Update all calls to rank_one_type, passing NULL for new
	VALUE parameter.
	* valarith.c (value_user_defined_cpp_op): Do not construct
	an array of types; pass the value array directly to
	find_overload_match.
	* valops.c (find_overload_method_list): Take an array of
	values instead of types.
	Save the type of OBJP for later use.
	Update calls to find_oload_champ, and find_oload_champ_namespace.
	(find_oload_champ_namespace): Take an array of values instead
	of types.
	(find_oload_champ_namespace_loop): Likewise.
	(find_oload_champ): Likewise.
	(classify_oload_match): Inspect all arguments
	until INCOMPATIBLE is found. Return the worst badness found
	otherwise.
	(compare_parameters): Update call to rank_one_type.
	* value.h (find_overload_match): Take an array of values instead
	of types.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.13437&r2=1.13438
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/eval.c.diff?cvsroot=src&r1=1.154&r2=1.155
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/gdbtypes.h.diff?cvsroot=src&r1=1.156&r2=1.157
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/gdbtypes.c.diff?cvsroot=src&r1=1.219&r2=1.220
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/valarith.c.diff?cvsroot=src&r1=1.99&r2=1.100
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/valops.c.diff?cvsroot=src&r1=1.287&r2=1.288
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/value.h.diff?cvsroot=src&r1=1.187&r2=1.188
Comment 5 cvs-commit@gcc.gnu.org 2011-10-14 20:23:01 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	kseitz@sourceware.org	2011-10-14 20:22:50

Modified files:
	gdb/testsuite  : ChangeLog 
	gdb/testsuite/gdb.cp: converts.exp converts.cc 

Log message:
	PR c++/13225
	* gdb.cp/converts.cc (foo3_1): New function.
	(foo3_2): New functions.
	* gdb.cp/converts.exp: Add tests for int to pointer conversion
	and null pointer conversions of integer constant zero.
	Add test to check if all arguments are checked for incompatible
	conversion BADNESS.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/ChangeLog.diff?cvsroot=src&r1=1.2897&r2=1.2898
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.cp/converts.exp.diff?cvsroot=src&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/testsuite/gdb.cp/converts.cc.diff?cvsroot=src&r1=1.2&r2=1.3
Comment 6 Keith Seitz 2011-10-14 20:30:39 UTC
Final patch committed.
Comment 7 Pedro Alves 2011-10-28 15:33:08 UTC
*** Bug 13356 has been marked as a duplicate of this bug. ***