aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-02-16 01:05:20 -0500
committerJason Merrill <jason@gcc.gnu.org>2010-02-16 01:05:20 -0500
commit1e2ddf80b6806a33e0043437466f9549e5f5bac2 (patch)
treee3b5c8c4521ed90808f9880d31e72252ba427cbe
parent38e40fcd450c508dbacdd2ddcd40ed1e500c4713 (diff)
downloadgcc-1e2ddf80b6806a33e0043437466f9549e5f5bac2.zip
gcc-1e2ddf80b6806a33e0043437466f9549e5f5bac2.tar.gz
gcc-1e2ddf80b6806a33e0043437466f9549e5f5bac2.tar.bz2
re PR c++/43031 (internal compiler error: verify_gimple failed after non-trivial conversion error when crosscompiling Firefox)
PR c++/43031 * cp-gimplify.c (cp_gimplify_expr) [MODIFY_EXPR]: Use VIEW_CONVERT_EXPR for conversions between structural equality types that the back end can't tell are the same. From-SVN: r156793
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-gimplify.c14
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/ext/attrib36.C20
4 files changed, 42 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8b9bc62..5b433f0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2010-02-16 Jason Merrill <jason@redhat.com>
+ PR c++/43031
+ * cp-gimplify.c (cp_gimplify_expr) [MODIFY_EXPR]: Use
+ VIEW_CONVERT_EXPR for conversions between structural equality types
+ that the back end can't tell are the same.
+
PR c++/43036
* tree.c (build_cplus_array_type): Set TYPE_MAIN_VARIANT to strip
cv-quals from element here.
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index e0047cf..7dc79b2 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -552,6 +552,20 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
25979. */
case INIT_EXPR:
cp_gimplify_init_expr (expr_p, pre_p, post_p);
+ /* Fall through. */
+ case MODIFY_EXPR:
+ {
+ /* If the back end isn't clever enough to know that the lhs and rhs
+ types are the same, add an explicit conversion. */
+ tree op0 = TREE_OPERAND (*expr_p, 0);
+ tree op1 = TREE_OPERAND (*expr_p, 1);
+
+ if ((TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
+ || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
+ && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
+ TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
+ TREE_TYPE (op0), op1);
+ }
ret = GS_OK;
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f361202..891acb1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2010-02-16 Jason Merrill <jason@redhat.com>
+ PR c++/43031
+ * g++.dg/ext/attrib36.C: New.
+
PR c++/43036
* g++.dg/other/array6.C: New.
diff --git a/gcc/testsuite/g++.dg/ext/attrib36.C b/gcc/testsuite/g++.dg/ext/attrib36.C
new file mode 100644
index 0000000..a4ee209
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attrib36.C
@@ -0,0 +1,20 @@
+// PR c++/43031
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+
+class T;
+class L { };
+class P : public L
+{
+ typedef void (__attribute__((__stdcall__)) T::*F) (L*);
+ void f(bool aAdd);
+};
+class T
+{
+public:
+ virtual void __attribute__((__stdcall__)) A(L *listener) = 0;
+ virtual void __attribute__((__stdcall__)) R(L *listener) = 0;
+};
+void P::f(bool aAdd)
+{
+ F addRemoveEventListener = (aAdd ? &T::A : &T::R);
+}