OSDN Git Service

2008-09-09 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Sep 2008 11:26:45 +0000 (11:26 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Sep 2008 11:26:45 +0000 (11:26 +0000)
PR middle-end/37354
PR middle-end/30165
* gimplify.c (gimplify_conversion): Change conversions of
non-register type to VIEW_CONVERT_EXPRs.
(gimplify_addr_expr): If we need to make the operand
addressable make sure to use a properly initialized
temporary for that so it gets a valid gimple store.

* g++.dg/torture/pr37354.C: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140145 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr37354.C [new file with mode: 0644]

index d5d0719..bccdea9 100644 (file)
@@ -1,3 +1,13 @@
+2008-09-09  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/37354
+       PR middle-end/30165
+       * gimplify.c (gimplify_conversion): Change conversions of
+       non-register type to VIEW_CONVERT_EXPRs.
+       (gimplify_addr_expr): If we need to make the operand
+       addressable make sure to use a properly initialized
+       temporary for that so it gets a valid gimple store.
+
 2008-09-09  Aldy Hernandez  <aldyh@redhat.com>
 
        * function.h (struct function): Add function_start_locus.
index c1f5744..55c5fb2 100644 (file)
@@ -1872,6 +1872,12 @@ gimplify_conversion (tree *expr_p)
        canonicalize_addr_expr (expr_p);
     }
 
+  /* If we have a conversion to a non-register type force the
+     use of a VIEW_CONVERT_EXPR instead.  */
+  if (!is_gimple_reg_type (TREE_TYPE (*expr_p)))
+    *expr_p = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
+                          TREE_OPERAND (*expr_p, 0));
+
   return GS_OK;
 }
 
@@ -4555,20 +4561,31 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       /* Mark the RHS addressable.  */
       ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
                           is_gimple_addressable, fb_either);
-      if (ret != GS_ERROR)
-       {
-         op0 = TREE_OPERAND (expr, 0);
+      if (ret == GS_ERROR)
+       break;
 
-         /* For various reasons, the gimplification of the expression
-            may have made a new INDIRECT_REF.  */
-         if (TREE_CODE (op0) == INDIRECT_REF)
-           goto do_indirect_ref;
+      /* We cannot rely on making the RHS addressable if it is
+        a temporary created by gimplification.  In this case create a
+        new temporary that is initialized by a copy (which will
+        become a store after we mark it addressable).
+        This mostly happens if the frontend passed us something that
+        it could not mark addressable yet, like a fortran
+        pass-by-reference parameter (int) floatvar.  */
+      if (is_gimple_formal_tmp_var (TREE_OPERAND (expr, 0)))
+       TREE_OPERAND (expr, 0)
+         = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p);
 
-         /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
-         recompute_tree_invariant_for_addr_expr (expr);
+      op0 = TREE_OPERAND (expr, 0);
 
-         mark_addressable (TREE_OPERAND (expr, 0));
-       }
+      /* For various reasons, the gimplification of the expression
+        may have made a new INDIRECT_REF.  */
+      if (TREE_CODE (op0) == INDIRECT_REF)
+       goto do_indirect_ref;
+
+      /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
+      recompute_tree_invariant_for_addr_expr (expr);
+
+      mark_addressable (TREE_OPERAND (expr, 0));
       break;
     }
 
index 2d18227..5393493 100644 (file)
@@ -1,3 +1,9 @@
+2008-09-09  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/37354
+       PR middle-end/30165
+       * g++.dg/torture/pr37354.C: New testcase.
+
 2008-09-09  Aldy Hernandez  <aldyh@redhat.com>
 
        * gcc.dg/always_inline.c: Place error message on function
diff --git a/gcc/testsuite/g++.dg/torture/pr37354.C b/gcc/testsuite/g++.dg/torture/pr37354.C
new file mode 100644 (file)
index 0000000..acdf291
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+class GenericClass;
+struct AlsaDriver
+{
+  virtual int _read (unsigned nframes);
+};
+typedef void (GenericClass::*GenericMemFuncType) ();
+GenericMemFuncType m_pFunction;
+void AlsaDriver1 ()
+{
+  m_pFunction = reinterpret_cast < GenericMemFuncType > (&AlsaDriver::_read);
+}
+