summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-09-09 11:26:45 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-09-09 11:26:45 +0000
commit90cf240db95ab4cd3764e7701a7fe79657a3c4dc (patch)
tree343871c9be1bd0b54caffbbb5f379ca0a5dc8833 /gcc
parent30099c0c3b0dd7c5395eb2946e75a16f900f297a (diff)
downloadgcc-90cf240db95ab4cd3764e7701a7fe79657a3c4dc.tar.gz
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. * g++.dg/torture/pr37354.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140145 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/gimplify.c39
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/torture/pr37354.C14
4 files changed, 58 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d5d07197e85..bccdea9ec24 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index c1f5744d7a8..55c5fb25889 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2d1822705e5..5393493a65b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..acdf2911063
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr37354.C
@@ -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);
+}
+