public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: sami wagiaalla <swagiaal@redhat.com>
To: gdb-patches@sourceware.org
Subject: Re: [patch] smart pointer support
Date: Mon, 09 Aug 2010 15:59:00 -0000	[thread overview]
Message-ID: <4C6025EF.5080509@redhat.com> (raw)
In-Reply-To: <m3hbj7qt7w.fsf@fleche.redhat.com>

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


> Sami>  +		      struct value *value = value_x_unop (arg2, op, noside);
> Sami>  +		      if (value)
> Sami>  +			arg2 = value;
>
> This seems strange.  When can the result here be NULL?  And what does
> that mean?  It seems like this either ought to be impossible, or it
> should be an error of some kind.
>

Yes this is incorrect. value_x_unop never returns null. If the operator 
is not found it throws an error. I added a try catch statement and tests 
for the failing case.

New patch attached.

[-- Attachment #2: smart_pointer.patch --]
[-- Type: text/plain, Size: 7691 bytes --]

Support overloading of 'operator->'.

2010-08-09  Sami Wagiaalla  <swagiaal@redhat.com>

	 PR C++/11500:
	* valarith.c (value_x_unop): Handle STRUCTOP_PTR.
	* eval.c (evaluate_subexp_standard): Check for overload of
	'operator->'.

2010-08-09  Sami Wagiaalla  <swagiaal@redhat.com>

	* gdb.cp/smartp.exp: New test.
	* gdb.cp/smartp.cc : New test.

diff --git a/gdb/eval.c b/gdb/eval.c
index ba75952..9786c1e 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1431,6 +1431,24 @@ evaluate_subexp_standard (struct type *expect_type,
 	  else
 	    {
 	      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+	      /* Check to see if the operator '->' has been overloaded.  If the operator
+	         has been overloaded replace arg2 with the value returned by the custom
+	         operator and continue evaluation.  */
+	      while (unop_user_defined_p (op, arg2))
+		{
+		  volatile struct gdb_exception except;
+		  struct value *value = NULL;
+		  TRY_CATCH (except, RETURN_MASK_ERROR)
+		    {
+		      value = value_x_unop (arg2, op, noside);
+		    }
+
+		  if (except.reason < 0)
+		    break;
+
+		  arg2 = value;
+		}
 	    }
 	  /* Now, say which argument to start evaluating from */
 	  tem = 2;
@@ -1819,6 +1837,23 @@ evaluate_subexp_standard (struct type *expect_type,
       if (noside == EVAL_SKIP)
 	goto nosideret;
 
+      /* Check to see if operator '->' has been overloaded.  If so replace
+         arg1 with the value returned by evaluating operator->().  */
+      while (unop_user_defined_p (op, arg1))
+	{
+	  volatile struct gdb_exception except;
+	  struct value *value = NULL;
+	  TRY_CATCH (except, RETURN_MASK_ERROR)
+	    {
+	      value = value_x_unop (arg1, op, noside);
+	    }
+
+	  if (except.reason < 0)
+	    break;
+
+	  arg1 = value;
+	}
+
       /* JYG: if print object is on we need to replace the base type
 	 with rtti type in order to continue on with successful
 	 lookup of member / method only available in the rtti type. */
diff --git a/gdb/testsuite/gdb.cp/smartp.cc b/gdb/testsuite/gdb.cp/smartp.cc
new file mode 100644
index 0000000..baa8f46
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/smartp.cc
@@ -0,0 +1,163 @@
+/* This test script is part of GDB, the GNU debugger.
+
+   Copyright 1999, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   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/>.
+   */
+
+class Type1{
+  public:
+  int foo(){
+    return 11;
+  }
+};
+
+class Type2{
+  public:
+  int foo(){
+    return 22;
+  }
+};
+
+class Type3{
+  public:
+  int foo(int){
+    return 33;
+  }
+  int foo(char){
+    return 44;
+  }
+};
+
+class Type4 {
+  public:
+    int a;
+    int b;
+};
+
+int foo (Type3, float)
+{
+  return 55;
+}
+
+class MyPointer{
+  Type1 *p;
+ public:
+  MyPointer(Type1 *pointer){
+    p = pointer;
+  }
+
+  Type1 *operator->(){
+    return p;
+  }
+};
+
+template <typename T> class SmartPointer{
+  T *p;
+ public:
+  SmartPointer(T *pointer){
+    p = pointer;
+  }
+
+  T *operator->(){
+    return p;
+  }
+};
+
+
+class A {
+ public:
+  int inta;
+  int foo() { return 66; }
+};
+
+class B {
+ public:
+  A a;
+  A* operator->(){
+    return &a;
+  }
+};
+
+class C {
+ public:
+  B b;
+  B& operator->(){
+    return b;
+  }
+};
+
+class C2 {
+ public:
+  B b;
+  B operator->(){
+    return b;
+  }
+};
+
+int main(){
+  Type1 mt1;
+  Type2 mt2;
+  Type3 mt3;
+
+  Type4 mt4;
+  mt4.a = 11;
+  mt4.b = 12;
+
+  MyPointer mp(&mt1);
+  Type1 *mtp = &mt1;
+
+  SmartPointer<Type1> sp1(&mt1);
+  SmartPointer<Type2> sp2(&mt2);
+  SmartPointer<Type3> sp3(&mt3);
+  SmartPointer<Type4> sp4(&mt4);
+
+  mp->foo();
+  mtp->foo();
+
+  sp1->foo();
+  sp2->foo();
+
+  sp3->foo(1);
+  sp3->foo('a');
+
+  sp4->a;
+  sp4->b;
+
+  Type4 *mt4p = &mt4;
+  mt4p->a;
+  mt4p->b;
+
+  A a;
+  B b;
+  C c;
+  C2 c2;
+
+  a.inta = 77;
+  b.a = a;
+  c.b = b;
+  c2.b = b;
+
+  a.foo();
+  b->foo();
+  c->foo();
+
+  b->inta = 77;
+  c->inta = 77;
+  c2->inta = 77;
+
+  return 0; // end of main
+}
+
diff --git a/gdb/testsuite/gdb.cp/smartp.exp b/gdb/testsuite/gdb.cp/smartp.exp
new file mode 100644
index 0000000..01c8a11
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/smartp.exp
@@ -0,0 +1,74 @@
+# Copyright 2008 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/>.
+
+set testfile smartp
+set srcfile ${testfile}.cc
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
+     return -1
+}
+
+############################################
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "end of main"]
+gdb_continue_to_breakpoint "end of main"
+
+# Test that overloaded arrow operator works
+gdb_test "p mp->foo()"            "= 11"
+
+# Test that regular arrow operator still works
+gdb_test "p mtp->foo()"            "= 11"
+
+# Test that normal '.' operator still works.
+gdb_test "p mt1.foo()"             "= 11"
+
+# test that gdb extension '.' for pointers still works.
+gdb_test "p mt4p.a"                "= 11"
+
+# Test that templated smart pointers work
+gdb_test "p sp1->foo()"            "= 11"
+gdb_test "p sp2->foo()"            "= 22"
+
+# Test that overload resolution works properly
+# with smart pointers
+gdb_test "p sp3->foo(1)"           "= 33"
+gdb_test "p sp3->foo('a')"         "= 44"
+
+# Test smart pointers work for member references
+gdb_test "p sp4->a"         "= 11"
+gdb_test "p sp4->b"         "= 12"
+
+# Test regular arrow operator still works for
+# member references
+gdb_test "p mt4p->a"         "= 11"
+gdb_test "p mt4p->b"         "= 12"
+
+# Test that incorrect use of the arrow operator
+# is still handled correctly.
+gdb_test "p mt4->fake"       "There is no member named fake."
+gdb_test "p mt4->fake()"     "Couldn't find method Type4::fake"
+
+# Test that overloading of -> works recursively
+gdb_test "p b->foo()"         "= 66"
+gdb_test "p c->foo()"         "= 66"
+gdb_test "p c->inta"          "= 77"
+
+setup_kfail "gdb/11606" "*-*-*"
+gdb_test "p c2->inta"          "= 77"
+
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 0c40905..91f9c0c 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -616,6 +616,9 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
     case UNOP_IND:
       strcpy (ptr, "*");
       break;
+    case STRUCTOP_PTR:
+      strcpy (ptr, "->");
+      break;
     default:
       error (_("Invalid unary operation specified."));
     }

  reply	other threads:[~2010-08-09 15:59 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-20 15:58 sami wagiaalla
2010-07-23 23:37 ` Tom Tromey
2010-08-05 18:46   ` sami wagiaalla
2010-08-05 22:57     ` Ulrich Weigand
2010-08-06 16:23       ` sami wagiaalla
2010-08-06 16:48         ` Ulrich Weigand
2010-08-06 17:29           ` Tom Tromey
2010-08-08 15:01             ` Ulrich Weigand
2010-08-06 21:33           ` sami wagiaalla
2010-08-06 22:20             ` Tom Tromey
2010-08-09 15:59               ` sami wagiaalla [this message]
2010-08-09 17:35                 ` Tom Tromey
2010-08-09 18:04                   ` sami wagiaalla
2010-08-09 18:23                     ` Jan Kratochvil
2010-08-16 20:31                       ` sami wagiaalla
2010-08-16 20:59                         ` Pedro Alves
2010-08-17 16:16                           ` sami wagiaalla
2010-08-17 17:15                             ` Tom Tromey
2010-10-19 20:55                               ` sami wagiaalla

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C6025EF.5080509@redhat.com \
    --to=swagiaal@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).