From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 8Q2sDyF1cmkpMRAAWB0awg (envelope-from ) for ; Thu, 22 Jan 2026 14:06:09 -0500 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=D5DWSHMu; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 36E301E0AD; Thu, 22 Jan 2026 14:06:09 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_INVALID,DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id C99CB1E089 for ; Thu, 22 Jan 2026 14:06:07 -0500 (EST) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 8BFC74BC895F for ; Thu, 22 Jan 2026 19:06:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8BFC74BC895F Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=D5DWSHMu Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 384B04BA2E29 for ; Thu, 22 Jan 2026 19:05:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 384B04BA2E29 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 384B04BA2E29 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1769108738; cv=none; b=nbmfmlJ1pytBhcByWn2Jojn0GbIhWux7sl0xRlsNn1JP5H4l1ujTIfyC/ZxoY1B9Px4aTLpsSApUKAu0UWVlm/uUB3IkY487RMo2NsTnuv7cZm02fEa4aXOU7ihPSmlfOoyAAnT+O+aFRSAg6AVe2MdMFNAl4btm+9yb5GM9GZ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1769108738; c=relaxed/simple; bh=IgYCcd9FV62OUnYaLlBv2bAZ2X1AvD+o5GFhvcVf3Qc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=UupyeoJiF5/r398BMK/4e0rHTROtu/sgGbXDaljimiMLNGaoCxy2R4RrBmbJ/9k+S1MwopNIy5et+OpulzLK6mCiFj/EGpCe/K0DtK7aLbU4NNNs9Pl3hG87tmLtaB9REIjdXFf+5meD/AI9VP0Hd1Ew3uzsF1uAOQIR6lvDBcU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 384B04BA2E29 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1769108737; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZSNEMGuLiQ/LFq0Q5P/09zFtyhfFz/Kr6om23WfYEpo=; b=D5DWSHMuer9gtCHaci+bRNY2ZywJqXM+f0t6ETcxDGMF2VwvK9M2iSFZXzt3C3ys3R0Ci3 QkeDqg5+pzXYSpVnymlABbaQvPwskAvwzAnHrbNht6SGyMM2nVV+GFawIO+lQ0MUjJ/CYS xTyxzvlCCkoW7MCzzKH2AvSAxeJDo6o= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-37-XfBJcAijNL-LsT-7cxcWhw-1; Thu, 22 Jan 2026 14:05:35 -0500 X-MC-Unique: XfBJcAijNL-LsT-7cxcWhw-1 X-Mimecast-MFC-AGG-ID: XfBJcAijNL-LsT-7cxcWhw_1769108735 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1959E18005B3 for ; Thu, 22 Jan 2026 19:05:35 +0000 (UTC) Received: from keiths-thinkpadp1gen7.rmtuswa.csb (unknown [10.22.82.60]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7AB321800577 for ; Thu, 22 Jan 2026 19:05:34 +0000 (UTC) From: Keith Seitz To: gdb-patches@sourceware.org Subject: [PATCH v2] infcall: Add support for integer literals as reference function paramters Date: Thu, 22 Jan 2026 11:05:32 -0800 Message-ID: <8eca9443ad95346c52e5e4bec71eb44ba173f0c0.1769104412.git.keiths@redhat.com> In-Reply-To: <87qzuvcfb1.fsf@redhat.com> References: <87qzuvcfb1.fsf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: fx5dEjCP2CgNqrrYqU4aIiS1zz_vOubpM9-6YA3gxWI_1769108735 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true 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~public-inbox=simark.ca@sourceware.org This patch attempts to mitigate the shortcomings of passing literals to inferior function calls requiring references. The specific use case here is std::map's operator[]: std::map int_map; int_map[1] = 10; (gdb) print int_map[1] Attempt to take address of value not located in memory. This is occurring because while value_coerce_to_target understands that some values need to be allocated and copied to the inferior's memory, it only considers the actual parsed type of the argument value, ignoring the actual type of the function parameter. That is, in this specific case, the value's parsed type is TYPE_CODE_INT, but the function requires TYPE_CODE_REF. We need to account for the reference. In value_arg_coerce, we have special handling for references, but it has not specifically dealt with this case. It now checks if the reference is in memory, and if it isn't, it copies it, if the type is trivially copyable. As a result of this patch, the last remaining failure in c++/15372 is now fixed, and that bug can be closed. With this patch, we can now print map entries with integer keys: (gdb) print int_map[1] $1 = (std::map, std::allocator > >::mapped_type &) @0x41f2d4: 10 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=15372 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=25957 Changes in v2 - Move logic to value_arg_coerce - Add some attempt to limit copying to trivially copyable types --- gdb/infcall.c | 19 ++- gdb/testsuite/gdb.cp/ref-params.cc | 95 ++++++++++++++- gdb/testsuite/gdb.cp/ref-params.exp | 122 +++++++++++++++++++ gdb/testsuite/gdb.cp/rvalue-ref-overload.exp | 1 - 4 files changed, 232 insertions(+), 5 deletions(-) diff --git a/gdb/infcall.c b/gdb/infcall.c index dcbae679d07..b836a868d15 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -276,10 +276,23 @@ value_arg_coerce (struct gdbarch *gdbarch, struct value *arg, return value_cast_pointers (type, arg, 0); /* Cast the value to the reference's target type, and then - convert it back to a reference. This will issue an error - if the value was not previously in memory - in some cases - we should clearly be allowing this, but how? */ + convert it back to a reference. For C++ reference parameters, + if the value is not already in memory (e.g., a literal), we + need to allocate space in the inferior and copy the value there. + If the value is already in memory, we can use its address + directly. */ new_value = value_cast (type->target_type (), arg); + if (new_value->lval () != lval_memory + && language_pass_by_reference (new_value->type ()) + .trivially_copyable) + { + LONGEST length = check_typedef (new_value->type ())->length (); + struct value *addr_val = value_allocate_space_in_inferior (length); + CORE_ADDR addr = value_as_address (addr_val); + write_memory (addr, new_value->contents ().data (), length); + new_value = value_at_lazy (new_value->type (), addr); + } + new_value = value_ref (new_value, type->code ()); return new_value; } diff --git a/gdb/testsuite/gdb.cp/ref-params.cc b/gdb/testsuite/gdb.cp/ref-params.cc index 12e2716b435..3c1aa82396a 100644 --- a/gdb/testsuite/gdb.cp/ref-params.cc +++ b/gdb/testsuite/gdb.cp/ref-params.cc @@ -60,6 +60,68 @@ int mf2(MultiChild& C) return mf1(C); } +/* A class to be used by functions and methods exercising c++/25957. */ +class TestClass +{ + public: + int value; + + TestClass (int v) : value (v) {} + + int + const_ref_method (const int &x) const + { + return value + x; + } + + int + const_ref_method (const TestClass &obj) const + { + return value + obj.value; + } + + int + ref_method (int &x) + { + return value + 2 * x; + } + + int + ref_method (TestClass &obj) + { + return value + 2 * obj.value; + } +}; + +/* Define globals to be used by functions and methods exercising c++/25957. */ +int global_int = 42; +TestClass global_obj (10); + +/* Helper functions to test reference parameter behavior for c++/25957. */ +int +const_ref_func (const int &x) +{ + return x * 2; +} + +int +const_ref_func (const TestClass &obj) +{ + return obj.value * 2; +} + +int +ref_func (int &x) +{ + return x + 1; +} + +int +ref_func (TestClass &obj) +{ + return obj.value + 1; +} + int main(void) { Child Q(42); @@ -76,5 +138,36 @@ int main(void) mf2(MQ); /* Set breakpoint MQ here. */ - return 0; + TestClass obj (5); + int local_var = 15; + + /* Prevent compiler from optimizing away the function and method calls. */ + int dummy_int = 99; + (void) const_ref_func (dummy_int); + (void) const_ref_func (global_int); + (void) const_ref_func (obj); + (void) const_ref_func (global_obj); + (void) ref_func (dummy_int); + (void) ref_func (global_int); + (void) ref_func (obj); + (void) ref_func (global_obj); + (void) obj.const_ref_method (dummy_int); + (void) obj.const_ref_method (global_int); + (void) obj.const_ref_method (obj); + (void) obj.const_ref_method (global_obj); + (void) obj.ref_method (dummy_int); + (void) obj.ref_method (global_int); + (void) obj.ref_method (obj); + (void) obj.ref_method (global_obj); + (void) global_obj.const_ref_method (dummy_int); + (void) global_obj.const_ref_method (global_int); + (void) global_obj.const_ref_method (obj); + (void) global_obj.const_ref_method (global_obj); + (void) global_obj.ref_method (dummy_int); + (void) global_obj.ref_method (global_int); + (void) global_obj.ref_method (obj); + (void) global_obj.ref_method (global_obj); + + /* Breakpoint here for c++/25957 testing. */ + return 0; /* breakpoint-here */ } diff --git a/gdb/testsuite/gdb.cp/ref-params.exp b/gdb/testsuite/gdb.cp/ref-params.exp index b61055e9f50..a94927fae56 100644 --- a/gdb/testsuite/gdb.cp/ref-params.exp +++ b/gdb/testsuite/gdb.cp/ref-params.exp @@ -63,3 +63,125 @@ gdb_test "print f1(MQR)" ".* = 53" gdb_test "print mf1(MQR)" ".* = 106" gdb_test "print mf2(MQR)" ".* = 106" gdb_test "print f3(Q.id)" ".* = 42" + +# Inferior function call tests which have reference arguments. +# https://sourceware.org/bugzilla/show_bug.cgi?id=25957 +gdb_start_again "breakpoint-here" + +# Test functions taking const reference parameter. +gdb_test "print const_ref_func(10)" \ + "= 20" \ + "call function with const ref param and literal" + +gdb_test "print const_ref_func(global_int)" \ + "= 84" \ + "call function with const ref param and global variable" + +gdb_test "print const_ref_func(local_var)" \ + "= 30" \ + "call function with const ref param and local variable" + +gdb_test "print const_ref_func(obj)" \ + "= 10" \ + "call function with const ref param and object" + +gdb_test "print const_ref_func(global_obj)" \ + "= 20" \ + "call function with const ref param and global object" + +# Test functions taking non-const reference parameter. +gdb_test "print ref_func(10)" \ + "Cannot resolve function ref_func to any overloaded instance" \ + "call function with non-const ref param and literal" + +gdb_test "print ref_func(global_int)" \ + " = 43" \ + "call function with non-const ref param and global variable" + +gdb_test "print ref_func(local_var)" \ + " = 16" \ + "call function with non-const ref param and local variable" + +gdb_test "print ref_func(obj)" \ + "= 6" \ + "call function with non-const ref param and object" + +gdb_test "print ref_func(global_obj)" \ + "= 11" \ + "call function with non-const ref param and global object" + +# Test methods taking constant reference parameter. +gdb_test "print obj.const_ref_method(5)" \ + "= 10" \ + "call const method with const ref param and literal" + +gdb_test "print obj.const_ref_method(global_int)" \ + "= 47" \ + "call const method with const ref param and global variable" + +gdb_test "print obj.const_ref_method(local_var)" \ + "= 20" \ + "call const method with const ref param and local variable" + +gdb_test "print obj.const_ref_method (obj)" \ + "= 10" \ + "call method with const ref param and object" + +# Test methods taking non-const reference parameters. +gdb_test "print obj.ref_method(5)" \ + "Cannot resolve method TestClass::ref_method to any overloaded instance" \ + "call method with non-const ref param and literal" + +gdb_test "print obj.ref_method(global_int)" \ + "= 89" \ + "cal method with non-const ref param and global variable" + +gdb_test "print obj.ref_method(local_var)" \ + " = 35" \ + "call method with non-const ref param and local variable" + +gdb_test "print obj.ref_method(obj)" \ + "= 15" \ + "call method with non-const ref param and object" + +# Test global_obj methods taking constant reference parameter. +gdb_test "print global_obj.const_ref_method(5)" \ + "= 15" \ + "call global const method with const ref param and literal" + +gdb_test "print global_obj.const_ref_method(global_int)" \ + "= 52" \ + "call global const method with const ref param and global variable" + +gdb_test "print global_obj.const_ref_method(local_var)" \ + "= 25" \ + "call global const method with const ref param and local variable" + +gdb_test "print global_obj.const_ref_method(obj)" \ + "= 15" \ + "call global method with const ref param and object" + +gdb_test "print global_obj.const_ref_method(global_obj)" \ + "= 20" \ + "call global method with const ref param and global object" + +# Test global_obj methods taking non-const reference parameters. +gdb_test "print global_obj.ref_method(5)" \ + "Cannot resolve method TestClass::ref_method to any overloaded instance" \ + "call global method with non-const ref param and literal" + +gdb_test "print global_obj.ref_method(global_int)" \ + "= 94" \ + "call global method with non-const ref param and global variable" + +gdb_test "print global_obj.ref_method(local_var)" \ + "= 40" \ + "call global method with non-const ref param and local variable" + +gdb_test "print global_obj.ref_method(obj)" \ + "= 20" \ + "call global method with non-const ref param and object" + +gdb_test "print global_obj.ref_method(global_obj)" \ + "= 30" \ + "call global method with non-const ref param and global object" \ No newline at end of file diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp index bd6933673db..b9da32c244e 100644 --- a/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp +++ b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp @@ -64,7 +64,6 @@ gdb_test "print f (i)" "1" "lvalue reference overload" gdb_test "print f (ci)" "2" "lvalue reference to const overload" -setup_kfail "c++/15372" "*-*-*" gdb_test "print f (3)" "3" "rvalue reference overload" gdb_test "print g (i)" \ base-commit: 01be62d46b2e05e5a994b080974dd3832755e137 -- 2.52.0