mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-15 08:10:28 +08:00
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:
parent
50668cf626
commit
9044951e0d
@ -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.
|
||||
|
37
gcc/testsuite/g++.dg/tree-ssa/pr20458.C
Normal file
37
gcc/testsuite/g++.dg/tree-ssa/pr20458.C
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user