]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/59645 (ICE with covariant return and volatile)
authorJason Merrill <jason@redhat.com>
Thu, 30 Jan 2014 14:18:15 +0000 (09:18 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 30 Jan 2014 14:18:15 +0000 (09:18 -0500)
PR c++/59645
* cgraphunit.c (expand_thunk): Copy volatile arg to a temporary.

From-SVN: r207301

gcc/ChangeLog
gcc/cgraphunit.c
gcc/testsuite/g++.dg/inherit/covariant21.C [new file with mode: 0644]

index b908dc08340dfbc1f9c1fb8568b644d2609628aa..e259b5730ed1c6137aafd431b2459ea4410e6213 100644 (file)
@@ -1,3 +1,8 @@
+2014-01-30  Jason Merrill  <jason@redhat.com>
+
+       PR c++/59645
+       * cgraphunit.c (expand_thunk): Copy volatile arg to a temporary.
+
 2014-01-30  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/59951
index d22265a9a3f779b71f0e39e894f4c028c7d3c291..06283fc3f640ea598b17a494c8b935cd0a2aaaee 100644 (file)
@@ -1592,7 +1592,17 @@ expand_thunk (struct cgraph_node *node, bool output_asm_thunks)
 
       if (nargs)
         for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
-         vargs.quick_push (arg);
+         {
+           tree tmp = arg;
+           if (!is_gimple_val (arg))
+             {
+               tmp = create_tmp_reg (TYPE_MAIN_VARIANT
+                                     (TREE_TYPE (arg)), "arg");
+               gimple stmt = gimple_build_assign (tmp, arg);
+               gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
+             }
+           vargs.quick_push (tmp);
+         }
       call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
       node->callees->call_stmt = call;
       gimple_call_set_from_thunk (call, true);
diff --git a/gcc/testsuite/g++.dg/inherit/covariant21.C b/gcc/testsuite/g++.dg/inherit/covariant21.C
new file mode 100644 (file)
index 0000000..42cdf87
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/59645
+
+struct A { virtual ~A(); };
+struct B { virtual ~B(); };
+struct C : A, B {};
+
+struct X
+{
+  virtual B* foo(volatile int);
+};
+
+struct Y : X
+{
+  virtual C* foo(volatile int);
+};
+
+C* Y::foo(volatile int) { return 0; }