Fix PR middle-end/19286 Fix PR debug/19267

2005-01-05  Daniel Berlin  <dberlin@dberlin.org>

	Fix PR middle-end/19286
	Fix PR debug/19267
	* dwarf2out.c (gen_subprogram_die): If we've already tried to
	output this subprogram, simply ignore this attempt to do it again.
	(add_abstract_origin_attribute): Don't abort trying to add the abstract
	origin attribute if it's not possible.
	(gen_block_die): Don't ignore subblocks of "unused" blocks.
	(decls_for_scope): Ditto.
	* gimple-low.c (mark_blocks_with_used_subblocks): Remove.
	(mark_used_blocks): Don't call mark_blocks_with_used_subblocks.

From-SVN: r92991
This commit is contained in:
Daniel Berlin 2005-01-06 14:49:34 +00:00 committed by Daniel Berlin
parent 56ffd9b3ba
commit 9acf766fe1
4 changed files with 58 additions and 65 deletions

View File

@ -1,3 +1,16 @@
2005-01-05 Daniel Berlin <dberlin@dberlin.org>
Fix PR middle-end/19286
Fix PR debug/19267
* dwarf2out.c (gen_subprogram_die): If we've already tried to
output this subprogram, simply ignore this attempt to do it again.
(add_abstract_origin_attribute): Don't abort trying to add the abstract
origin attribute if it's not possible.
(gen_block_die): Don't ignore subblocks of "unused" blocks.
(decls_for_scope): Ditto.
* gimple-low.c (mark_blocks_with_used_subblocks): Remove.
(mark_used_blocks): Don't call mark_blocks_with_used_subblocks.
2005-01-05 Richard Henderson <rth@redhat.com>
PR target/11327

View File

@ -10462,9 +10462,17 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin)
else if (TYPE_P (origin))
origin_die = lookup_type_die (origin);
gcc_assert (origin_die);
/* XXX: Functions that are never lowered don't always have correct block
trees (in the case of java, they simply have no block tree, in some other
languages). For these functions, there is nothing we can really do to
output correct debug info for inlined functions in all cases. Rather
than abort, we'll just produce deficient debug info now, in that we will
have variables without a proper abstract origin. In the future, when all
functions are lowered, we should re-add a gcc_assert (origin_die)
here. */
add_AT_die_ref (die, DW_AT_abstract_origin, origin_die);
if (origin_die)
add_AT_die_ref (die, DW_AT_abstract_origin, origin_die);
}
/* We do not currently support the pure_virtual attribute. */
@ -11199,12 +11207,8 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
It seems reasonable to use AT_specification in this case. */
&& !get_AT (old_die, DW_AT_inline))
{
/* ??? This can happen if there is a bug in the program, for
instance, if it has duplicate function definitions. Ideally,
we should detect this case and ignore it. For now, if we have
already reported an error, any error at all, then assume that
we got here because of an input error, not a dwarf2 bug. */
gcc_assert (errorcount);
/* Detect and ignore this case, where we are trying to output
something we have already output. */
return;
}
@ -12234,9 +12238,8 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
tree decl;
enum tree_code origin_code;
/* Ignore blocks never really used to make RTL. */
if (stmt == NULL_TREE || !TREE_USED (stmt)
|| (!TREE_ASM_WRITTEN (stmt) && !BLOCK_ABSTRACT (stmt)))
/* Ignore blocks that are NULL. */
if (stmt == NULL_TREE)
return;
/* If the block is one fragment of a non-contiguous block, do not
@ -12282,7 +12285,10 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
if (debug_info_level > DINFO_LEVEL_TERSE)
/* We are not in terse mode so *any* local declaration counts
as being a "significant" one. */
must_output_die = (BLOCK_VARS (stmt) != NULL);
must_output_die = (BLOCK_VARS (stmt) != NULL
&& (TREE_USED (stmt)
|| TREE_ASM_WRITTEN (stmt)
|| BLOCK_ABSTRACT (stmt)));
else
/* We are in terse mode, so only local (nested) function
definitions count as "significant" local declarations. */
@ -12324,29 +12330,32 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
tree decl;
tree subblocks;
/* Ignore blocks never really used to make RTL. */
if (stmt == NULL_TREE || ! TREE_USED (stmt))
/* Ignore NULL blocks. */
if (stmt == NULL_TREE)
return;
/* Output the DIEs to represent all of the data objects and typedefs
declared directly within this block but not within any nested
sub-blocks. Also, nested function and tag DIEs have been
generated with a parent of NULL; fix that up now. */
for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
if (TREE_USED (stmt))
{
dw_die_ref die;
if (TREE_CODE (decl) == FUNCTION_DECL)
die = lookup_decl_die (decl);
else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
die = lookup_type_die (TREE_TYPE (decl));
else
die = NULL;
if (die != NULL && die->die_parent == NULL)
add_child_die (context_die, die);
else
gen_decl_die (decl, context_die);
/* Output the DIEs to represent all of the data objects and typedefs
declared directly within this block but not within any nested
sub-blocks. Also, nested function and tag DIEs have been
generated with a parent of NULL; fix that up now. */
for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
{
dw_die_ref die;
if (TREE_CODE (decl) == FUNCTION_DECL)
die = lookup_decl_die (decl);
else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
die = lookup_type_die (TREE_TYPE (decl));
else
die = NULL;
if (die != NULL && die->die_parent == NULL)
add_child_die (context_die, die);
else
gen_decl_die (decl, context_die);
}
}
/* If we're at -g1, we're not interested in subblocks. */

