]> gcc.gnu.org Git - gcc.git/commitdiff
re PR tree-optimization/20458 (structure aliasing causes wrong code)
authorDaniel Berlin <dberlin@dberlin.org>
Tue, 15 Mar 2005 01:26:35 +0000 (01:26 +0000)
committerDaniel Berlin <dberlin@gcc.gnu.org>
Tue, 15 Mar 2005 01:26:35 +0000 (01:26 +0000)
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

gcc/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr20458.C [new file with mode: 0644]
gcc/tree-flow-inline.h
gcc/tree-ssa-operands.c
gcc/tree-tailcall.c

index 13e2a83a1e81bfddec68b61a479b6e530379d762..010a9ad003b871143fd5cef1049d3f10643ef15a 100644 (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.
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr20458.C b/gcc/testsuite/g++.dg/tree-ssa/pr20458.C
new file mode 100644 (file)
index 0000000..d4e7d1a
--- /dev/null
@@ -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;
+}
+
index 7701e5cc7fd3c5eac327bc3d8672fa9da916609c..2d29eb2ff13b93221be6ee75db36538bcc8f543c 100644 (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;
index 2a63d0874a67322c81382070a8376c5386c980b5..a3b44e22ea3b47dcf3fb7a97d37d10908d637bd4 100644 (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);
     }
 }
 
index 8f4778da0b3607c1b3d74131ae9e6338edad192d..3c2036cdeac01deb93cb19adbada6fa0da4d762e 100644 (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;
     }
This page took 0.099843 seconds and 5 git commands to generate.