forked from Imagelibrary/binutils-gdb
Fix Fortran regression with variables in nested functions
Sergio pointed out that commit commit aa3b6533 ("Allow nested function
displays") regressed a few gdb.fortran tests. I was able to reproduce
these failures with gcc head.
The bug is that some spots calling contained_in will in fact do the
wrong thing if nested functions are considered as contained. In the
particular case of the Fortran regression, it was the call in
block_innermost_frame, being called from get_hosting_frame -- in this
case, the caller is specifically trying to avoid the nested case.
This patch fixes the problem by adding an "allow_nested" parameter to
contained_in, essentially reverting the change for most callers.
gdb/ChangeLog
2019-08-19 Tom Tromey <tromey@adacore.com>
* printcmd.c (do_one_display, info_display_command): Update.
* block.h (contained_in): Return bool. Add allow_nested
parameter.
* block.c (contained_in): Return bool. Add allow_nested
parameter.
This commit is contained in:
@@ -1,3 +1,11 @@
|
|||||||
|
2019-08-19 Tom Tromey <tromey@adacore.com>
|
||||||
|
|
||||||
|
* printcmd.c (do_one_display, info_display_command): Update.
|
||||||
|
* block.h (contained_in): Return bool. Add allow_nested
|
||||||
|
parameter.
|
||||||
|
* block.c (contained_in): Return bool. Add allow_nested
|
||||||
|
parameter.
|
||||||
|
|
||||||
2019-08-19 Tom Tromey <tom@tromey.com>
|
2019-08-19 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* configure: Rebuild.
|
* configure: Rebuild.
|
||||||
|
|||||||
19
gdb/block.c
19
gdb/block.c
@@ -65,25 +65,28 @@ block_gdbarch (const struct block *block)
|
|||||||
return get_objfile_arch (block_objfile (block));
|
return get_objfile_arch (block_objfile (block));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return Nonzero if block a is lexically nested within block b,
|
/* See block.h. */
|
||||||
or if a and b have the same pc range.
|
|
||||||
Return zero otherwise. */
|
|
||||||
|
|
||||||
int
|
bool
|
||||||
contained_in (const struct block *a, const struct block *b)
|
contained_in (const struct block *a, const struct block *b,
|
||||||
|
bool allow_nested)
|
||||||
{
|
{
|
||||||
if (!a || !b)
|
if (!a || !b)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (a == b)
|
if (a == b)
|
||||||
return 1;
|
return true;
|
||||||
|
/* If A is a function block, then A cannot be contained in B,
|
||||||
|
except if A was inlined. */
|
||||||
|
if (!allow_nested && BLOCK_FUNCTION (a) != NULL && !block_inlined_p (a))
|
||||||
|
return false;
|
||||||
a = BLOCK_SUPERBLOCK (a);
|
a = BLOCK_SUPERBLOCK (a);
|
||||||
}
|
}
|
||||||
while (a != NULL);
|
while (a != NULL);
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
10
gdb/block.h
10
gdb/block.h
@@ -219,7 +219,15 @@ extern struct symbol *block_containing_function (const struct block *);
|
|||||||
|
|
||||||
extern int block_inlined_p (const struct block *block);
|
extern int block_inlined_p (const struct block *block);
|
||||||
|
|
||||||
extern int contained_in (const struct block *, const struct block *);
|
/* Return true if block A is lexically nested within block B, or if a
|
||||||
|
and b have the same pc range. Return false otherwise. If
|
||||||
|
ALLOW_NESTED is true, then block A is considered to be in block B
|
||||||
|
if A is in a nested function in B's function. If ALLOW_NESTED is
|
||||||
|
false (the default), then blocks in nested functions are not
|
||||||
|
considered to be contained. */
|
||||||
|
|
||||||
|
extern bool contained_in (const struct block *a, const struct block *b,
|
||||||
|
bool allow_nested = false);
|
||||||
|
|
||||||
extern const struct blockvector *blockvector_for_pc (CORE_ADDR,
|
extern const struct blockvector *blockvector_for_pc (CORE_ADDR,
|
||||||
const struct block **);
|
const struct block **);
|
||||||
|
|||||||
@@ -1936,7 +1936,8 @@ do_one_display (struct display *d)
|
|||||||
if (d->block)
|
if (d->block)
|
||||||
{
|
{
|
||||||
if (d->pspace == current_program_space)
|
if (d->pspace == current_program_space)
|
||||||
within_current_scope = contained_in (get_selected_block (0), d->block);
|
within_current_scope = contained_in (get_selected_block (0), d->block,
|
||||||
|
true);
|
||||||
else
|
else
|
||||||
within_current_scope = 0;
|
within_current_scope = 0;
|
||||||
}
|
}
|
||||||
@@ -2098,7 +2099,7 @@ Num Enb Expression\n"));
|
|||||||
else if (d->format.format)
|
else if (d->format.format)
|
||||||
printf_filtered ("/%c ", d->format.format);
|
printf_filtered ("/%c ", d->format.format);
|
||||||
puts_filtered (d->exp_string);
|
puts_filtered (d->exp_string);
|
||||||
if (d->block && !contained_in (get_selected_block (0), d->block))
|
if (d->block && !contained_in (get_selected_block (0), d->block, true))
|
||||||
printf_filtered (_(" (cannot be evaluated in the current context)"));
|
printf_filtered (_(" (cannot be evaluated in the current context)"));
|
||||||
printf_filtered ("\n");
|
printf_filtered ("\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user