mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-12 12:16:04 +08:00
424da6cf3b
Consider the following function, which takes no parameter and returns an integer: function Something return Integer; For the purpose of this discussion, our function has been implemented to always return 124: function Something return Integer is begin return 124; end Something; In Ada, such function can been called without using the parentheses. For instance, in the statement below, variable My_Value is assigned the returned value from the call to Something: My_Value := Something; The Ada expression interpeter in GDB supports this case, as we can see below: (gdb) print something $1 = 124 However, we get fairly strange results when trying to use this feature as part of a larger expression. For instance: (gdb) print something + 1 $2 = 248 The problem occurs while doing the resolution pass of the expression. After prefixying the expression, we obtain the following expression: 0 BINOP_ADD 1 OP_VAR_VALUE Block @0x2021550, symbol @0x20213a0 (pck.something) 5 OP_LONG Type @0x1e3c170 (int), value 1 (0x1) The resolution pass is then expected to remove the OP_VAR_VALUE entry, and replace it with an OP_FUNCALL. This is what the call to replace_operator_with_call in ada-lang.c::resolve_subexp is expected to do: if (deprocedure_p && (TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 2].symbol)) == TYPE_CODE_FUNC)) { replace_operator_with_call (expp, pc, 0, 0, exp->elts[pc + 2].symbol, exp->elts[pc + 1].block); exp = expp->get (); } The problem is that we're passing OPLEN (zero -- 4th parameter in the call), and so replace_operator_with_call ends up removing zero element from our expression, and inserting the corresponding OP_FUNCALL instead. As a result, instead of having the OP_LONG (1) as the second argument of the BINOP_ADD, it is now the OP_VAR_VALUE that we were meant to replace. That OP_VAR_VALUE then itself gets transformed into an OP_FUNCALL, with the same issue, and eventually, the resolved expression now looks like this: 0 BINOP_ADD 1 OP_FUNCALL Number of args: 0 4 OP_VAR_VALUE Block @0x2021550, symbol @0x20213a0 (pck.something) 8 OP_FUNCALL Number of args: 0 11 OP_VAR_VALUE Block @0x2021550, symbol @0x20213a0 (pck.something) 15 OP_VAR_VALUE Block @0x2021550, symbol @0x20213a0 (pck.something) 19 OP_LONG Type @0x1e3c170 (int), value 1 (0x1) This explains why we get twice the result of the function call instead of its value plus one. The extra entries in the expression at the end are just ignored. This patch fixes the issue by calling replace_operator_with_call with the correct OPLEN equal to the size of an OP_VAR_VALUE (4). gdb/ChangeLog: * ada-lang.c (resolve_subexp): Pass correct OPLEN in call to replace_operator_with_call. gdb/testsuite/ChangeLog: * gdb.ada/expr_with_funcall: New testcase. |
||
---|---|---|
bfd | ||
binutils | ||
config | ||
contrib | ||
cpu | ||
elfcpp | ||
etc | ||
gas | ||
gdb | ||
gold | ||
gprof | ||
include | ||
intl | ||
ld | ||
libdecnumber | ||
libiberty | ||
opcodes | ||
readline | ||
sim | ||
texinfo | ||
zlib | ||
.cvsignore | ||
.gitattributes | ||
.gitignore | ||
ar-lib | ||
ChangeLog | ||
compile | ||
config-ml.in | ||
config.guess | ||
config.rpath | ||
config.sub | ||
configure | ||
configure.ac | ||
COPYING | ||
COPYING3 | ||
COPYING3.LIB | ||
COPYING.LIB | ||
COPYING.LIBGLOSS | ||
COPYING.NEWLIB | ||
depcomp | ||
djunpack.bat | ||
install-sh | ||
libtool.m4 | ||
lt~obsolete.m4 | ||
ltgcc.m4 | ||
ltmain.sh | ||
ltoptions.m4 | ||
ltsugar.m4 | ||
ltversion.m4 | ||
MAINTAINERS | ||
Makefile.def | ||
Makefile.in | ||
Makefile.tpl | ||
makefile.vms | ||
missing | ||
mkdep | ||
mkinstalldirs | ||
move-if-change | ||
README | ||
README-maintainer-mode | ||
setup.com | ||
src-release.sh | ||
symlink-tree | ||
test-driver | ||
ylwrap |
README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, definitions, and documentation. If you are receiving this as part of a GDB release, see the file gdb/README. If with a binutils release, see binutils/README; if with a libg++ release, see libg++/README, etc. That'll give you info about this package -- supported targets, how to use it, how to report bugs, etc. It is now possible to automatically configure and build a variety of tools with one command. To build all of the tools contained herein, run the ``configure'' script here, e.g.: ./configure make To install them (by default in /usr/local/bin, /usr/local/lib, etc), then do: make install (If the configure script can't determine your type of computer, give it the name as an argument, for instance ``./configure sun4''. You can use the script ``config.sub'' to test whether a name is recognized; if it is, config.sub translates it to a triplet specifying CPU, vendor, and OS.) If you have more than one compiler on your system, it is often best to explicitly set CC in the environment before running configure, and to also set CC when running make. For example (assuming sh/bash/ksh): CC=gcc ./configure make A similar example using csh: setenv CC gcc ./configure make Much of the code and documentation enclosed is copyright by the Free Software Foundation, Inc. See the file COPYING or COPYING.LIB in the various directories, for a description of the GNU General Public License terms under which you can copy the files. REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info on where and how to report problems.