From patchwork Fri Mar 3 21:12:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 65993 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 216E9385022B for ; Fri, 3 Mar 2023 21:13:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 216E9385022B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1677878002; bh=+WBDTYiyJHcKpDYkgTxVQQhRAYR81QKXYzBS5+5Yrvg=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=AcjkbIBLDf5AbXMwG3rAbn/uE7V1I2gUlu4/tfpns7575XONhWjIT87URAIC1DtEu 26618HwNngFDB0+Y5dhrFX5Xq6/sY2KfNpebSyFYJgQSD3MYyiX3Zm0by2gfb2WuNv PakSB6v4ah5vrfvmH9XZua/FLvKd6QA2mnvxEK8c= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x12e.google.com (mail-il1-x12e.google.com [IPv6:2607:f8b0:4864:20::12e]) by sourceware.org (Postfix) with ESMTPS id 35DCC3858288 for ; Fri, 3 Mar 2023 21:12:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 35DCC3858288 Received: by mail-il1-x12e.google.com with SMTP id z5so2622919ilq.0 for ; Fri, 03 Mar 2023 13:12:24 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1677877943; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+WBDTYiyJHcKpDYkgTxVQQhRAYR81QKXYzBS5+5Yrvg=; b=wvGP0XWv88geCVnQyMk7kgni49TLq/irO1y4HlWWIKVj+X49StTzew1Eqvr8H2oZIu QdzSQot5lyTEZ52K8xXXZvzFF1NjCgHS8BxxpX8xuYZ/MRULjW9fsXc+pcgHeSZKwnId Bw3cgiru2UYrs785VIk8SdJuzhMozh4kGS108edxvMj5+HWE1OY3RoSoaZWHwy1dbkEh 8cl2fGO8jKBhYyPtqcOYrzcJRUgponPG742UevtIQV1HsxCoW3VdFgihjrfqvnv5m3Pn sALGNzSnUbWeAwqb5bmCQHRtL0EnsvSfO+tih1xtaysh24MCvYdehPFmg9HDXpsILToy vFWg== X-Gm-Message-State: AO0yUKXqe7Y5KHyDXJpICt//d6JELzovKBAb9hqKeHgfuVPDxDTyCtd+ sRHAipL5O0+VNBclMcK3udDk/kH7JIrdaaXbzYo= X-Google-Smtp-Source: AK7set/Nij1GUQJOKSzGv5u+EkAiLY+LZsltpQxkumJeCzphuzuLtYC0dlIzsQVlcPpi7XV5FpqPzw== X-Received: by 2002:a05:6e02:2193:b0:316:e033:86ba with SMTP id j19-20020a056e02219300b00316e03386bamr2940072ila.31.1677877943093; Fri, 03 Mar 2023 13:12:23 -0800 (PST) Received: from localhost.localdomain (75-166-130-93.hlrn.qwest.net. [75.166.130.93]) by smtp.gmail.com with ESMTPSA id g8-20020a925208000000b00313b281ecd2sm867988ilb.70.2023.03.03.13.12.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Mar 2023 13:12:22 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 7/8] Use gdb_gmp for scalar arithmetic Date: Fri, 3 Mar 2023 14:12:06 -0700 Message-Id: <20230303211207.1053037-8-tromey@adacore.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230303211207.1053037-1-tromey@adacore.com> References: <20230303211207.1053037-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LOTSOFHASH, KAM_SHORT, RCVD_IN_DNSWL_NONE, 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.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This changes gdb to use scalar arithmetic for expression evaluation. I suspect this patch is not truly complete, as there may be code paths that still don't correctly handle 128-bit integers. However, many things do work now. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30190 --- gdb/testsuite/gdb.rust/onetwoeight.exp | 65 ++++ gdb/testsuite/gdb.rust/onetwoeight.rs | 31 ++ gdb/utils.c | 30 -- gdb/utils.h | 7 - gdb/valarith.c | 489 ++++++++----------------- gdb/valops.c | 14 +- 6 files changed, 253 insertions(+), 383 deletions(-) create mode 100644 gdb/testsuite/gdb.rust/onetwoeight.exp create mode 100644 gdb/testsuite/gdb.rust/onetwoeight.rs diff --git a/gdb/testsuite/gdb.rust/onetwoeight.exp b/gdb/testsuite/gdb.rust/onetwoeight.exp new file mode 100644 index 00000000000..317c848a899 --- /dev/null +++ b/gdb/testsuite/gdb.rust/onetwoeight.exp @@ -0,0 +1,65 @@ +# Copyright (C) 2023 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 . + +# Test expression parsing and evaluation that requires Rust compiler. + +load_lib rust-support.exp +require allow_rust_tests + +set v [split [rust_compiler_version] .] +if {[lindex $v 0] == 1 && [lindex $v 1] < 43} { + untested "128-bit ints require rust 1.43 or greater" + return -1 +} + +standard_testfile .rs +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug rust}]} { + return -1 +} + +set line [gdb_get_line_number "BREAK"] +if {![runto ${srcfile}:$line]} { + untested "could not run to breakpoint" + return -1 +} + +gdb_test "print x" " = 340282366920938463463374607431768211455" +gdb_test "print y" " = 170141183460469231731687303715884105727" + +gdb_test "print x / 2" " = 170141183460469231731687303715884105727" +gdb_test "print sm * 2" " = 170141183460469231731687303715884105726" +gdb_test "print sm + sm" " = 170141183460469231731687303715884105726" +gdb_test "print x - y" " = 170141183460469231731687303715884105728" +gdb_test "print -y" " = -170141183460469231731687303715884105727" +gdb_test "print +y" " = 170141183460469231731687303715884105727" + +gdb_test "print/x x" " = 0xffffffffffffffffffffffffffffffff" +gdb_test "print x % 4" " = 3" +gdb_test "print !x" " = 0" + +gdb_test "print x < 0" " = false" +gdb_test "print -y < 0" " = true" +gdb_test "print x > y" " = true" +gdb_test "print y >= y" " = true" +gdb_test "print y <= y" " = true" +gdb_test "print y == y" " = true" +gdb_test "print x != y" " = true" + +gdb_test "print sm << 2" "= 340282366920938463463374607431768211452" +gdb_test "print x >> 2" "= 85070591730234615865843651857942052863" + +gdb_test "print/x x & mask" " = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0" +gdb_test "print/x x ^ mask" " = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f" +gdb_test "print/x mask | (mask >> 4)" " = 0xffffffffffffffffffffffffffffffff" diff --git a/gdb/testsuite/gdb.rust/onetwoeight.rs b/gdb/testsuite/gdb.rust/onetwoeight.rs new file mode 100644 index 00000000000..aa8cb1cf7b1 --- /dev/null +++ b/gdb/testsuite/gdb.rust/onetwoeight.rs @@ -0,0 +1,31 @@ +// Copyright (C) 2023 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 . + +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_assignments)] + + +fn empty() { +} + +fn main () { + let x : u128 = 340_282_366_920_938_463_463_374_607_431_768_211_455; + let sm : u128 = x /4; + let y : i128 = 170_141_183_460_469_231_731_687_303_715_884_105_727; + let mask : u128 = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0; + + empty(); // BREAK +} diff --git a/gdb/utils.c b/gdb/utils.c index 0138c8e9fb6..9ca83246b24 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -723,36 +723,6 @@ myread (int desc, char *addr, int len) return orglen; } -/* See utils.h. */ - -ULONGEST -uinteger_pow (ULONGEST v1, LONGEST v2) -{ - if (v2 < 0) - { - if (v1 == 0) - error (_("Attempt to raise 0 to negative power.")); - else - return 0; - } - else - { - /* The Russian Peasant's Algorithm. */ - ULONGEST v; - - v = 1; - for (;;) - { - if (v2 & 1L) - v *= v1; - v2 >>= 1; - if (v2 == 0) - return v; - v1 *= v1; - } - } -} - /* An RAII class that sets up to handle input and then tears down diff --git a/gdb/utils.h b/gdb/utils.h index 6e240deccbf..a383036bcfe 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -303,13 +303,6 @@ extern pid_t wait_to_die_with_timeout (pid_t pid, int *status, int timeout); extern int myread (int, char *, int); -/* Integer exponentiation: Return V1**V2, where both arguments - are integers. - - Requires V1 != 0 if V2 < 0. - Returns 1 for 0 ** 0. */ -extern ULONGEST uinteger_pow (ULONGEST v1, LONGEST v2); - /* Resource limits used by getrlimit and setrlimit. */ enum resource_limit_kind diff --git a/gdb/valarith.c b/gdb/valarith.c index 99597bef695..a8ae17e1730 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -34,13 +34,6 @@ static struct value *value_subscripted_rvalue (struct value *array, LONGEST index, LONGEST lowerbound); -/* Define whether or not the C operator '/' truncates towards zero for - differently signed operands (truncation direction is undefined in C). */ - -#ifndef TRUNCATION_TOWARDS_ZERO -#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2) -#endif - /* Given a pointer, return the size of its target. If the pointer type is void *, then return 1. If the target type is incomplete, then error out. @@ -726,36 +719,6 @@ value_concat (struct value *arg1, struct value *arg2) return result; } -/* Integer exponentiation: V1**V2, where both arguments are - integers. Requires V1 != 0 if V2 < 0. Returns 1 for 0 ** 0. */ - -static LONGEST -integer_pow (LONGEST v1, LONGEST v2) -{ - if (v2 < 0) - { - if (v1 == 0) - error (_("Attempt to raise 0 to negative power.")); - else - return 0; - } - else - { - /* The Russian Peasant's Algorithm. */ - LONGEST v; - - v = 1; - for (;;) - { - if (v2 & 1L) - v *= v1; - v2 >>= 1; - if (v2 == 0) - return v; - v1 *= v1; - } - } -} /* Obtain argument values for binary operation, converting from other types if one of them is not floating point. */ @@ -1099,33 +1062,39 @@ type_length_bits (type *type) both negative and too-large shift amounts, which are undefined, and would crash a GDB built with UBSan. Depending on the current language, if the shift is not valid, this either warns and returns - false, or errors out. Returns true if valid. */ + false, or errors out. Returns true and sets NBITS if valid. */ static bool check_valid_shift_count (enum exp_opcode op, type *result_type, - type *shift_count_type, ULONGEST shift_count) + type *shift_count_type, const gdb_mpz &shift_count, + unsigned long &nbits) { - if (!shift_count_type->is_unsigned () && (LONGEST) shift_count < 0) + if (!shift_count_type->is_unsigned ()) { - auto error_or_warning = [] (const char *msg) - { - /* Shifts by a negative amount are always an error in Go. Other - languages are more permissive and their compilers just warn or - have modes to disable the errors. */ - if (current_language->la_language == language_go) - error (("%s"), msg); - else - warning (("%s"), msg); - }; + LONGEST count = shift_count.as_integer (); + if (count < 0) + { + auto error_or_warning = [] (const char *msg) + { + /* Shifts by a negative amount are always an error in Go. Other + languages are more permissive and their compilers just warn or + have modes to disable the errors. */ + if (current_language->la_language == language_go) + error (("%s"), msg); + else + warning (("%s"), msg); + }; - if (op == BINOP_RSH) - error_or_warning (_("right shift count is negative")); - else - error_or_warning (_("left shift count is negative")); - return false; + if (op == BINOP_RSH) + error_or_warning (_("right shift count is negative")); + else + error_or_warning (_("left shift count is negative")); + return false; + } } - if (shift_count >= type_length_bits (result_type)) + nbits = shift_count.as_integer (); + if (nbits >= type_length_bits (result_type)) { /* In Go, shifting by large amounts is defined. Be silent and still return false, as the caller's error path does the right @@ -1249,299 +1218,135 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) else result_type = promotion_type (type1, type2); - if (result_type->is_unsigned ()) + gdb_mpz v1 = value_as_mpz (arg1); + gdb_mpz v2 = value_as_mpz (arg2); + gdb_mpz v; + + switch (op) { - LONGEST v2_signed = value_as_long (arg2); - ULONGEST v1, v2, v = 0; + case BINOP_ADD: + v = v1 + v2; + break; - v1 = (ULONGEST) value_as_long (arg1); - v2 = (ULONGEST) v2_signed; + case BINOP_SUB: + v = v1 - v2; + break; - switch (op) - { - case BINOP_ADD: - v = v1 + v2; - break; - - case BINOP_SUB: - v = v1 - v2; - break; - - case BINOP_MUL: - v = v1 * v2; - break; - - case BINOP_DIV: - case BINOP_INTDIV: - if (v2 != 0) - v = v1 / v2; - else - error (_("Division by zero")); - break; - - case BINOP_EXP: - v = uinteger_pow (v1, v2_signed); - break; - - case BINOP_REM: - if (v2 != 0) - v = v1 % v2; - else - error (_("Division by zero")); - break; - - case BINOP_MOD: - /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, - v1 mod 0 has a defined value, v1. */ - if (v2 == 0) - { - v = v1; - } - else - { - v = v1 / v2; - /* Note floor(v1/v2) == v1/v2 for unsigned. */ - v = v1 - (v2 * v); - } - break; - - case BINOP_LSH: - if (!check_valid_shift_count (op, result_type, type2, v2)) - v = 0; - else - v = v1 << v2; - break; - - case BINOP_RSH: - if (!check_valid_shift_count (op, result_type, type2, v2)) - v = 0; - else - v = v1 >> v2; - break; - - case BINOP_BITWISE_AND: - v = v1 & v2; - break; - - case BINOP_BITWISE_IOR: - v = v1 | v2; - break; - - case BINOP_BITWISE_XOR: - v = v1 ^ v2; - break; - - case BINOP_LOGICAL_AND: - v = v1 && v2; - break; - - case BINOP_LOGICAL_OR: - v = v1 || v2; - break; - - case BINOP_MIN: - v = v1 < v2 ? v1 : v2; - break; - - case BINOP_MAX: - v = v1 > v2 ? v1 : v2; - break; - - case BINOP_EQUAL: - v = v1 == v2; - break; - - case BINOP_NOTEQUAL: - v = v1 != v2; - break; - - case BINOP_LESS: - v = v1 < v2; - break; - - case BINOP_GTR: - v = v1 > v2; - break; - - case BINOP_LEQ: - v = v1 <= v2; - break; - - case BINOP_GEQ: - v = v1 >= v2; - break; - - default: - error (_("Invalid binary operation on numbers.")); - } + case BINOP_MUL: + v = v1 * v2; + break; - val = value::allocate (result_type); - store_unsigned_integer (val->contents_raw ().data (), - val->type ()->length (), - type_byte_order (result_type), - v); - } - else - { - LONGEST v1, v2, v = 0; + case BINOP_DIV: + case BINOP_INTDIV: + if (v2.sgn () != 0) + v = v1 / v2; + else + error (_("Division by zero")); + break; - v1 = value_as_long (arg1); - v2 = value_as_long (arg2); + case BINOP_EXP: + v = v1.pow (v2.as_integer ()); + break; + + case BINOP_REM: + if (v2.sgn () != 0) + v = v1 % v2; + else + error (_("Division by zero")); + break; - switch (op) + case BINOP_MOD: + /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, + v1 mod 0 has a defined value, v1. */ + if (v2.sgn () == 0) + { + v = v1; + } + else { - case BINOP_ADD: - v = v1 + v2; - break; - - case BINOP_SUB: - /* Avoid runtime error: signed integer overflow: \ - 0 - -9223372036854775808 cannot be represented in type - 'long int'. */ - v = (ULONGEST)v1 - (ULONGEST)v2; - break; - - case BINOP_MUL: - v = v1 * v2; - break; - - case BINOP_DIV: - case BINOP_INTDIV: - if (v2 != 0) - v = v1 / v2; - else - error (_("Division by zero")); - break; - - case BINOP_EXP: - v = integer_pow (v1, v2); - break; - - case BINOP_REM: - if (v2 != 0) - v = v1 % v2; - else - error (_("Division by zero")); - break; - - case BINOP_MOD: - /* Knuth 1.2.4, integer only. Note that unlike the C '%' op, - X mod 0 has a defined value, X. */ - if (v2 == 0) - { - v = v1; - } - else - { - v = v1 / v2; - /* Compute floor. */ - if (TRUNCATION_TOWARDS_ZERO && (v < 0) && ((v1 % v2) != 0)) - { - v--; - } - v = v1 - (v2 * v); - } - break; - - case BINOP_LSH: - if (!check_valid_shift_count (op, result_type, type2, v2)) - v = 0; - else - { - /* Cast to unsigned to avoid undefined behavior on - signed shift overflow (unless C++20 or later), - which would crash GDB when built with UBSan. - Note we don't warn on left signed shift overflow, - because starting with C++20, that is actually - defined behavior. Also, note GDB assumes 2's - complement throughout. */ - v = (ULONGEST) v1 << v2; - } - break; - - case BINOP_RSH: - if (!check_valid_shift_count (op, result_type, type2, v2)) - { - /* Pretend the too-large shift was decomposed in a - number of smaller shifts. An arithmetic signed - right shift of a negative number always yields -1 - with such semantics. This is the right thing to - do for Go, and we might as well do it for - languages where it is undefined. Also, pretend a - shift by a negative number was a shift by the - negative number cast to unsigned, which is the - same as shifting by a too-large number. */ - if (v1 < 0) - v = -1; - else - v = 0; - } - else - v = v1 >> v2; - break; - - case BINOP_BITWISE_AND: - v = v1 & v2; - break; - - case BINOP_BITWISE_IOR: - v = v1 | v2; - break; - - case BINOP_BITWISE_XOR: - v = v1 ^ v2; - break; - - case BINOP_LOGICAL_AND: - v = v1 && v2; - break; - - case BINOP_LOGICAL_OR: - v = v1 || v2; - break; - - case BINOP_MIN: - v = v1 < v2 ? v1 : v2; - break; - - case BINOP_MAX: - v = v1 > v2 ? v1 : v2; - break; - - case BINOP_EQUAL: - v = v1 == v2; - break; - - case BINOP_NOTEQUAL: - v = v1 != v2; - break; - - case BINOP_LESS: - v = v1 < v2; - break; - - case BINOP_GTR: - v = v1 > v2; - break; - - case BINOP_LEQ: - v = v1 <= v2; - break; - - case BINOP_GEQ: - v = v1 >= v2; - break; - - default: - error (_("Invalid binary operation on numbers.")); + v = v1 / v2; + /* Note floor(v1/v2) == v1/v2 for unsigned. */ + v = v1 - (v2 * v); } + break; - val = value::allocate (result_type); - store_signed_integer (val->contents_raw ().data (), - val->type ()->length (), - type_byte_order (result_type), - v); + case BINOP_LSH: + { + unsigned long nbits; + if (!check_valid_shift_count (op, result_type, type2, v2, nbits)) + v = 0; + else + v = v1 << nbits; + } + break; + + case BINOP_RSH: + { + unsigned long nbits; + if (!check_valid_shift_count (op, result_type, type2, v2, nbits)) + v = 0; + else + v = v1 >> nbits; + } + break; + + case BINOP_BITWISE_AND: + v = v1 & v2; + break; + + case BINOP_BITWISE_IOR: + v = v1 | v2; + break; + + case BINOP_BITWISE_XOR: + v = v1 ^ v2; + break; + + case BINOP_LOGICAL_AND: + v = v1 && v2; + break; + + case BINOP_LOGICAL_OR: + v = v1 || v2; + break; + + case BINOP_MIN: + v = v1 < v2 ? v1 : v2; + break; + + case BINOP_MAX: + v = v1 > v2 ? v1 : v2; + break; + + case BINOP_EQUAL: + v = v1 == v2; + break; + + case BINOP_NOTEQUAL: + v = v1 != v2; + break; + + case BINOP_LESS: + v = v1 < v2; + break; + + case BINOP_GTR: + v = v1 > v2; + break; + + case BINOP_LEQ: + v = v1 <= v2; + break; + + case BINOP_GEQ: + v = v1 >= v2; + break; + + default: + error (_("Invalid binary operation on numbers.")); } + + val = value_from_mpz (result_type, v); } return val; @@ -1960,7 +1765,11 @@ value_complement (struct value *arg1) type = check_typedef (arg1->type ()); if (is_integral_type (type)) - val = value_from_longest (type, ~value_as_long (arg1)); + { + gdb_mpz num = value_as_mpz (arg1); + num.complement (); + val = value_from_mpz (type, num); + } else if (type->code () == TYPE_CODE_ARRAY && type->is_vector ()) { struct type *eltype = check_typedef (type->target_type ()); diff --git a/gdb/valops.c b/gdb/valops.c index 2cef24fc4c5..f06969e92e6 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -569,7 +569,7 @@ value_cast (struct type *type, struct value *arg2) && (scalar || code2 == TYPE_CODE_PTR || code2 == TYPE_CODE_MEMBERPTR)) { - LONGEST longest; + gdb_mpz longest; /* When we cast pointers to integers, we mustn't use gdbarch_pointer_to_address to find the address the pointer @@ -578,12 +578,14 @@ value_cast (struct type *type, struct value *arg2) sees a cast as a simple reinterpretation of the pointer's bits. */ if (code2 == TYPE_CODE_PTR) - longest = extract_unsigned_integer - (arg2->contents (), type_byte_order (type2)); + longest = extract_unsigned_integer (arg2->contents (), + type_byte_order (type2)); else - longest = value_as_long (arg2); - return value_from_longest (to_type, convert_to_boolean ? - (LONGEST) (longest ? 1 : 0) : longest); + longest = value_as_mpz (arg2); + if (convert_to_boolean) + longest = bool (longest); + + return value_from_mpz (to_type, longest); } else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_ENUM