aboutsummaryrefslogtreecommitdiff
path: root/gdb/valarith.c
AgeCommit message (Collapse)AuthorFilesLines
2023-03-27Use gdb_gmp for scalar arithmeticTom Tromey1-324/+141
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
2023-03-27Use value_true in value_equal and value_lessTom Tromey1-4/+2
Both value_equal and value_less use value_as_long to check a presumably boolean result of calling value_binop. However, value_binop in this case actually returns an int as wide as its arguments, and this approach can then fail for integers wider than LONGEST. Instead, rewrite this in a form that works for any size integer.
2023-03-14Add operators and methods to gdb_mpqTom Tromey1-9/+9
This adds some operators and methods to gdb_mpq, in preparation for making its implementation private. This only adds the operators currently needed by gdb. More could be added as necessary.
2023-03-13Remove dead code from scalar_binopTom Tromey1-16/+0
scalar_binop has code for "&&" and "||", but I think this code can't currently be run -- and, furthermore, it doesn't make sense to have this code here, as the point of these operators is to short-circuit evaluation. This patch removes the dead code. Regression tested on x86-64 Fedora 36. Approved-by: Kevin Buettner <kevinb@redhat.com>
2023-03-02Fix some value commentsTom Tromey1-1/+5
I noticed a very stale comment in valarith.c. This patch fixes a few comments in this area. Reviewed-By: Andrew Burgess <aburgess@redhat.com>
2023-03-01Fix type of check_valid_shift_count parameterTom Tromey1-1/+1
check_valid_shift_count has an 'int' parameter that really should be an enum exp_opcode. This patch makes the change. Tested by rebuilding.
2023-02-28Remove value_inTom Tromey1-23/+0
value_in is unused. From git log, it seems to have been part of the Chill language, which was removed from gdb eons ago. This patch removes the function. Tested by rebuilding.
2023-02-21Issue error on erroneous expressionTom Tromey1-1/+1
A while back I discovered that this does not issue an error: (gdb) p $x = (void * ) 57 $3 = (void *) 0x39 (gdb) p $x + 7 = 3 $6 = (void *) 0x3 This patch fixes the bug. Regression tested on x86-64 Fedora 36. Reviewed-By: Bruno Larsen <blarsen@redhat.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=19312
2023-02-13Remove deprecated_lval_hackTom Tromey1-7/+7
This removes deprecated_lval_hack and the VALUE_LVAL macro, replacing all uses with a call to value::lval. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Introduce set_lval method on valueTom Tromey1-1/+1
This introduces the set_lval method on value, one step toward removing deprecated_lval_hack. Ultimately I think the goal should be for some of these set_* methods to be replaced with constructors; but I haven't done this, as the series is already too long. Other 'deprecated' methods can probably be handled the same way. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn some xmethod functions into methodsTom Tromey1-4/+4
This turns value_from_xmethod, result_type_of_xmethod, and call_xmethod to be methods of value. value_from_xmethod is a static "constructor" now. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn set_value_component_location into methodTom Tromey1-1/+1
This turns set_value_component_location into a method of value. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn many optimized-out value functions into methodsTom Tromey1-2/+2
This turns many functions that are related to optimized-out or availability-checking to be methods of value. The static function value_entirely_covered_by_range_vector is also converted to be a private method. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn remaining value_contents functions into methodsTom Tromey1-20/+20
This turns the remaining value_contents functions -- value_contents, value_contents_all, value_contents_for_printing, and value_contents_for_printing_const -- into methods of value. It also converts the static functions require_not_optimized_out and require_available to be private methods. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn some value_contents functions into methodsTom Tromey1-10/+10
This turns value_contents_raw, value_contents_writeable, and value_contents_all_raw into methods on value. The remaining functions will be changed later in the series; they were a bit trickier and so I didn't include them in this patch. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn value_zero into static "constructor"Tom Tromey1-7/+7
This turns value_zero into a static "constructor" of value. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn allocate_value into a static "constructor"Tom Tromey1-11/+11
This changes allocate_value to be a static "constructor" of value. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn value_address and set_value_address functions into methodsTom Tromey1-2/+2
This changes the value_address and set_value_address functions to be methods of value. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn value_lazy and set_value_lazy functions into methodsTom Tromey1-1/+1
This changes the value_lazy and set_value_lazy functions to be methods of value. Much of this patch was written by script. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13Turn value_type into methodTom Tromey1-48/+48
This changes value_type to be a method of value. Much of this patch was written by script. Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-10GDB: Only make data actually retrieved into value history availableMaciej W. Rozycki1-0/+15
While it makes sense to allow accessing out-of-bounds elements in the debuggee and see whatever there might happen to be there in memory (we are a debugger and not a programming rules enforcement facility and we want to make people's life easier in chasing bugs), e.g.: (gdb) print one_hundred[-1] $1 = 0 (gdb) print one_hundred[100] $2 = 0 (gdb) we shouldn't really pretend that we have any meaningful data around values recorded in history (what these commands really retrieve are current debuggee memory contents outside the original data accessed, really confusing in my opinion). Mark values recorded in history as such then and verify accesses to be in-range for them: (gdb) print one_hundred[-1] $1 = <unavailable> (gdb) print one_hundred[100] $2 = <unavailable> Add a suitable test case, which also covers integer overflows in data location calculation. Approved-By: Tom Tromey <tom@tromey.com>
2023-01-01Update copyright year range in header of all files managed by GDBJoel Brobecker1-1/+1
This commit is the result of running the gdb/copyright.py script, which automated the update of the copyright year range for all source files managed by the GDB project to be updated to include year 2023.
2022-10-14Use scoped_value_mark in more placesTom Tromey1-2/+1
I looked at all the spots using value_mark, and converted all the straightforward ones to use scoped_value_mark instead. Regression tested on x86-64 Fedora 34.
2022-09-21gdb: remove TYPE_LENGTHSimon Marchi1-30/+30
Remove the macro, replace all uses with calls to type::length. Change-Id: Ib9bdc954576860b21190886534c99103d6a47afb
2022-09-21gdb: remove TYPE_TARGET_TYPESimon Marchi1-20/+18
Remove the macro, replace all uses by calls to type::target_type. Change-Id: Ie51d3e1e22f94130176d6abd723255282bb6d1ed
2022-05-23[gdb/exp] Fix UB in scalar_binopTom de Vries1-1/+4
When building gdb with -fsanitize=undefined, I run into: ... $ gdb -q -batch -ex "p -(-0x7fffffffffffffff - 1)" src/gdb/valarith.c:1385:10: runtime error: signed integer overflow: \ 0 - -9223372036854775808 cannot be represented in type 'long int' $1 = -9223372036854775808 ... Fix this by performing the substraction in scalar_binop using unsigned types. Tested on x86_64-linux.
2022-04-08gdb: Avoid undefined shifts, fix Go shiftsPedro Alves1-4/+99
I noticed that a build of GDB with GCC + --enable-ubsan, testing against GDBserver showed this GDB crash: (gdb) PASS: gdb.trace/trace-condition.exp: trace: 0x00abababcdcdcdcd << 46 == 0x7373400000000000: advance to trace begin tstart ../../src/gdb/valarith.c:1365:15: runtime error: left shift of 48320975398096333 by 46 places cannot be represented in type 'long int' ERROR: GDB process no longer exists GDB process exited with wait status 269549 exp9 0 1 UNRESOLVED: gdb.trace/trace-condition.exp: trace: 0x00abababcdcdcdcd << 46 == 0x7373400000000000: start trace experiment The problem is that, "0x00abababcdcdcdcd << 46" is an undefined signed left shift, because the result is not representable in the type of the lhs, which is signed. This actually became defined in C++20, and if you compile with "g++ -std=c++20 -Wall", you'll see that GCC no longer warns about it, while it warns if you specify prior language versions. While at it, there are a couple other situations that are undefined (and are still undefined in C++20) and result in GDB dying: shifting by a negative ammount, or by >= than the bit size of the promoted lhs. For the latter, GDB shifts using (U)LONGEST internally, so you have to shift by >= 64 bits to see it: $ gdb --batch -q -ex "p 1 << -1" ../../src/gdb/valarith.c:1365:15: runtime error: shift exponent -1 is negative $ # gdb exited $ gdb --batch -q -ex "p 1 << 64" ../../src/gdb/valarith.c:1365:15: runtime error: shift exponent 64 is too large for 64-bit type 'long int' $ # gdb exited Also, right shifting a negative value is implementation-defined (before C++20, after which it is defined). For this, I chose to change nothing in GDB other than adding tests, as I don't really know whether we need to do anything. AFAIK, most implementations do an arithmetic right shift, and it may be we don't support any host or target that behaves differently. Plus, this becomes defined in C++20 exactly as arithmetic right shift. Compilers don't error out on such shifts, at best they warn, so I think GDB should just continue doing the shifts anyhow too. Thus: - Adjust scalar_binop to avoid the undefined paths, either by adding explicit result paths, or by casting the lhs of the left shift to unsigned, as appropriate. For the shifts by a too-large count, I made the result be what you'd get if you split the large count in a series of smaller shifts. Thus: Left shift, positive or negative lhs: V << 64 => V << 16 << 16 << 16 << 16 => 0 Right shift, positive lhs: Vpos >> 64 => Vpos >> 16 >> 16 >> 16 >> 16 => 0 Right shift, negative lhs: Vneg >> 64 => Vneg >> 16 >> 16 >> 16 >> 16 => -1 This is actually Go's semantics (the compiler really emits instructions to make it so that you get 0 or -1 if you have a too-large shift). So for that language GDB does the shift and nothing else. For other C-like languages where such a shift is undefined, GDB warns in addition to performing the shift. For shift by a negative count, for Go, this is a hard error. For other languages, since their compilers only warn, I made GDB warn too. The semantics I chose (we're free to pick them since this is undefined behavior) is as-if you had shifted by the count cast to unsigned, thus as if you had shifted by a too-large count, thus the same as the previous scenario illustrated above. Examples: (gdb) set language go (gdb) p 1 << 100 $1 = 0 (gdb) p -1 << 100 $2 = 0 (gdb) p 1 >> 100 $3 = 0 (gdb) p -1 >> 100 $4 = -1 (gdb) p -2 >> 100 $5 = -1 (gdb) p 1 << -1 left shift count is negative (gdb) set language c (gdb) p -2 >> 100 warning: right shift count >= width of type $6 = -1 (gdb) p -2 << 100 warning: left shift count >= width of type $7 = 0 (gdb) p 1 << -1 warning: left shift count is negative $8 = 0 (gdb) p -1 >> -1 warning: right shift count is negative $9 = -1 - The warnings' texts are the same as what GCC prints. - Add comprehensive tests in a new gdb.base/bitshift.exp testcase, so that we exercise all these scenarios. Change-Id: I8bcd5fa02de3114b7ababc03e65702d86ec8d45d
2022-03-16Reimplement array concatenation for Ada and DTom Tromey1-128/+41
This started as a patch to implement string concatenation for Ada. However, while working on this, I looked at how this code could possibly be called. It turns out there are only two users of concat_operation: Ada and D. So, in addition to implementing this for Ada, this patch rewrites value_concat, removing the odd "concatenate or repeat" semantics, which were completely unused. As Ada and D both seem to represent strings using TYPE_CODE_ARRAY, this removes the TYPE_CODE_STRING code from there as well.
2022-03-16Remove eval_op_concatTom Tromey1-1/+1
eval_op_concat has code to search for an operator overload of BINOP_CONCAT. However, the operator overloading code is specific to C++, which does not have this operator. And, binop_types_user_defined_p rejects this case right at the start, and value_x_binop does not handle this case. I think this code has been dead for a very long time. This patch removes it and hoists the remaining call into concatenation::evaluate, removing eval_op_concat entirely.
2022-01-01Automatic Copyright Year update after running gdb/copyright.pyJoel Brobecker1-1/+1
This commit brings all the changes made by running gdb/copyright.py as per GDB's Start of New Year Procedure. For the avoidance of doubt, all changes in this commits were performed by the script.
2021-12-13gdb: improve reuse of value contents when fetching array elementsAndrew Burgess1-9/+9
While working on a Python script, which was interacting with a remote target, I noticed some weird slowness in GDB. In my program I had a structure something like this: struct foo_t { int array[5]; }; struct foo_t global_foo; Then in the Python script I was fetching a complete copy of global foo, like: val = gdb.parse_and_eval('global_foo') val.fetch_lazy() Then I would work with items in foo_t.array, like: print(val['array'][1]) I called the fetch_lazy method specifically because I knew I was going to end up accessing almost all of the contents of val, and so I wanted GDB to do a single remote protocol call to fetch all the contents in one go, rather than trying to do lazy fetches for a couple of bytes at a time. What I observed was that, after the fetch_lazy call, GDB does, correctly, fetch the entire contents of global_foo, including all of the contents of array, however, when I access val.array[1], GDB still goes and fetches the value of this element from the remote target. What's going on is that in valarith.c, in value_subscript, for C like languages, we always end up treating the array value as a pointer, and then doing value_ptradd, and value_ind, the second of these calls always returns a lazy value. My guess is that this approach allows us to handle indexing off the end of an array, when working with zero element arrays, or when indexing a raw pointer as an array. And, I agree, that in these cases, where, even when the original value is non-lazy, we still will not have the content of the array loaded, we should be using the value_ind approach. However, for cases where we do have the array contents loaded, and we do know the bounds of the array, I think we should be using value_subscripted_rvalue, which is what we use for non C like languages. One problem I did run into, exposed by gdb.base/charset.exp, was that value_subscripted_rvalue stripped typedefs from the element type of the array, which means the value returned will not have the same type as an element of the array, but would be the raw, non-typedefed, type. In charset.exp we got back an 'int' instead of a 'wchar_t' (which is a typedef of 'int'), and this impacts how we print the value. Removing typedefs from the resulting value just seems wrong, so I got rid of that, and I don't see any test regressions. With this change in place, my original Python script is now doing no additional memory accesses, and its performance increases about 10x!
2021-12-03gdb: trivial changes to use array_viewSimon Marchi1-6/+3
Change a few relatively obvious spots using value contents to propagate the use array_view a bit more. Change-Id: I5338a60986f06d5969fec803d04f8423c9288a15
2021-12-03gdbsupport: add array_view copy functionSimon Marchi1-22/+27
An assertion was recently added to array_view::operator[] to ensure we don't do out of bounds accesses. However, when the array_view is copied to or from using memcpy, it bypasses that safety. To address this, add a `copy` free function that copies data from an array view to another, ensuring that the destination and source array views have the same size. When copying to or from parts of an array_view, we are expected to use gdb::array_view::slice, which does its own bounds check. With all that, any copy operation that goes out of bounds should be caught by an assertion at runtime. copy is implemented using std::copy and std::copy_backward, which, at least on libstdc++, appears to pick memmove when copying trivial data. So in the end there shouldn't be much difference vs using a bare memcpy, as we do right now. When copying non-trivial data, std::copy and std::copy_backward assigns each element in a loop. To properly support overlapping ranges, we must use std::copy or std::copy_backward, depending on whether the destination is before the source or vice-versa. std::copy and std::copy_backward don't support copying exactly overlapping ranges (where the source range is equal to the destination range). But in this case, no copy is needed anyway, so we do nothing. The order of parameters of the new copy function is based on std::copy and std::copy_backward, where the source comes before the destination. Change a few randomly selected spots to use the new function, to show how it can be used. Add a test for the new function, testing both with arrays of a trivial type (int) and of a non-trivial type (foo). Test non-overlapping ranges as well as three kinds of overlapping ranges: source before dest, dest before source, and dest == source. Change-Id: Ibeaca04e0028410fd44ce82f72e60058d6230a03
2021-12-03gdb: make value_subscripted_rvalue staticAndrew Burgess1-2/+8
The function value_subscripted_rvalue is only used in valarith.c, so lets make it a static function. There should be no user visible change after this commit.
2021-10-25gdb: change functions returning value contents to use gdb::array_viewSimon Marchi1-35/+36
The bug fixed by this [1] patch was caused by an out-of-bounds access to a value's content. The code gets the value's content (just a pointer) and then indexes it with a non-sensical index. This made me think of changing functions that return value contents to return array_views instead of a plain pointer. This has the advantage that when GDB is built with _GLIBCXX_DEBUG, accesses to the array_view are checked, making bugs more apparent / easier to find. This patch changes the return types of these functions, and updates callers to call .data() on the result, meaning it's not changing anything in practice. Additional work will be needed (which can be done little by little) to make callers propagate the use of array_view and reap the benefits. [1] https://sourceware.org/pipermail/gdb-patches/2021-September/182306.html Change-Id: I5151f888f169e1c36abe2cbc57620110673816f3
2021-09-24Move value_true to value.hTom Tromey1-2/+2
I noticed that value_true is declared in language.h and defined in language.c. However, as part of the value API, I think it would be better in one of those files. And, because it is very short, I changed it to be an inline function in value.h. I've also removed a comment from the implementation, on the basis that it seems obsolete -- if the change it suggests was needed, it probably would have been done by now; and if it is needed in the future, odds are it would be done differently anyway. Finally, this patch also changes value_true and value_logical_not to return a bool, and updates some uses.
2021-06-25gdb: use gdb::optional instead of passing a pointer to gdb::array_viewAndrew Burgess1-1/+1
Following on from the previous commit, this commit changes the API of value_struct_elt to take gdb::optional<gdb::array_view<value *>> instead of a pointer to the gdb::array_view. This makes the optional nature of the array_view parameter explicit. This commit is purely a refactoring commit, there should be no user visible change after this commit. I have deliberately kept this refactor separate from the previous two commits as this is a more extensive change, and I'm not 100% sure that using gdb::optional for the parameter type, instead of a pointer, is going to be to everyone's taste. If there's push back on this patch then this one can be dropped from the series. gdb/ChangeLog: * ada-lang.c (desc_bounds): Use '{}' instead of NULL to indicate an empty gdb::optional when calling value_struct_elt. (desc_data): Likewise. (desc_one_bound): Likewise. * eval.c (structop_base_operation::evaluate_funcall): Pass gdb::array_view, not a gdb::array_view* to value_struct_elt. (eval_op_structop_struct): Use '{}' instead of NULL to indicate an empty gdb::optional when calling value_struct_elt. (eval_op_structop_ptr): Likewise. * f-lang.c (fortran_structop_operation::evaluate): Likewise. * guile/scm-value.c (gdbscm_value_field): Likewise. * m2-lang.c (eval_op_m2_high): Likewise. (eval_op_m2_subscript): Likewise. * opencl-lang.c (opencl_structop_operation::evaluate): Likewise. * python/py-value.c (valpy_getitem): Likewise. * rust-lang.c (rust_val_print_str): Likewise. (rust_range): Likewise. (rust_subscript): Likewise. (eval_op_rust_structop): Likewise. (rust_aggregate_operation::evaluate): Likewise. * valarith.c (value_user_defined_op): Likewise. * valops.c (search_struct_method): Change parameter type, update function body accordingly, and update header comment. (value_struct_elt): Change parameter type, update function body accordingly. * value.h (value_struct_elt): Update declaration.
2021-06-25gdb: replace NULL terminated array with array_viewAndrew Burgess1-1/+1
After the previous commit, this commit updates the value_struct_elt function to take an array_view rather than a NULL terminated array of values. The requirement for a NULL terminated array of values actually stems from typecmp, so the change from an array to array_view needs to be propagated through to this function. While making this change I noticed that this fixes another bug, in value_x_binop and value_x_unop GDB creates an array of values which doesn't have a NULL at the end. An array_view of this array is passed to value_user_defined_op, which then unpacks the array_view and passed the raw array to value_struct_elt, but only if the language is not C++. As value_x_binop and value_x_unop can only request member functions with the names of C++ operators, then most of the time, assuming the inferior is not a C++ program, then GDB will not find a matching member function with the call to value_struct_elt, and so typecmp will never be called, and so, GDB will avoid undefined behaviour. However, it is worth remembering that, when GDB's language is set to "auto", the current language is selected based on the language of the current compilation unit. As C++ programs usually link against libc, which is written in C, then, if the inferior is stopped in libc GDB will set the language to C. And so, it is possible that we will end up using value_struct_elt to try and lookup, and match, a C++ operator. If this occurs then GDB will experience undefined behaviour. I have extended the test added in the previous commit to also cover this case. Finally, this commit changes the API from passing around a pointer to an array to passing around a pointer to an array_view. The reason for this is that we need to be able to distinguish between the cases where we call value_struct_elt with no arguments, i.e. we are looking up a struct member, but we either don't have the arguments we want to pass yet, or we don't expect there to be any need for GDB to use the argument types to resolve any overloading; and the second case where we call value_struct_elt looking for a function that takes no arguments, that is, the argument list is empty. NOTE: While writing this I realise that if we pass an array_view at all then it will always have at least one item in it, the `this' pointer for the object we are planning to call the method on. So we could, I guess, pass an empty array_view to indicate the case where we don't know anything about the arguments, and when the array_view is length 1 or more, it means we do have the arguments. However, though we could do this, I don't think this would be better, the length 0 vs length 1 difference seems a little too subtle, I think that there's a better solution... I think a better solution would be to wrap the array_view in a gdb::optional, this would make the whole, do we have an array view or not question explicit. I haven't done this as part of this commit as making that change is much more extensive, every user of value_struct_elt will need to be updated, and as this commit already contains a bug fix, I wanted to keep the large refactoring in a separate commit, so, check out the next commit for the use of gdb::optional. gdb/ChangeLog: PR gdb/27994 * eval.c (structop_base_operation::evaluate_funcall): Pass array_view instead of array to value_struct_elt. * valarith.c (value_user_defined_op): Likewise. * valops.c (typecmp): Change parameter type from array pointer to array_view. Update header comment, and update body accordingly. (search_struct_method): Likewise. (value_struct_elt): Likewise. * value.h (value_struct_elt): Update declaration. gdb/testsuite/ChangeLog: PR gdb/27994 * gdb.cp/method-call-in-c.cc (struct foo_type): Add operator+=, change initial value of var member variable. (main): Make use of foo_type's operator+=. * gdb.cp/method-call-in-c.exp: Test use of operator+=.
2021-02-05[gdb/exp] Fix assert when adding ptr to imaginary unitTom de Vries1-0/+3
I'm running into this assertion failure: ... $ gdb -batch -ex "p (void *)0 - 5i" gdbtypes.c:3430: internal-error: \ type* init_complex_type(const char*, type*): Assertion \ `target_type->code () == TYPE_CODE_INT \ || target_type->code () == TYPE_CODE_FLT' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ... This is a regression since commit c34e8714662 "Implement complex arithmetic". Before that commit we had: ... (gdb) p (void *)0 - 5i Argument to arithmetic operation not a number or boolean. ... Fix this in complex_binop by throwing an error, such that we have: ... (gdb) print (void *)0 - 5i Argument to complex arithmetic operation not supported. ... Tested on x86_64-linux. gdb/ChangeLog: 2021-02-05 Tom de Vries <tdevries@suse.de> PR exp/27265 * valarith.c (complex_binop): Throw an error if complex type can't be created. gdb/testsuite/ChangeLog: 2021-02-05 Tom de Vries <tdevries@suse.de> PR exp/27265 * gdb.base/complex-parts.exp: Add tests.
2021-01-28gdb: rename get_type_arch to type::archSimon Marchi1-4/+4
... and update all users. gdb/ChangeLog: * gdbtypes.h (get_type_arch): Rename to... (struct type) <arch>: ... this, update all users. Change-Id: I0e3ef938a0afe798ac0da74a9976bbd1d082fc6f
2021-01-06Fix fixed-point binary operation type handlingTom Tromey1-16/+30
Testing showed that gdb was not correctly handling some fixed-point binary operations correctly. Addition and subtraction worked by casting the result to the type of left hand operand. So, "fixed+int" had a different type -- and different value -- from "int+fixed". Furthermore, for multiplication and division, it does not make sense to first cast both sides to the fixed-point type. For example, this can prevent "f * 1" from yielding "f", if 1 is not in the domain of "f". Instead, this patch changes gdb to use the value. (This is somewhat different from Ada semantics, as those can yield a "universal fixed point".) This includes a new test case. It is only run in "minimal" mode, as the old-style fixed point works differently, and is obsolete, so I have no plans to change it. gdb/ChangeLog 2021-01-06 Tom Tromey <tromey@adacore.com> * ada-lang.c (ada_evaluate_subexp) <BINOP_ADD, BINOP_SUB>: Do not cast result. * valarith.c (fixed_point_binop): Handle multiplication and division specially. * valops.c (value_to_gdb_mpq): New function. (value_cast_to_fixed_point): Use it. gdb/testsuite/ChangeLog 2021-01-06 Tom Tromey <tromey@adacore.com> * gdb.ada/fixed_points/pck.ads (Delta4): New constant. (FP4_Type): New type. (FP4_Var): New variable. * gdb.ada/fixed_points/fixed_points.adb: Update. * gdb.ada/fixed_points.exp: Add tests for binary operators.
2021-01-01Update copyright year range in all GDB filesJoel Brobecker1-1/+1
This commits the result of running gdb/copyright.py as per our Start of New Year procedure... gdb/ChangeLog Update copyright year range in copyright header of all GDB files.
2020-12-14Handle fixed-point division by zeroTom Tromey1-0/+2
fixed_point_binop did not account for division by zero. This would lead to gdb getting SIGFPE and subsequently cause some test cases to hang. gdb/ChangeLog 2020-12-14 Tom Tromey <tromey@adacore.com> * valarith.c (fixed_point_binop): Call error on division by zero. gdb/testsuite/ChangeLog 2020-12-14 Tom Tromey <tromey@adacore.com> * gdb.dwarf2/dw2-fixed-point.exp: Add test for division by zero.
2020-12-09gdb: fix value_subscript when array upper bound is not knownSimon Marchi1-7/+15
Since commit 7c6f27129631 ("gdb: make get_discrete_bounds check for non-constant range bounds"), subscripting flexible array member fails: struct no_size { int n; int items[]; }; (gdb) p *ns $1 = {n = 3, items = 0x5555555592a4} (gdb) p ns->items[0] Cannot access memory at address 0xfffe555b733a0164 (gdb) p *((int *) 0x5555555592a4) $2 = 101 <--- we would expect that (gdb) p &ns->items[0] $3 = (int *) 0xfffe5559ee829a24 <--- wrong address Since the flexible array member (items) has an unspecified size, the array type created for it in the DWARF doesn't have dimensions (this is with gcc 9.3.0, Ubuntu 20.04): 0x000000a4: DW_TAG_array_type DW_AT_type [DW_FORM_ref4] (0x00000038 "int") DW_AT_sibling [DW_FORM_ref4] (0x000000b3) 0x000000ad: DW_TAG_subrange_type DW_AT_type [DW_FORM_ref4] (0x00000031 "long unsigned int") This causes GDB to create a range type (TYPE_CODE_RANGE) with a defined constant low bound (dynamic_prop with kind PROP_CONST) and an undefined high bound (dynamic_prop with kind PROP_UNDEFINED). value_subscript gets both bounds of that range using get_discrete_bounds. Before commit 7c6f27129631, get_discrete_bounds didn't check the kind of the dynamic_props and would just blindly read them as if they were PROP_CONST. It would return 0 for the high bound, because we zero-initialize the range_bounds structure. And it didn't really matter in this case, because the returned high bound wasn't used in the end. Commit 7c6f27129631 changed get_discrete_bounds to return a failure if either the low or high bound is not a constant, to make sure we don't read a dynamic prop that isn't a PROP_CONST as a PROP_CONST. This change made get_discrete_bounds start to return a failure for that range, and as a result would not set *lowp and *highp. And since value_subscript doesn't check get_discrete_bounds' return value, it just carries on an uses an uninitialized value for the low bound. If value_subscript did check the return value of get_discrete_bounds, we would get an error message instead of a bogus value. But it would still be a bug, as we wouldn't be able to print the flexible array member's elements. Looking at value_subscript, we see that the low bound is always needed, but the high bound is only needed if !c_style. So, change value_subscript to use get_discrete_low_bound and get_discrete_high_bound separately. This fixes the case described above, where the low bound is known but the high bound isn't (and is not needed). This restores the original behavior without accessing a dynamic_prop in a wrong way. A test is added. In addition to the case described above, a case with an array member of size 0 is added, which is a GNU C extension that existed before flexible array members were introduced. That case currently fails when compiled with gcc <= 8. gcc <= 8 produces DWARF similar to the one shown above, while gcc 9 adds a DW_AT_count of 0 in there, which makes the high bound known. A case where an array member of size 0 is the only member of the struct is also added, as that was how PR 28675 was originally reported, and it's an interesting corner case that I think could trigger other funny bugs. Question about the implementation: in value_subscript, I made it such that if the low or high bound is unknown, we fall back to zero. That effectively makes it the same as it was before 7c6f27129631. But should we instead error() out? gdb/ChangeLog: PR 26875, PR 26901 * gdbtypes.c (get_discrete_low_bound): Make non-static. (get_discrete_high_bound): Make non-static. * gdbtypes.h (get_discrete_low_bound): New declaration. (get_discrete_high_bound): New declaration. * valarith.c (value_subscript): Only fetch high bound if necessary. gdb/testsuite/ChangeLog: PR 26875, PR 26901 * gdb.base/flexible-array-member.c: New test. * gdb.base/flexible-array-member.exp: New test. Change-Id: I832056f80e6c56f621f398b4780d55a3a1e299d7
2020-12-09gdb: make get_discrete_bounds return boolSimon Marchi1-1/+1
get_discrete_bounds currently has three possible return values (see its current doc for details). It appears that for all callers, it would be sufficient to have a boolean "worked" / "didn't work" return value. Change the return type of get_discrete_bounds to bool and adjust all callers. Doing so simplifies the following patch. gdb/ChangeLog: * gdbtypes.h (get_discrete_bounds): Return bool, adjust all callers. * gdbtypes.c (get_discrete_bounds): Return bool. Change-Id: Ie51feee23c75f0cd7939742604282d745db59172
2020-11-23valarith.c: Replace INIT_VAL_WITH_FIXED_POINT_VAL macro by lambdaJoel Brobecker1-15/+19
gdb/ChangeLog (Simon Marchi <simark@simark.ca>): * valarith.c (fixed_point_binop): Replace the INIT_VAL_WITH_FIXED_POINT_VAL macro by a lambda. Update all users accordingly.
2020-11-23Make function fixed_point_scaling_factor a method of struct typeJoel Brobecker1-3/+3
This logically connects this function to the object it inspects. gdb/ChangeLog: * gdbtypes.h (struct type) <fixed_point_scaling_factor>: New method, replacing fixed_point_scaling_factor. All callers updated throughout this project. (fixed_point_scaling_factor): Delete declaration. * gdbtypes.c (type::fixed_point_scaling_factor): Replaces fixed_point_scaling_factor. Adjust implementation accordingly.
2020-11-23gmp-utils: Convert the read/write methods to using gdb::array_viewJoel Brobecker1-3/+6
This commit changes the interfaces of some of the methods declared in gmp-utils to take a gdb::array_view of gdb_byte instead of a (gdb_byte *, size) couple. This makes these methods' API probably more C++-idiomatic. * gmp-utils.h (gdb_mpz::read): Change buf and len parameters into one single gdb::array_view parameter. (gdb_mpz::write): Likewise. (gdb_mpq::read_fixed_point, gdb_mpq::write_fixed_point): Likewise. * gmp-utils.c (gdb_mpz::read): Change buf and len parameters into one single gdb::array_view parameter. Adjust implementation accordingly. (gdb_mpz::write): Likewise. (gdb_mpq::read_fixed_point, gdb_mpq::write_fixed_point): Likewise. * unittests/gmp-utils-selftests.c: Adapt following changes above. * valarith.c, valops.c, valprint.c, value.c: Likewise.
2020-11-15Add support for fixed-point type comparison operatorsJoel Brobecker1-1/+14
This patch adds support for binary comparison operators with fixed-point type values. gdb/ChangeLog: * valarith.c (fixed_point_binop): Add BINOP_EQUAL and BINOP_LESS handling. (value_less): Add fixed-point handling. gdb/testsuite/ChangeLog: * gdb.ada/fixed_cmp.exp: Add -fgnat-encodings=minimal testing. * gdb.dwarf2/dw2-fixed-point.c (pck__fp1_var2): New global. (main): Add reference to pck__fp1_var2. * gdb.dwarf2/dw2-fixed-point.exp: Add comparison operator testing.
2020-11-15Add support for fixed-point type arithmeticJoel Brobecker1-2/+89
This patch adds support for binary operations on fixed-point values, as well as for the negative unary operator. gdb/ChangeLog: * eval.c (binop_promote): Add fixed-point type handling. * valarith.c (fixed_point_binop): New function. (scalar_binop): Add fixed-point type handling. (value_neg): Add fixed-point type handling. * valops.c (value_cast_to_fixed_point): New function. (value_cast): Add fixed-point type handling. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-fixed-point.exp: Add arithmetic tests.