commit 0cbf28df997d109615545f113b01ac233d64879f
Author: Jason Merrill <jason@redhat.com>
Date: Wed Jan 29 20:47:54 2014 -0500
PR c++/59645
* cgraphunit.c (expand_thunk): Copy volatile arg to a temporary.
@@ -1592,7 +1592,18 @@ 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 (TREE_THIS_VOLATILE (TREE_TYPE (arg)))
+ {
+ gcc_assert (is_gimple_reg_type (TREE_TYPE (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);
new file mode 100644
@@ -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; }