View File

@ -541,7 +541,7 @@ struct tree_opt_pass pass_remove_useless_vars =
0 /* letter */
};
/* Mark BLOCK used if it has a used variable in it, then recurse over it's
/* Mark BLOCK used if it has a used variable in it, then recurse over its
subblocks. */
static void
@ -569,42 +569,12 @@ mark_blocks_with_used_vars (tree block)
mark_blocks_with_used_vars (subblock);
}
/* Mark BLOCK used if any of it's subblocks have the USED bit set, or it's
abstract origin is used. */
static bool
mark_blocks_with_used_subblocks (tree block)
{
tree subblock;
/* The block may have no variables, but still be used, if it's abstract
origin is used. This occurs when we inline functions with no parameters
that call functions with no parameters or local vars (such as
dwarf2/dwarf-die7.c). You end up with a block that has an abstract
origin, no variables, and nothing in the subblocks is used. However, the
block is really used, because it's abstract origin was used. */
if (BLOCK_ABSTRACT_ORIGIN (block))
{
if (TREE_USED (BLOCK_ABSTRACT_ORIGIN (block)))
TREE_USED (block) = true;
}
for (subblock = BLOCK_SUBBLOCKS (block);
subblock;
subblock = BLOCK_CHAIN (subblock))
TREE_USED (block) |= mark_blocks_with_used_subblocks (subblock);
return TREE_USED (block);
}
/* Mark the used attribute on blocks correctly. */
static void
mark_used_blocks (void)
{
{
mark_blocks_with_used_vars (DECL_INITIAL (current_function_decl));
mark_blocks_with_used_subblocks (DECL_INITIAL (current_function_decl));
}

View File

@ -966,7 +966,8 @@ extern void tree_operand_check_failed (int, enum tree_code,
/* Nonzero in a _DECL if the name is used in its scope.
Nonzero in an expr node means inhibit warning if value is unused.
In IDENTIFIER_NODEs, this means that some extern decl for this name
was used. */
was used.
In a BLOCK, this means that the block contains variables that are used. */
#define TREE_USED(NODE) ((NODE)->common.used_flag)
/* In a FUNCTION_DECL, nonzero means a call to the function cannot throw