Commit 9acf766f by Daniel Berlin Committed by Daniel Berlin

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
parent 56ffd9b3
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> 2005-01-05 Richard Henderson <rth@redhat.com>
PR target/11327 PR target/11327
......
...@@ -10462,9 +10462,17 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin) ...@@ -10462,9 +10462,17 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin)
else if (TYPE_P (origin)) else if (TYPE_P (origin))
origin_die = lookup_type_die (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. */ /* We do not currently support the pure_virtual attribute. */
...@@ -11199,12 +11207,8 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) ...@@ -11199,12 +11207,8 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
It seems reasonable to use AT_specification in this case. */ It seems reasonable to use AT_specification in this case. */
&& !get_AT (old_die, DW_AT_inline)) && !get_AT (old_die, DW_AT_inline))
{ {
/* ??? This can happen if there is a bug in the program, for /* Detect and ignore this case, where we are trying to output
instance, if it has duplicate function definitions. Ideally, something we have already output. */
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);
return; return;
} }
...@@ -12234,9 +12238,8 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth) ...@@ -12234,9 +12238,8 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
tree decl; tree decl;
enum tree_code origin_code; enum tree_code origin_code;
/* Ignore blocks never really used to make RTL. */ /* Ignore blocks that are NULL. */
if (stmt == NULL_TREE || !TREE_USED (stmt) if (stmt == NULL_TREE)
|| (!TREE_ASM_WRITTEN (stmt) && !BLOCK_ABSTRACT (stmt)))
return; return;
/* If the block is one fragment of a non-contiguous block, do not /* 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) ...@@ -12282,7 +12285,10 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
if (debug_info_level > DINFO_LEVEL_TERSE) if (debug_info_level > DINFO_LEVEL_TERSE)
/* We are not in terse mode so *any* local declaration counts /* We are not in terse mode so *any* local declaration counts
as being a "significant" one. */ 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 else
/* We are in terse mode, so only local (nested) function /* We are in terse mode, so only local (nested) function
definitions count as "significant" local declarations. */ definitions count as "significant" local declarations. */
...@@ -12324,29 +12330,32 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth) ...@@ -12324,29 +12330,32 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
tree decl; tree decl;
tree subblocks; tree subblocks;
/* Ignore blocks never really used to make RTL. */ /* Ignore NULL blocks. */
if (stmt == NULL_TREE || ! TREE_USED (stmt)) if (stmt == NULL_TREE)
return; return;
/* Output the DIEs to represent all of the data objects and typedefs if (TREE_USED (stmt))
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; /* Output the DIEs to represent all of the data objects and typedefs
declared directly within this block but not within any nested
if (TREE_CODE (decl) == FUNCTION_DECL) sub-blocks. Also, nested function and tag DIEs have been
die = lookup_decl_die (decl); generated with a parent of NULL; fix that up now. */
else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)) for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
die = lookup_type_die (TREE_TYPE (decl)); {
else dw_die_ref die;
die = NULL;
if (TREE_CODE (decl) == FUNCTION_DECL)
if (die != NULL && die->die_parent == NULL) die = lookup_decl_die (decl);
add_child_die (context_die, die); else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
else die = lookup_type_die (TREE_TYPE (decl));
gen_decl_die (decl, context_die); 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. */ /* If we're at -g1, we're not interested in subblocks. */
......
...@@ -541,7 +541,7 @@ struct tree_opt_pass pass_remove_useless_vars = ...@@ -541,7 +541,7 @@ struct tree_opt_pass pass_remove_useless_vars =
0 /* letter */ 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. */ subblocks. */
static void static void
...@@ -569,42 +569,12 @@ mark_blocks_with_used_vars (tree block) ...@@ -569,42 +569,12 @@ mark_blocks_with_used_vars (tree block)
mark_blocks_with_used_vars (subblock); 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. */ /* Mark the used attribute on blocks correctly. */
static void static void
mark_used_blocks (void) mark_used_blocks (void)
{ {
mark_blocks_with_used_vars (DECL_INITIAL (current_function_decl)); 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, ...@@ -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 a _DECL if the name is used in its scope.
Nonzero in an expr node means inhibit warning if value is unused. Nonzero in an expr node means inhibit warning if value is unused.
In IDENTIFIER_NODEs, this means that some extern decl for this name 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) #define TREE_USED(NODE) ((NODE)->common.used_flag)
/* In a FUNCTION_DECL, nonzero means a call to the function cannot throw /* In a FUNCTION_DECL, nonzero means a call to the function cannot throw
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment