mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-20 08:10:28 +08:00
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:
parent
56ffd9b3ba
commit
9acf766fe1
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user