From patchwork Sat May 18 13:41:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Domani X-Patchwork-Id: 90408 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 348553858402 for ; Sat, 18 May 2024 13:42:17 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from sonic310-57.consmr.mail.ir2.yahoo.com (sonic310-57.consmr.mail.ir2.yahoo.com [77.238.177.30]) by sourceware.org (Postfix) with ESMTPS id D58FE3858C52 for ; Sat, 18 May 2024 13:41:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D58FE3858C52 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=yahoo.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yahoo.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D58FE3858C52 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=77.238.177.30 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716039714; cv=none; b=IIBHA5LasLnd+FmJl8ERN4C6wJER1Z3YDJkxg6B47uR3q/nnxKrDLAu/+foHJivYKWobqa1rQyZEazJgEYjWmzHSh8AmOr5XRyiIg3nVKwjQYH8mVd61z5AN44k3S3fYUbjSmWiUaPK36L0mTE1G6iL5eNcBFUgMIg/Qf3ybEAc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716039714; c=relaxed/simple; bh=jHBZPhqRQVUvg2JAPc5bqrxlp6YtJQrZVDfixpYN4tE=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=VFN1FAkBgjxsIR2H8hGwPyMkGrS5/K4MuUXgHdUH/90AijoVQPPP5VtBwh+Okcf2mZc6uIeEFksl5G/1/g2U0MjUwUqBvMi4kgmi3khqstdsAUotsnQV3ONKcfYOEppo/SONtP/b49vtou+ZWiEYb/ncISKZiGbFrRUy1418ODw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s2048; t=1716039709; bh=YAku32ymkmqYzMRFDDrrjF0aYLU/WAXO/4hzmcmS15k=; h=From:To:Cc:Subject:Date:References:From:Subject:Reply-To; b=ZY7C1CjEmRTWbGdTk0XAdLBtwZSJK1mLMWTmb+BSj/J84oc5cIW6Hk6oPgkiFS2fSpB8lRqEUodTGkYLE3qfnmECyQdTvvnGuyUVZrfuVqyKPQ70Zu4yhfvPprbFR6Irn20Hh2jQQi39Kjh1qd3O9GQEl5KPEvUefcwK+PA9Ovs4TGmVylXFb3jQ7kRR/f8sSXLgAjloVMPNiceAzJ2X6+EApIQB8ft5iLsKuM2DuEIsC+nsJDBUqC4yvIWGw4V3V4mRHVlQ3fczd5sCJ7+gcGXgpGSk/SaDDKjkbGW6zXR3LDvnP3bR4Z5MQGAk8AhVmK/S1I416flna2JzoDmffA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1716039709; bh=YdQl3HibSPrxYK34ormV9KA4krhDPt75poIAGC98fLc=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=NkBtPIQ8Fa/WHdH0XXb0XQqva+np8S0ZolxkvVdKzHiP9dQlW1Q0BpRU5xcUXiSvqbnYeueatf50qvy03zyFa6Xfilk/IT7s1PihfcjEpeA9X7UKgBFp4FJ00wjSm+zMDV7bVBTIiNhytQQ2F1peUiKUn1Lo6r3Rv7akH/dVFvUJdT6i32p0QhhS6v7P2EdJIyKIokOVOTRxZzixbjKF67zEFVzUqOaVXK9XVf2zzISDFmN4hSy3IYikeg0omb/Docgp6CekA6HzpJxOGf7HxNL7X/xonRHXFnbY3JZp3IipW13c6LWSYS3pLGfwVocSyRfFEGNcK8AT7y5f4C5SgA== X-YMail-OSG: CQRaSyoVM1k3detvljrj1fbNsoVyhroTzT7zJy7jlAQCoL56.ubrxUdGaLshDRv TaXDYF62.yJtQej92hb0.72Liwc77s6.G3OUh9tF519MRjuT6Fs2TMl6oj2boitSyuA2xU2yTvgD yoO4.TLaEEdh1xfJVdhPcIKvFWqBShJrl3VRwefzAUw.o86QofGLUrw.jqEUSsMNywT_70fUSVlm vUmzIHGUpk4aJj.F789uoTFE99vzKfW.ugCEspz.AbdcarMHnZbn7Tw.v3jBX9PWPHR5K7vjM6hC vuS8Mh0Ox7Y3TmLjcGvGrQaPnZ3TpwONOAzjCk.pLVoUQtO7QTCWGaOOyrBN9SlTzTStWG7rTRRx dyKxcNu7wn1PQEDcCsfiuCKMtH3eJUtmW.nSI8gNoWF9T1CkP5k9ZLpYJxEawKHXcCXFCdzd1Lkh 8Jrp6znBhrzE3Roi8t0Riy2O3AAYpWi_YI8Xna481mrl4mT0e.fqVVm3KvF24A.T1y7C8MJS36WD Eb.XtZZaV5PK0PM6jd2VVlzofzy2YdUkn8085pfUSi50FStrBVcNgij_dD8TFXLLfLnYb_JCb4FZ ADJUQ47Fs1jJ5RAhzHBFt5DyqpgdjGe3EzHBJttwHDnoudGT9VmKHjc0Jx9tSkVvtD0tYwbPtTSt 1x1YUcQVS4a3YW413rVS4s4pFW1oEsbaM_Ew3KGJ6t5sDm65VyPZ7Jb6wZu0t7M23X5vJvOp0skB HHQHdi5and0Pzx0fT4eOm9SDvyugu4fXwu5_31yZKtobqiABlfd065D0FnHQIOGa3X38JK3oBuf1 P.lu3a7UudmLRrW0YIPaU7aX9B8_Lw__2.9mh8B87KftxQXpXYqzh3V.5i05h.n_7gvYk.vttAyp yUbIEV3i8Gfk.H3aG8yO1guBp9ffOFxoWdsSyNm85EtsrMXMrcRYq9bUuwa5Kdl5uSmGth6NOjRJ c4HR9pzy6WJ7Qjj3HfbyJNkeYDqg.eckLmSNidkr7BK4eAfLOaOytjCxXgNatIc3YYwbDUW9JZR0 .TYknpd1SQ0_kWuH9dqbXtt55OqB50QG5eLTDRMVFlDTra1NKNLleZRwOdSVmvxP.DFdpQD_WwbK z.ylzXeDODZEtEDIJGq_OiFDqwypf9lKWutcJxYXrk4sT5lgkFqGr1M6107lx8U7fqWNJLjcerjk 4cnmDHZA8hO4dj.1_6.lXR_H2MXo6qAUpYMDU1xSpPqERKDpCumyxUprzSstmLsIjrKNggRfWH1i 1XoweoDGvknqdsa3H5AJtWu3mwUulfG0YLBXe9IkJ6u8Adbuqti_TZ6f2FawXbe1CrHAjLqW5q.v z.1Tl5u4BshT9IVF1JcgNyo5WmjXb3iuGQXY85RHBmpDc5BUcnATlNTir1eQgQwqKU.lK7q2XavV I0lhB0eCWZ74hNt8RMhL4ykF3UO7h1RAVVq_DCplIuNDGp8tqnO4ClY15fEjP3FC2MathimzKTvE YkiLoTK8t4Q2Ygvx1HFpcl.AIbpVEoVXoL_twNEpHsRkPHZu3mnYxTuqXiOmBveyAFCaNRO3e49f 8vqENvPDhbXKI_93HcBHXclIz6OXRT0nRiiqmn63YGrKeVCqWJuNfmQxJ9xftjTiodIUmvlIiE5h zeMM7_MPbUqE7r0Dq0iM4809zKURFsQsIjn3Oe3ll.98TD46sLxbxc9NDaXqq.W6VQtj7AR1fR6H AUHeJs4qvINGyNDFLW7YM2TWMDxuHNw6FpjLBjXZxT1OOl0ZoPr5cpJVNhy9SBbL7dzU6.A76K8_ 5oxkho2xPldvh.2QjMJ8Va76xd8f.4jqW.haEOoF5JXVU..DIahIyniLZxPt9ytNIzskd2zpWbNb FsEmLF1CZBrWTczJNyOVVipK9k0uBE1NfdQxNJuIALYB2.xGfB4eF1ucfajrHj2ZeIW_WHVLSh8n Fwi78PSKnwjueU4Z9Mi1xNcMk5SIVAen3IW7uC44hJiVzYAnZrGz0Qb7mAjRV6g3LQi8ywOY8q4e KJQzBabXgvpAjV9T3hUZ1scd8feZ0.ZVHSsCFHXRQ1NqLNj9dK7.NmEye7C.h9sPcgwNPbKZd4h3 PdQ0yqgHT.9ba6lr6Rf3srT8YRGSwhgCEvH7I11_OZslp.HQaHvEnT4TVfUoajIgGbe600ff1ex8 U.KRo0cQWzKZXbYSiWWp.KKXqpqiKWlB2mF74o8Mxh18uiXbAcT1tArGjUba35Fhqit1hL8T0VK2 DFIh4ndyN_LtAnaL9HDi_cFOQZy2Cg5R2.r5NAOIguZg. X-Sonic-MF: X-Sonic-ID: 9a6eb0c9-8df0-48a9-983d-27f4847218e5 Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.ir2.yahoo.com with HTTP; Sat, 18 May 2024 13:41:49 +0000 Received: by hermes--production-ir2-7b99fc9bb6-npkzn (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID e00057b5afae63c108758c4641d5f48e; Sat, 18 May 2024 13:41:47 +0000 (UTC) From: Hannes Domani To: gdb-patches@sourceware.org Cc: blarsen@redhat.com, tom@tromey.com Subject: [PATCH v3] Allow calling of user-defined function call operators Date: Sat, 18 May 2024 15:41:23 +0200 Message-Id: <20240518134123.1243-1-ssbssa@yahoo.de> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-Antivirus: Avast (VPS 240518-2, 05/18/2024), Outbound message X-Antivirus-Status: Clean References: <20240518134123.1243-1-ssbssa.ref@yahoo.de> X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Currently it's not possible to call user-defined function call operators, at least not without specifying operator() directly: ``` (gdb) l 1 1 struct S { 2 int operator() (int x) { return x + 5; } 3 }; 4 5 int main () { 6 S s; 7 8 return s(23); 9 } (gdb) p s(10) Invalid data type for function to be called. (gdb) p s.operator()(10) $1 = 15 ``` This now looks if an user-defined call operator is available when trying to 'call' a struct value, and calls it instead, making this possible: ``` (gdb) p s(10) $1 = 15 ``` The change in operation::evaluate_funcall is to make sure the type fields are only used for function types, only they use them as the argument types. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=12213 --- v2: - Move the logic into evaluate_subexp_do_call, to avoid duplication in every evaluate_funcall of each operation subclass. This makes it now work for some cases it didn't in v1, like if it's called on a class member (`print c.m(5)` in the new test). - Added tests for other (struct member) operations. v3: - Additional comments. --- gdb/eval.c | 32 +++++++++++++++++++++++++++++--- gdb/testsuite/gdb.cp/userdef.cc | 22 ++++++++++++++++++++++ gdb/testsuite/gdb.cp/userdef.exp | 7 +++++++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/gdb/eval.c b/gdb/eval.c index 6b752e70635..356e88b8d4e 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -588,14 +588,36 @@ evaluate_subexp_do_call (expression *exp, enum noside noside, { if (callee == NULL) error (_("Cannot evaluate function -- may be inlined")); + + type *ftype = callee->type (); + + /* If the callee is a struct, there might be a user-defined function call + operator that should be used instead. */ + std::vector vals; + if (overload_resolution + && exp->language_defn->la_language == language_cplus + && check_typedef (ftype)->code () == TYPE_CODE_STRUCT) + { + /* Include space for the `this' pointer at the start. */ + vals.resize (argvec.size () + 1); + + vals[0] = value_addr (callee); + for (int i = 0; i < argvec.size (); ++i) + vals[i + 1] = argvec[i]; + + int static_memfuncp; + find_overload_match (vals, "operator()", METHOD, &vals[0], nullptr, + &callee, nullptr, &static_memfuncp, 0, noside); + if (!static_memfuncp) + argvec = vals; + } + if (noside == EVAL_AVOID_SIDE_EFFECTS) { /* If the return type doesn't look like a function type, call an error. This can happen if somebody tries to turn a variable into a function call. */ - type *ftype = callee->type (); - if (ftype->code () == TYPE_CODE_INTERNAL_FUNCTION) { /* We don't know anything about what the internal @@ -666,9 +688,13 @@ operation::evaluate_funcall (struct type *expect_type, struct type *type = callee->type (); if (type->code () == TYPE_CODE_PTR) type = type->target_type (); + /* If type is a struct, num_fields would refer to the number of + members in the type, not the number of arguments. */ + bool type_has_arguments + = type->code () == TYPE_CODE_FUNC || type->code () == TYPE_CODE_METHOD; for (int i = 0; i < args.size (); ++i) { - if (i < type->num_fields ()) + if (type_has_arguments && i < type->num_fields ()) vals[i] = args[i]->evaluate (type->field (i).type (), exp, noside); else vals[i] = args[i]->evaluate_with_coercion (exp, noside); diff --git a/gdb/testsuite/gdb.cp/userdef.cc b/gdb/testsuite/gdb.cp/userdef.cc index 774191726f3..7e045e46b3b 100644 --- a/gdb/testsuite/gdb.cp/userdef.cc +++ b/gdb/testsuite/gdb.cp/userdef.cc @@ -307,8 +307,21 @@ class Member { public: int z; + + int operator() (); + int operator() (int); }; +int Member::operator() () +{ + return z; +} + +int Member::operator() (int value) +{ + return value * z; +} + bool operator== (const Member &m1, const Member &m2) { return m1.z == m2.z; @@ -335,9 +348,11 @@ int main (void) Container c; Member mem1, mem2; int val; + Member Container::* mptr = &Container::m; mem1.z = 5; mem2.z = 7; + c.m.z = 8; marker1(); // marker1-returns-here cout << one; // marker1-returns-here @@ -404,6 +419,13 @@ int main (void) ++three; cout << "preinc " << three; + val = mem1 (); + cout << "funcall " << val << endl; + val = mem1 (10); + cout << "funcall 2 " << val << endl; + val = (c.*mptr) (11); + cout << "funcall 3 " << val << endl; + (*c).z = 1; return 0; diff --git a/gdb/testsuite/gdb.cp/userdef.exp b/gdb/testsuite/gdb.cp/userdef.exp index e96636bef0c..ce2781977e7 100644 --- a/gdb/testsuite/gdb.cp/userdef.exp +++ b/gdb/testsuite/gdb.cp/userdef.exp @@ -132,4 +132,11 @@ gdb_test "ptype &*c" "type = (struct|class) Member {(\[\r\n \]+public:)?\[\r\n \ gdb_test "print operator== (mem1, mem2)" " = false" gdb_test "print operator== (mem1, mem1)" " = true" +gdb_test "print mem1()" " = 5" +gdb_test "print mem1(10)" " = 50" +gdb_test "print (*&mem1)(2)" " = 10" +gdb_test "print (c.*mptr)(3)" " = 24" +gdb_test "print (&c)->m(4)" " = 32" +gdb_test "print c.m(5)" " = 40" + gdb_exit