PR gdb/9675:
	* dwarf2read.c (unsigned_int_compar, inherit_abstract_dies): New.
	(read_func_scope): Call inherit_abstract_dies.

gdb/testsuite/
	* gdb.cp/abstract-origin.exp, gdb.cp/abstract-origin.cc: New test.
This commit is contained in:
Jan Kratochvil 2009-04-27 08:36:17 +00:00
parent 8f3e5e92ce
commit d389af10b7
5 changed files with 182 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2009-04-27 Jan Kratochvil <jan.kratochvil@redhat.com>
PR gdb/9675:
* dwarf2read.c (unsigned_int_compar, inherit_abstract_dies): New.
(read_func_scope): Call inherit_abstract_dies.
2009-04-25 Eli Zaretskii <eliz@gnu.org>
* Makefile.in (ALLDEPFILES): Remove duplicate entries for

View File

@ -3089,6 +3089,103 @@ add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc,
cu->last_fn = thisfn;
}
/* qsort helper for inherit_abstract_dies. */
static int
unsigned_int_compar (const void *ap, const void *bp)
{
unsigned int a = *(unsigned int *) ap;
unsigned int b = *(unsigned int *) bp;
return (a > b) - (b > a);
}
/* DW_AT_abstract_origin inherits whole DIEs (not just their attributes).
Inherit only the children of the DW_AT_abstract_origin DIE not being already
referenced by DW_AT_abstract_origin from the children of the current DIE. */
static void
inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
{
struct die_info *child_die;
unsigned die_children_count;
/* CU offsets which were referenced by children of the current DIE. */
unsigned *offsets;
unsigned *offsets_end, *offsetp;
/* Parent of DIE - referenced by DW_AT_abstract_origin. */
struct die_info *origin_die;
/* Iterator of the ORIGIN_DIE children. */
struct die_info *origin_child_die;
struct cleanup *cleanups;
struct attribute *attr;
attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
if (!attr)
return;
origin_die = follow_die_ref (die, attr, &cu);
if (die->tag != origin_die->tag)
complaint (&symfile_complaints,
_("DIE 0x%x and its abstract origin 0x%x have different tags"),
die->offset, origin_die->offset);
child_die = die->child;
die_children_count = 0;
while (child_die && child_die->tag)
{
child_die = sibling_die (child_die);
die_children_count++;
}
offsets = xmalloc (sizeof (*offsets) * die_children_count);
cleanups = make_cleanup (xfree, offsets);
offsets_end = offsets;
child_die = die->child;
while (child_die && child_die->tag)
{
attr = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
/* According to DWARF3 3.3.8.2 #3 new entries without their abstract
counterpart may exist. */
if (attr)
{
struct die_info *child_origin_die;
child_origin_die = follow_die_ref (child_die, attr, &cu);
if (child_die->tag != child_origin_die->tag)
complaint (&symfile_complaints,
_("Child DIE 0x%x and its abstract origin 0x%x have "
"different tags"), child_die->offset,
child_origin_die->offset);
*offsets_end++ = child_origin_die->offset;
}
child_die = sibling_die (child_die);
}
qsort (offsets, offsets_end - offsets, sizeof (*offsets),
unsigned_int_compar);
for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
if (offsetp[-1] == *offsetp)
complaint (&symfile_complaints, _("Multiple children of DIE 0x%x refer "
"to DIE 0x%x as their abstract origin"),
die->offset, *offsetp);
offsetp = offsets;
origin_child_die = origin_die->child;
while (origin_child_die && origin_child_die->tag)
{
/* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */
while (offsetp < offsets_end && *offsetp < origin_child_die->offset)
offsetp++;
if (offsetp >= offsets_end || *offsetp > origin_child_die->offset)
{
/* Found that ORIGIN_CHILD_DIE is really not referenced. */
process_die (origin_child_die, cu);
}
origin_child_die = sibling_die (origin_child_die);
}
do_cleanups (cleanups);
}
static void
read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
{
@ -3147,6 +3244,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
}
}
inherit_abstract_dies (die, cu);
new = pop_context ();
/* Make a block for the local symbols within. */
block = finish_block (new->name, &local_symbols, new->old_blocks,

View File

@ -1,3 +1,7 @@
2009-04-27 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.cp/abstract-origin.exp, gdb.cp/abstract-origin.cc: New test.
2009-04-22 Joseph Myers <joseph@codesourcery.com>
* lib/gdb.exp (get_compiler_info): Use -E -o in remote-host case.

View File

@ -0,0 +1,42 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2009 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 <http://www.gnu.org/licenses/>.
*/
extern void f (int *);
class A
{
public:
A(int i);
};
A::A(int i)
{
static int *problem = new int(i);
f (problem); /* break-here */
}
void f (int *)
{
}
int
main (void)
{
A a(42);
return 0;
}

View File

@ -0,0 +1,31 @@
# Copyright 2009 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 <http://www.gnu.org/licenses/>.
set testfile abstract-origin
set srcfile ${testfile}.cc
if [prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}] {
return -1
}
if ![runto_main] {
untested abstract-origin
return -1
}
gdb_breakpoint [gdb_get_line_number "break-here"]
gdb_continue_to_breakpoint "break-here"
# The Bug was: No symbol "problem" in current context.
gdb_test "p problem" " = \\(int \\*\\) 0x.*"