From patchwork Thu Jul 13 02:19:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 21579 Received: (qmail 7742 invoked by alias); 13 Jul 2017 02:29:29 -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 7278 invoked by uid 89); 13 Jul 2017 02:29:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 13 Jul 2017 02:29:20 +0000 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA54461D19 for ; Thu, 13 Jul 2017 02:19:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com DA54461D19 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=palves@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com DA54461D19 Received: from cascais.lan (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 63D6760E37 for ; Thu, 13 Jul 2017 02:19:43 +0000 (UTC) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 12/13] Fix calling prototyped functions via function pointers Date: Thu, 13 Jul 2017 03:19:29 +0100 Message-Id: <1499912370-1842-13-git-send-email-palves@redhat.com> In-Reply-To: <1499912370-1842-1-git-send-email-palves@redhat.com> References: <1499912370-1842-1-git-send-email-palves@redhat.com> Calling a prototyped function via a function pointer with the right prototype doesn't work correctly, if the called function requires argument coercion... Like, e.g., with: float mult (float f1, float f2) { return f1 * f2; } (gdb) p mult (2, 3.5) $1 = 7 (gdb) p ((float (*) (float, float)) mult) (2, 3.5) $2 = 0 both calls should have returned the same, of course. The problem is that GDB misses marking the type of the function pointer target as prototyped... Without the fix, the new test fails like this: (gdb) p ((int (*) (float, float)) t_float_values2)(3.14159,float_val2) $30 = 0 (gdb) FAIL: gdb.base/callfuncs.exp: p ((int (*) (float, float)) t_float_values2)(3.14159,float_val2) gdb/ChangeLog: yyyy-mm-dd Pedro Alves * gdbtypes.c (lookup_function_type_with_arguments): Mark function types with more than one parameter as prototyped. gdb/ChangeLog: yyyy-mm-dd Pedro Alves * gdb.base/callfuncs.exp (do_function_calls): New parameter "prototypes". Test calling float functions via prototyped and unprototyped function pointers. (perform_all_tests): New parameter "prototypes". Pass it down. (top level): Pass down "prototypes" parameter to perform_all_tests. --- gdb/gdbtypes.c | 2 ++ gdb/testsuite/gdb.base/callfuncs.exp | 26 +++++++++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 674a724..fc86225 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -547,6 +547,8 @@ lookup_function_type_with_arguments (struct type *type, gdb_assert (nparams == 0); TYPE_PROTOTYPED (fn) = 1; } + else + TYPE_PROTOTYPED (fn) = 1; } TYPE_NFIELDS (fn) = nparams; diff --git a/gdb/testsuite/gdb.base/callfuncs.exp b/gdb/testsuite/gdb.base/callfuncs.exp index 3651963..a537ebd 100644 --- a/gdb/testsuite/gdb.base/callfuncs.exp +++ b/gdb/testsuite/gdb.base/callfuncs.exp @@ -39,7 +39,7 @@ set skip_float_test [gdb_skip_float_test] # specifies that the numeric value of a relational or logical expression # (computed in the inferior) is 1 for true and 0 for false. -proc do_function_calls {} { +proc do_function_calls {prototypes} { global gdb_prompt skip_float_test # We need to up this because this can be really slow on some boards. @@ -95,11 +95,25 @@ proc do_function_calls {} { setup_xfail "mn10300-*-*" if { [test_compiler_info "armcc-*"] } { setup_xfail "*-*-*" } gdb_test "p t_float_values(float_val1,-2.3765)" " = 1" + # Same, via unprototyped function pointer (t_float_values is + # always unprototyped). + gdb_test "p ((int (*) ()) t_float_values)(float_val1,-2.3765)" " = 1" # Test passing of arguments which might not be widened. gdb_test "p t_float_values2(0.0,0.0)" " = 0" + # Same, via function pointer. + if {$prototypes} { + gdb_test "p ((int (*) (float, float)) t_float_values2)(0.0,0.0)" " = 0" + } else { + gdb_test "p ((int (*) ()) t_float_values2)(0.0,0.0)" " = 0" + } gdb_test "p t_float_values2(3.14159,float_val2)" " = 1" + if {$prototypes} { + gdb_test "p ((int (*) (float, float)) t_float_values2)(3.14159,float_val2)" " = 1" + } else { + gdb_test "p ((int (*) ()) t_float_values2)(3.14159,float_val2)" " = 1" + } gdb_test "p t_float_many_args (float_val1, float_val2, float_val3, float_val4, float_val5, float_val6, float_val7, float_val8, float_val9, float_val10, float_val11, float_val12, float_val13, float_val14, float_val15)" " = 1" "call function with many float arguments." @@ -315,7 +329,7 @@ proc rerun_and_prepare {} { "next to t_structs_c" } -proc perform_all_tests {} { +proc perform_all_tests {prototypes} { gdb_test_no_output "set print sevenbit-strings" gdb_test_no_output "set print address off" gdb_test_no_output "set width 0" @@ -326,7 +340,7 @@ proc perform_all_tests {} { set old_reg_content [fetch_all_registers "retrieve original register contents"] # Perform function calls. - do_function_calls + do_function_calls $prototypes # Check if all registers still have the same value. set new_reg_content [fetch_all_registers \ @@ -500,9 +514,11 @@ proc perform_all_tests {} { # Perform all tests with and without function prototypes. if { ![prepare_for_testing "failed to prepare" $testfile $srcfile "$compile_flags additional_flags=-DPROTOTYPES"] } { - perform_all_tests + perform_all_tests 1 } if { ![prepare_for_testing "failed to prepare" $testfile $srcfile "$compile_flags additional_flags=-DNO_PROTOTYPES"] } { - with_test_prefix "noproto" perform_all_tests + with_test_prefix "noproto" { + perform_all_tests 0 + } }