re PR c++/43031 (internal compiler error: verify_gimple failed after non-trivial...
authorJason Merrill <jason@redhat.com>
Tue, 16 Feb 2010 06:05:20 +0000 (01:05 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 16 Feb 2010 06:05:20 +0000 (01:05 -0500)
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

gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/attrib36.C [new file with mode: 0644]

index 8b9bc62589ece5f4c77a6d5250ce8ce2dfaf7081..5b433f033c00a9c798a6d9cccedb22b4ea1a4912 100644 (file)
@@ -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.
index e0047cf116908a222c6af16ee9d93802282bcacc..7dc79b2554fc425d27e5e7ca9cdb73702102a87e 100644 (file)
@@ -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;
 
index f361202c2e397ae5bea2fc05e7ed218b1f14a5b5..891acb15c68ebe20449ba4624ce7312f6ef7b1c0 100644 (file)
@@ -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 (file)
index 0000000..a4ee209
--- /dev/null
@@ -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);
+}