From patchwork Thu Aug 14 13:42:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siva Chandra Reddy X-Patchwork-Id: 2394 Received: (qmail 11387 invoked by alias); 14 Aug 2014 13:42:51 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 11352 invoked by uid 89); 14 Aug 2014 13:42:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-oa0-f50.google.com Received: from mail-oa0-f50.google.com (HELO mail-oa0-f50.google.com) (209.85.219.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 14 Aug 2014 13:42:41 +0000 Received: by mail-oa0-f50.google.com with SMTP id g18so983388oah.37 for ; Thu, 14 Aug 2014 06:42:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-type; bh=p9NwEtQw1in762Eb+xOVUphBsOx/K7X7BeBVh7ctBwA=; b=ha49gk+uro47xpz2jFRvciqyPZuoYK/s6Ay1NmBW+MkqycVe2pjg0rHqvdkTs2JuiY Je7nBclPN6FE4+B1a2fOEOXR/9ktO9P3GvQd0YK+/YYDOCC06BEh9iw6DQIVY8wWnU0d fZLdz8g06mlbp5c74vjz8NEf3y8qAPZEs5rKuU8okmFJxqKnKWLy1z9KUx8Ai9nvPr7J 5F9VT7578RdAUptt4SfEbFxIzx+EDQlZk9opiE7Qj+lBVvEaTs4iNRxMm8yVO52SFB53 /E2ZuijMePKkOvxB7m2htFIxm35K0fuB2t0C752037vD+wjIVQL2PkVDl0PkoZnDnrA4 Cy9A== X-Gm-Message-State: ALoCoQl7bQSWTjjCkLsqQwVDbF24p5sTS6QbeY8wMGEKaOvvGZSWG8QI3VxxgOLAqhETVdPgdvAh MIME-Version: 1.0 X-Received: by 10.60.134.76 with SMTP id pi12mr13119161oeb.0.1408023759598; Thu, 14 Aug 2014 06:42:39 -0700 (PDT) Received: by 10.202.12.193 with HTTP; Thu, 14 Aug 2014 06:42:39 -0700 (PDT) Date: Thu, 14 Aug 2014 06:42:39 -0700 Message-ID: Subject: [PATCH v2 PR c++/17132] Add new argument NOSIDE to find_overload_match From: Siva Chandra To: gdb-patches X-IsSubscribed: yes The attached patch has been updated per Doug's suggestions. Original post: https://sourceware.org/ml/gdb-patches/2014-07/msg00197.html Doug's review comments: https://sourceware.org/ml/gdb-patches/2014-08/msg00055.html ChangeLog: 2014-08-14 Siva Chandra Reddy 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. diff --git a/gdb/eval.c b/gdb/eval.c index de8e8ec..c379209 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -1563,7 +1563,7 @@ evaluate_subexp_standard (struct type *expect_type, NON_METHOD, /* not method */ NULL, NULL, /* pass NULL symbol since symbol is unknown */ - NULL, &symp, NULL, 0); + NULL, &symp, NULL, 0, noside); /* Now fix the expression being evaluated. */ exp->elts[save_pos1 + 2].symbol = symp; @@ -1599,7 +1599,7 @@ evaluate_subexp_standard (struct type *expect_type, METHOD, /* method */ &arg2, /* the object */ NULL, &valp, NULL, - &static_memfuncp, 0); + &static_memfuncp, 0, noside); if (op == OP_SCOPE && !static_memfuncp) { @@ -1670,7 +1670,7 @@ evaluate_subexp_standard (struct type *expect_type, NULL, /* no need for name */ NON_METHOD, /* not method */ NULL, function, /* the function */ - NULL, &symp, NULL, no_adl); + NULL, &symp, NULL, no_adl, noside); if (op == OP_VAR_VALUE) { diff --git a/gdb/testsuite/gdb.cp/pr17132.cc b/gdb/testsuite/gdb.cp/pr17132.cc new file mode 100644 index 0000000..42d99af --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr17132.cc @@ -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 . */ + + +/* One could use unique_ptr instead, but that requires a GCC which can + support "-std=c++11". */ + +template +class smart_ptr +{ +public: + smart_ptr (T *obj) : _obj (obj) { } + ~smart_ptr () { delete _obj; } + + T *operator-> (); + +private: + T *_obj; +}; + +template +T * +smart_ptr::operator-> () +{ + return _obj; +} + +class A +{ +public: + virtual int func (); +}; + +int +A::func () +{ + return 3; +} + +int +main () +{ + A *a_ptr = 0; + smart_ptr a (new A); + + return a->func(); /* Break here */ +} diff --git a/gdb/testsuite/gdb.cp/pr17132.exp b/gdb/testsuite/gdb.cp/pr17132.exp new file mode 100644 index 0000000..26a02a2 --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr17132.exp @@ -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 . + +# 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()" diff --git a/gdb/valarith.c b/gdb/valarith.c index d60dedb..44673a1 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -286,7 +286,7 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1) static struct value * 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; @@ -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 */, &args[0] /* objp */, NULL /* pass NULL symbol since symbol is unknown */, - &valp, &symp, static_memfuncp, 0); + &valp, &symp, static_memfuncp, 0, noside); if (valp) return valp; @@ -317,12 +317,15 @@ value_user_defined_cpp_op (struct value **args, int nargs, char *operator, static struct value * 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; 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 result = value_struct_elt (argp, args, name, static_memfuncp, "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, - &static_memfuncp, 2); + &static_memfuncp, 2, noside); 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, - &static_memfuncp, nargs); + &static_memfuncp, nargs, noside); if (argvec[0]) { diff --git a/gdb/valops.c b/gdb/valops.c index d9ce2f2..e1decf0 100644 --- a/gdb/valops.c +++ b/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 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 overload_resolution. Caller must check it to see whether overload resolution is permitted. */ @@ -2458,7 +2464,8 @@ find_overload_match (struct value **args, int nargs, const char *name, enum oload_search_type method, struct value **objp, struct symbol *fsym, 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 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 (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, method_oload_champ)) - *valp = value_virtual_fn_field (&temp, fns_ptr, method_oload_champ, - basetype, boffset); + if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, method_oload_champ) + && noside != EVAL_AVOID_SIDE_EFFECTS) + { + *valp = value_virtual_fn_field (&temp, fns_ptr, + method_oload_champ, basetype, + boffset); + } else *valp = value_fn_field (&temp, fns_ptr, method_oload_champ, basetype, boffset); diff --git a/gdb/value.h b/gdb/value.h index 4654042..843478b 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -693,7 +693,8 @@ extern int find_overload_match (struct value **args, int nargs, enum oload_search_type method, struct value **objp, struct symbol *fsym, 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);