From patchwork Sat Apr 27 16:36:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Domani X-Patchwork-Id: 89074 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 E9C363858C53 for ; Sat, 27 Apr 2024 16:37:00 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from sonic312-26.consmr.mail.ir2.yahoo.com (sonic312-26.consmr.mail.ir2.yahoo.com [77.238.178.97]) by sourceware.org (Postfix) with ESMTPS id A55F53858C33 for ; Sat, 27 Apr 2024 16:36:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A55F53858C33 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 A55F53858C33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=77.238.178.97 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714235797; cv=none; b=EffShkhIEFKen2QaEhhJ8+JpoPrsOQxwoI5VYoT3VfDbFGOmr2zh9BI+KU8kjSrWuXqB98nrqpD2xxtaAfWO3HV/s0wscpVkis4pIHfdYXvW12ftgf6TxX1LqMc7DsZHFg8fAthuMl4lZZ4cNMe1f24cz7DMgkC8ogg6wyBps9I= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714235797; c=relaxed/simple; bh=Y574QxeRJs3Fk0xFfvpryjXrEchVbtRY2Ob5/9wlRdM=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=R72P2t17vhffkhHmHsWncwacp8werX/es836duX/75zt2f8IR+vpfLf1FXPB85C9IoAvSfLVTcknEEeyc7qOtNR44ADLIF0JVjvTzLiRYmzmoU1tJlUhRqiCkgEAe5/+aIhjIH+PztyuZBvYN2Cgcz02jhByGbMTtuvYsCNGlRc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.de; s=s2048; t=1714235792; bh=se2iB71JPOaoUq1sG4PrCAipYR/CZKeAwcW/u2xdilM=; h=From:To:Cc:Subject:Date:References:From:Subject:Reply-To; b=LUrF//lhGBtW+Q1imvYiRhTWVRqTTeVvHXOhCl0SdTfmQS2FaVEG5hNHHbQeTxvbkWxyyvKkId6J0nzgj19rO8nplxwBUmfb7aYJrelaXOiHTocM10BeHsJMgFkERFNAzUyNZWpqiWWlm9hZR2c5Ry+qCbcmr8Jl05YXIHypcRjzr3rH7WF0w017HTLq5FDHKHXU5vvRAxW+wMxBpla0ziLHt6omh3kmveBlxW5jnQg0wXb3HjtEz8txI2lRHL7hBnjccfCmzffZTJGf6FH5iS8nHAWRhDI9P2GbQsOs/rYFs0lA2lPyHgHpyjFIwgx+03l9+XPPohXHPEjrQoSDwQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1714235792; bh=+M14zQhj172aVhkDIMMh5frKiCG3PbWW98bXGaw5gi1=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=RMoD9E6QafDfQxyKGwqpebuuzeX4Il+s0kHr5liFy//rYVqrXQbsf5AyBE5MUH3vxUPaBO5S4X6fMv7pUE1kj6IrP5h5NuowiVMvpzmVLm1fqNC0iLf2JMFB44GwXDCBCe87+xqFOPjqIVG+7q6BNTqlysdIc287JRLwOlqaz35K3fe4dWYTQiskCO88s1p8UwbbD+WSV/LynN7OI5dQypmhJiNMHnQTJS3EUsmm0rLIQPu2JbKsFQmOp2+vowsXMFWYfUZdL93s1lV8NbWjM1XPjo4NfeWu7qvuLYVYogAQWuBK3CG/jn8TsJMg6PtzWpxx7+naspLzDSQ9jxLHiQ== X-YMail-OSG: 1Jx9NzUVM1ns4cl12C_KCbYRnLqdwNFi6Hq.i46IULTcYdz9Zp3qweAKnpyMXNZ .41J2nQOe8xyNFr7IDfNrdGWc.J52CDLkdlt7frDZSsMqbd3ghIsnMqGNOM7bwB_88mQq0Xp04Pe MvGq4X7iPr_eUmujYO0hu3KceH0liEXTf0D6x3fLwSUhn_Nom0AKl9y1uQepI2VXMqpdzEAW94C2 _.B8mfpEdKLTNGRWFdHYEsmU463owqZUucYoo6UU7lUdKhSl2vBkRfaoSiqm7.S0D7_s9QkznuFZ 2q7zAPN_TYagW7wbjFy3WZxEZdrK5xVmVlPf.HLAvnrBKxgKUnYt9wG72sYZ65YfAD951.zOtLna b0g_3kbQjs2bUEgQ6D.yIC4F8l7tix9zszEQ41cVYNTf7gyXb3HmcTbLbChUG2mqd9XfZL7JDWXV ZY1LUytl6KMpXHAS6j4b7mEO6tPGJc_0Y1lf.KA8DOY6m.SRT5HSRlZcQbgN6Pb.MMJrZTl7LlbN 0wJaK47wSLrjYkcFmVr1m9VI_p2ufydnn_tsoimjdXe8Nq1W7oJHze4RZXdjJ9AnQSbu_iHfBQwS msYoyF7a0lGvW.csb_HS4Zntu1_V0hS60MmwhUUm67W7BteHqtGAVDTJQGxoPdIFs9ZcEw7grqIN v5NMjq8AvwOwYTLZ2GXEqb4srE_Paktpxr33yA0T93vM2jH9U55vHPztS7hvNj7r_eijGiLv7uh2 wcpeff4oDBfTjHXZzeo9uSPDGP0TQKZdtAKzoVVBVyMAeWixoH45tmWNoydZwO4nrb6Upv_c5EjO NqYZFYkjATiYSaBiW7YZcMBTMhWg2HK4sr6lwaEqQgWu3kcT.wm_8sqbeii4ODlAlPwN1viSk160 lWE0BjgKyhGDkAFBfZMbnQT.wbyK2IKK9CtUXxkj1uwQ9DZ0f1CAfby8On7TeSK45ziAfX5x5ptu ur_h1y.9vWpmxpPLDbSNivx135i67k.hEjmlAehKlshkXmVsQMeMckwdsRLm0Z6jKkENfNYxccKd d5WlHFUyFhLkmMn0wKy.kQRglmZDcxbVzxQ84E21Dr2Eo7Q2oYGfAowQNOqDi3qKn4tlTNhawl8i BlCvA3tv1V831E2sw3gVkZ.t_w9hiDWfdTs5ym3z7PP833QbT2MgHC0p_Hptj7u1cCXEU.nROCql N9RmtyiV6acu0xDbzFEhPVRvXTfM867S38ZGNKjcjw_ACTb8VNWKAhz4BngTbgurNLQrX2Oe_a_M Oftd4RjGBWoBHtMdXxbTCLL7RDmawC47tXWLAnWETVa_ltwI0JHzKv9Aze66yZAnJSrqw42oUPNI YliP7EZiVZtUOWxzaupf4g4ja8q4m0azbzkgUXozuHMd5DJ4eE0pFamWgxBsdiujGKzp40g3wlrr g9l1vGUObpYIPe5EmSJE2d0hu2XHOgU.y2QlUrDsCtXxk9y_XzrD6pOiCdFTPjXPYQ1J7h8QUq.N fPCkRy_4jSw3e.iSs7CyBbzAsjxHfTw9yOwhYNi_E7k04jfmhoW8vweUmus.EwY220x6IXDWHfKc WjSia3Uvtq3ExDuiqj1v8vAVxiESX9rG2AwHoCKXKHLI5JcYUgonksYzlABqHKJ..i22YkHeWser z9Fj8SVmStXlLNftcZ5PrTow3O2lxtSFlIidcAD6osDddcKLDRvRmcjk3QiPh5fWgV0uuWkKmqav nUcfJJ.1qeFlRs6wd0toR1YOu32XAD9hyLkM.cxrbNzG.2sZI3Q0GH59fLPtaTxARl8Mgt22hIyi IPIOrbS5KO.Y2bjuyBs3jjcX.RWJ6jRNe_QyNHodRYtfl0FV_5ApE5Cmo43j.JTvzgA5LBjiXDPI _BhcswHW1mGp6Zm0Rx_qvEiY1eDa.Cy7sREEBmMGEzbbyxs5xI3GN8ReMGO78xmMP7G_R7eSrL_H KddnYIhM8dp8xx9l.0UvRYLzTl2w0S7IUkVkF2V1Zib5qXh7v2Qm5pgCyTeRivN0PruCXO1pzZwK wVWznn3JIkamsZzHUi3mbZBurgA4rEUuGwzQbRpppgHep.y.WBVoN.LcjcWmU0w33hZOyADjpSeR WVzz0A72Mr9Ubi2Ai9WvGZ1NEJO2EgUFXNsajWsIYZUMec8UaYvxkx00bJhrvjnbssLii7aC2AKa vS3SSoTmrPZX72BgvGt_yPwaKZw7MNni9Uk95fTHznQanhFm5WHGEKydxDWZVYs6tFpWUdmw9r2Q RqcfiW0610AhBs1pHjuK10IiBn5aXdaHWGfxPMLEQUDXXWg-- X-Sonic-MF: X-Sonic-ID: 9775375e-0406-4bf0-9c7c-c28660859e7f Received: from sonic.gate.mail.ne1.yahoo.com by sonic312.consmr.mail.ir2.yahoo.com with HTTP; Sat, 27 Apr 2024 16:36:32 +0000 Received: by hermes--production-ir2-7b99fc9bb6-4j82p (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 12c2ed8162da4c2da800f48bcf5a169c; Sat, 27 Apr 2024 16:36:30 +0000 (UTC) From: Hannes Domani To: gdb-patches@sourceware.org Cc: blarsen@redhat.com Subject: [PATCH v2] Allow calling of user-defined function call operators Date: Sat, 27 Apr 2024 18:36:06 +0200 Message-Id: <20240427163606.1780-1-ssbssa@yahoo.de> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-Antivirus: Avast (VPS 240427-4, 04/27/2024), Outbound message X-Antivirus-Status: Clean References: <20240427163606.1780-1-ssbssa.ref@yahoo.de> X-Spam-Status: No, score=-10.5 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. --- gdb/eval.c | 29 ++++++++++++++++++++++++++--- gdb/testsuite/gdb.cp/userdef.cc | 22 ++++++++++++++++++++++ gdb/testsuite/gdb.cp/userdef.exp | 7 +++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/gdb/eval.c b/gdb/eval.c index 6b752e70635..8d5c354f480 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -588,14 +588,35 @@ 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) + { + 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 +687,11 @@ operation::evaluate_funcall (struct type *expect_type, struct type *type = callee->type (); if (type->code () == TYPE_CODE_PTR) type = type->target_type (); + 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