Add new argument NOSIDE to find_overload_match.
This is a fix for PR c++/17132. If this new argument is set to EVAL_AVOID_SIDE_EFFECTS, then the object's memory will not be read while picking the best overload match. gdb/ * eval.c: Update all calls to find_overload_match. * valarith.c: Likewise. (value_user_defined_cpp_op, value_user_defined_op): New argument NOSIDE. Update all callers. * valops.c (find_overload_match): New argument NOSIDE. * value.h (find_overload_match): Update signature. gdb/testsuite * gdb.cp/pr17132.cc: New file. * gdb.cp/pr17132.exp: New file.
This commit is contained in:
parent
940df40812
commit
e66d444669
8 changed files with 146 additions and 14 deletions
|
@ -1,3 +1,13 @@
|
||||||
|
2014-08-15 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
PR c++/17132
|
||||||
|
* eval.c: Update all calls to find_overload_match.
|
||||||
|
* valarith.c: Likewise.
|
||||||
|
(value_user_defined_cpp_op, value_user_defined_op): New
|
||||||
|
argument NOSIDE. Update all callers.
|
||||||
|
* valops.c (find_overload_match): New argument NOSIDE.
|
||||||
|
* value.h (find_overload_match): Update signature.
|
||||||
|
|
||||||
2014-08-15 Siva Chandra Reddy <sivachandra@google.com>
|
2014-08-15 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
* python/lib/gdb/command/xmethods.py (set_xm_status1): Use the
|
* python/lib/gdb/command/xmethods.py (set_xm_status1): Use the
|
||||||
|
|
|
@ -1563,7 +1563,7 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||||
NON_METHOD, /* not method */
|
NON_METHOD, /* not method */
|
||||||
NULL, NULL, /* pass NULL symbol since
|
NULL, NULL, /* pass NULL symbol since
|
||||||
symbol is unknown */
|
symbol is unknown */
|
||||||
NULL, &symp, NULL, 0);
|
NULL, &symp, NULL, 0, noside);
|
||||||
|
|
||||||
/* Now fix the expression being evaluated. */
|
/* Now fix the expression being evaluated. */
|
||||||
exp->elts[save_pos1 + 2].symbol = symp;
|
exp->elts[save_pos1 + 2].symbol = symp;
|
||||||
|
@ -1599,7 +1599,7 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||||
METHOD, /* method */
|
METHOD, /* method */
|
||||||
&arg2, /* the object */
|
&arg2, /* the object */
|
||||||
NULL, &valp, NULL,
|
NULL, &valp, NULL,
|
||||||
&static_memfuncp, 0);
|
&static_memfuncp, 0, noside);
|
||||||
|
|
||||||
if (op == OP_SCOPE && !static_memfuncp)
|
if (op == OP_SCOPE && !static_memfuncp)
|
||||||
{
|
{
|
||||||
|
@ -1670,7 +1670,7 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||||
NULL, /* no need for name */
|
NULL, /* no need for name */
|
||||||
NON_METHOD, /* not method */
|
NON_METHOD, /* not method */
|
||||||
NULL, function, /* the function */
|
NULL, function, /* the function */
|
||||||
NULL, &symp, NULL, no_adl);
|
NULL, &symp, NULL, no_adl, noside);
|
||||||
|
|
||||||
if (op == OP_VAR_VALUE)
|
if (op == OP_VAR_VALUE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2014-08-15 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
PR c++/17132
|
||||||
|
* gdb.cp/pr17132.cc: New file.
|
||||||
|
* gdb.cp/pr17132.exp: New file.
|
||||||
|
|
||||||
2014-08-15 Siva Chandra Reddy <sivachandra@google.com>
|
2014-08-15 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
* gdb.python/py-xmethods.py (A_getarrayind)
|
* gdb.python/py-xmethods.py (A_getarrayind)
|
||||||
|
|
61
gdb/testsuite/gdb.cp/pr17132.cc
Normal file
61
gdb/testsuite/gdb.cp/pr17132.cc
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2014 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
|
||||||
|
/* One could use unique_ptr instead, but that requires a GCC which can
|
||||||
|
support "-std=c++11". */
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class smart_ptr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
smart_ptr (T *obj) : _obj (obj) { }
|
||||||
|
~smart_ptr () { delete _obj; }
|
||||||
|
|
||||||
|
T *operator-> ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
T *_obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T *
|
||||||
|
smart_ptr<T>::operator-> ()
|
||||||
|
{
|
||||||
|
return _obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
class A
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual int func ();
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
A::func ()
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
A *a_ptr = 0;
|
||||||
|
smart_ptr<A> a (new A);
|
||||||
|
|
||||||
|
return a->func(); /* Break here */
|
||||||
|
}
|
40
gdb/testsuite/gdb.cp/pr17132.exp
Normal file
40
gdb/testsuite/gdb.cp/pr17132.exp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# Copyright 2014 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# This file is part of the gdb testsuite
|
||||||
|
|
||||||
|
if {[skip_cplus_tests]} { continue }
|
||||||
|
|
||||||
|
standard_testfile .cc
|
||||||
|
|
||||||
|
if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if {![runto_main]} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_breakpoint [gdb_get_line_number "Break here"]
|
||||||
|
gdb_continue_to_breakpoint "Break here"
|
||||||
|
|
||||||
|
gdb_test "ptype a_ptr->func ()" ".* = int" "ptype a_ptr->func ()"
|
||||||
|
gdb_test "ptype a->func ()" ".* = int" "ptype a->func ()"
|
||||||
|
gdb_test "p sizeof (a_ptr->func()) == sizeof (int)" ".* = true" \
|
||||||
|
"p sizeof (a_ptr->func())"
|
||||||
|
gdb_test "p sizeof (a->func()) == sizeof (int)" ".* = true" \
|
||||||
|
"p sizeof (a->func())"
|
||||||
|
gdb_test "p 1 && a->func()" ".* = true" "p 1 && a->func()"
|
||||||
|
gdb_test "p 0 || a->func()" ".* = true" "p 0 || a->func()"
|
|
@ -286,7 +286,7 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
|
||||||
|
|
||||||
static struct value *
|
static struct value *
|
||||||
value_user_defined_cpp_op (struct value **args, int nargs, char *operator,
|
value_user_defined_cpp_op (struct value **args, int nargs, char *operator,
|
||||||
int *static_memfuncp)
|
int *static_memfuncp, enum noside noside)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct symbol *symp = NULL;
|
struct symbol *symp = NULL;
|
||||||
|
@ -295,7 +295,7 @@ value_user_defined_cpp_op (struct value **args, int nargs, char *operator,
|
||||||
find_overload_match (args, nargs, operator, BOTH /* could be method */,
|
find_overload_match (args, nargs, operator, BOTH /* could be method */,
|
||||||
&args[0] /* objp */,
|
&args[0] /* objp */,
|
||||||
NULL /* pass NULL symbol since symbol is unknown */,
|
NULL /* pass NULL symbol since symbol is unknown */,
|
||||||
&valp, &symp, static_memfuncp, 0);
|
&valp, &symp, static_memfuncp, 0, noside);
|
||||||
|
|
||||||
if (valp)
|
if (valp)
|
||||||
return valp;
|
return valp;
|
||||||
|
@ -317,12 +317,15 @@ value_user_defined_cpp_op (struct value **args, int nargs, char *operator,
|
||||||
|
|
||||||
static struct value *
|
static struct value *
|
||||||
value_user_defined_op (struct value **argp, struct value **args, char *name,
|
value_user_defined_op (struct value **argp, struct value **args, char *name,
|
||||||
int *static_memfuncp, int nargs)
|
int *static_memfuncp, int nargs, enum noside noside)
|
||||||
{
|
{
|
||||||
struct value *result = NULL;
|
struct value *result = NULL;
|
||||||
|
|
||||||
if (current_language->la_language == language_cplus)
|
if (current_language->la_language == language_cplus)
|
||||||
result = value_user_defined_cpp_op (args, nargs, name, static_memfuncp);
|
{
|
||||||
|
result = value_user_defined_cpp_op (args, nargs, name, static_memfuncp,
|
||||||
|
noside);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
result = value_struct_elt (argp, args, name, static_memfuncp,
|
result = value_struct_elt (argp, args, name, static_memfuncp,
|
||||||
"structure");
|
"structure");
|
||||||
|
@ -471,7 +474,7 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
|
||||||
}
|
}
|
||||||
|
|
||||||
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
|
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
|
||||||
&static_memfuncp, 2);
|
&static_memfuncp, 2, noside);
|
||||||
|
|
||||||
if (argvec[0])
|
if (argvec[0])
|
||||||
{
|
{
|
||||||
|
@ -582,7 +585,7 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
|
||||||
}
|
}
|
||||||
|
|
||||||
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
|
argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
|
||||||
&static_memfuncp, nargs);
|
&static_memfuncp, nargs, noside);
|
||||||
|
|
||||||
if (argvec[0])
|
if (argvec[0])
|
||||||
{
|
{
|
||||||
|
|
19
gdb/valops.c
19
gdb/valops.c
|
@ -2449,6 +2449,12 @@ value_find_oload_method_list (struct value **argp, const char *method,
|
||||||
ADL overload candidates when performing overload resolution for a fully
|
ADL overload candidates when performing overload resolution for a fully
|
||||||
qualified name.
|
qualified name.
|
||||||
|
|
||||||
|
If NOSIDE is EVAL_AVOID_SIDE_EFFECTS, then OBJP's memory cannot be
|
||||||
|
read while picking the best overload match (it may be all zeroes and thus
|
||||||
|
not have a vtable pointer), in which case skip virtual function lookup.
|
||||||
|
This is ok as typically EVAL_AVOID_SIDE_EFFECTS is only used to determine
|
||||||
|
the result type.
|
||||||
|
|
||||||
Note: This function does *not* check the value of
|
Note: This function does *not* check the value of
|
||||||
overload_resolution. Caller must check it to see whether overload
|
overload_resolution. Caller must check it to see whether overload
|
||||||
resolution is permitted. */
|
resolution is permitted. */
|
||||||
|
@ -2458,7 +2464,8 @@ find_overload_match (struct value **args, int nargs,
|
||||||
const char *name, enum oload_search_type method,
|
const char *name, enum oload_search_type method,
|
||||||
struct value **objp, struct symbol *fsym,
|
struct value **objp, struct symbol *fsym,
|
||||||
struct value **valp, struct symbol **symp,
|
struct value **valp, struct symbol **symp,
|
||||||
int *staticp, const int no_adl)
|
int *staticp, const int no_adl,
|
||||||
|
const enum noside noside)
|
||||||
{
|
{
|
||||||
struct value *obj = (objp ? *objp : NULL);
|
struct value *obj = (objp ? *objp : NULL);
|
||||||
struct type *obj_type = obj ? value_type (obj) : NULL;
|
struct type *obj_type = obj ? value_type (obj) : NULL;
|
||||||
|
@ -2764,9 +2771,13 @@ find_overload_match (struct value **args, int nargs,
|
||||||
{
|
{
|
||||||
if (src_method_oload_champ >= 0)
|
if (src_method_oload_champ >= 0)
|
||||||
{
|
{
|
||||||
if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, method_oload_champ))
|
if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, method_oload_champ)
|
||||||
*valp = value_virtual_fn_field (&temp, fns_ptr, method_oload_champ,
|
&& noside != EVAL_AVOID_SIDE_EFFECTS)
|
||||||
basetype, boffset);
|
{
|
||||||
|
*valp = value_virtual_fn_field (&temp, fns_ptr,
|
||||||
|
method_oload_champ, basetype,
|
||||||
|
boffset);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
*valp = value_fn_field (&temp, fns_ptr, method_oload_champ,
|
*valp = value_fn_field (&temp, fns_ptr, method_oload_champ,
|
||||||
basetype, boffset);
|
basetype, boffset);
|
||||||
|
|
|
@ -693,7 +693,8 @@ extern int find_overload_match (struct value **args, int nargs,
|
||||||
enum oload_search_type method,
|
enum oload_search_type method,
|
||||||
struct value **objp, struct symbol *fsym,
|
struct value **objp, struct symbol *fsym,
|
||||||
struct value **valp, struct symbol **symp,
|
struct value **valp, struct symbol **symp,
|
||||||
int *staticp, const int no_adl);
|
int *staticp, const int no_adl,
|
||||||
|
enum noside noside);
|
||||||
|
|
||||||
extern struct value *value_field (struct value *arg1, int fieldno);
|
extern struct value *value_field (struct value *arg1, int fieldno);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue