re PR tree-optimization/20458 (structure aliasing causes wrong code)

2005-03-14  Daniel Berlin <dberlin@dberlin.org>

	Fix PR tree-optimization/20458

	* tree-flow-inline.h (mark_call_clobbered): Don't fiddle
	DECL_EXTERNAL on STRUCT_FIELD tags.
	(clear_call_clobbered): Ditto.
	* tree-ssa-operands.c (note_addressable): Make sure the original
	variable doesn't slip into the addressable list if we have
	subvars.
	* tree-tailcall.c (suitable_for_tail_opt_p): Look at STRUCT_FIELD
	tags too.

From-SVN: r96462
This commit is contained in:
Daniel Berlin 2005-03-15 01:26:35 +00:00 committed by Daniel Berlin
parent 50668cf626
commit 9044951e0d
5 changed files with 59 additions and 6 deletions

View File

@ -1,3 +1,16 @@
2005-03-14 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/20458
* tree-flow-inline.h (mark_call_clobbered): Don't fiddle
DECL_EXTERNAL on STRUCT_FIELD tags.
(clear_call_clobbered): Ditto.
* tree-ssa-operands.c (note_addressable): Make sure the original
variable doesn't slip into the addressable list if we have
subvars.
* tree-tailcall.c (suitable_for_tail_opt_p): Look at STRUCT_FIELD
tags too.
2005-03-14 Geoffrey Keating <geoffk@apple.com>
* doc/cppopts.texi (-fexec-charset): Add concept index entry.

View File

@ -0,0 +1,37 @@
/* { dg-do run } */
/* { dg-options "-O2" } */
/* The tail call optimization would inapproriately tail call the
destructors due to not recognizing a call clobbered variable */
namespace std
{
class locale
{
public:
locale();
~locale();
};
}
struct B
{
std::locale _M_buf_locale;
virtual ~B() {}
};
struct C : public B
{
char *s;
};
void foo ()
{
C c;
}
int main()
{
foo ();
return 0;
}

View File

@ -619,7 +619,7 @@ mark_call_clobbered (tree var)
variable. This is because the pointer that VAR represents has
been found to point to either an arbitrary location or to a known
location in global memory. */
if (ann->mem_tag_kind != NOT_A_TAG)
if (ann->mem_tag_kind != NOT_A_TAG && ann->mem_tag_kind != STRUCT_FIELD)
DECL_EXTERNAL (var) = 1;
bitmap_set_bit (call_clobbered_vars, ann->uid);
ssa_call_clobbered_cache_valid = false;
@ -631,7 +631,7 @@ static inline void
clear_call_clobbered (tree var)
{
var_ann_t ann = var_ann (var);
if (ann->mem_tag_kind != NOT_A_TAG)
if (ann->mem_tag_kind != NOT_A_TAG && ann->mem_tag_kind != STRUCT_FIELD)
DECL_EXTERNAL (var) = 0;
bitmap_clear_bit (call_clobbered_vars, ann->uid);
ssa_call_clobbered_cache_valid = false;

View File

@ -1729,7 +1729,7 @@ note_addressable (tree var, stmt_ann_t s_ann)
if (s_ann->addresses_taken == NULL)
s_ann->addresses_taken = BITMAP_GGC_ALLOC ();
bitmap_set_bit (s_ann->addresses_taken, var_ann (var)->uid);
if (var_can_have_subvars (var)
&& (svars = get_subvars_for_var (var)))
{
@ -1737,6 +1737,8 @@ note_addressable (tree var, stmt_ann_t s_ann)
for (sv = svars; sv; sv = sv->next)
bitmap_set_bit (s_ann->addresses_taken, var_ann (sv->var)->uid);
}
else
bitmap_set_bit (s_ann->addresses_taken, var_ann (var)->uid);
}
}

View File

@ -137,14 +137,15 @@ suitable_for_tail_opt_p (void)
if (current_function_stdarg)
return false;
/* No local variable should be call-clobbered. We ignore any kind
of memory tag, as these are not real variables. */
/* No local variable nor structure field should be call-clobbered. We
ignore any kind of memory tag, as these are not real variables. */
for (i = 0; i < (int) VARRAY_ACTIVE_SIZE (referenced_vars); i++)
{
tree var = VARRAY_TREE (referenced_vars, i);
if (!(TREE_STATIC (var) || DECL_EXTERNAL (var))
&& var_ann (var)->mem_tag_kind == NOT_A_TAG
&& (var_ann (var)->mem_tag_kind == NOT_A_TAG
|| var_ann (var)->mem_tag_kind == STRUCT_FIELD)
&& is_call_clobbered (var))
return false;
}