aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 13d6d03..6d2fef5 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -335,14 +335,14 @@ build_base_path (enum tree_code code,
/* In a base member initializer, we cannot rely on
the vtable being set up. We have to use the vtt_parm. */
tree derived = BINFO_INHERITANCE_CHAIN (v_binfo);
-
- v_offset = build (PLUS_EXPR, TREE_TYPE (current_vtt_parm),
- current_vtt_parm, BINFO_VPTR_INDEX (derived));
-
- v_offset = build1 (INDIRECT_REF,
- TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived))),
- v_offset);
-
+ tree t;
+
+ t = TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived)));
+ t = build_pointer_type (t);
+ v_offset = convert (t, current_vtt_parm);
+ v_offset = build (PLUS_EXPR, t, v_offset,
+ BINFO_VPTR_INDEX (derived));
+ v_offset = build_indirect_ref (v_offset, NULL);
}
else
v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
@@ -354,6 +354,8 @@ build_base_path (enum tree_code code,
build_pointer_type (ptrdiff_type_node),
v_offset);
v_offset = build_indirect_ref (v_offset, NULL);
+ TREE_CONSTANT (v_offset) = 1;
+ TREE_INVARIANT (v_offset) = 1;
offset = convert_to_integer (ptrdiff_type_node,
size_diffop (offset,
@@ -513,7 +515,7 @@ build_vtbl_ref_1 (tree instance, tree idx)
tree binfo = lookup_base (fixed_type, basetype,
ba_ignore|ba_quiet, NULL);
if (binfo)
- vtbl = BINFO_VTABLE (binfo);
+ vtbl = unshare_expr (BINFO_VTABLE (binfo));
}
if (!vtbl)
@@ -522,6 +524,8 @@ build_vtbl_ref_1 (tree instance, tree idx)
assemble_external (vtbl);
aref = build_array_ref (vtbl, idx);
+ TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
+ TREE_INVARIANT (aref) = TREE_CONSTANT (aref);
return aref;
}
@@ -7277,10 +7281,7 @@ dfs_accumulate_vtbl_inits (tree binfo,
/* Figure out the position to which the VPTR should point. */
vtbl = TREE_PURPOSE (l);
- vtbl = build1 (ADDR_EXPR,
- vtbl_ptr_type_node,
- vtbl);
- TREE_CONSTANT (vtbl) = 1;
+ vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, vtbl);
index = size_binop (PLUS_EXPR,
size_int (non_fn_entries),
size_int (list_length (TREE_VALUE (l))));
@@ -7288,7 +7289,6 @@ dfs_accumulate_vtbl_inits (tree binfo,
TYPE_SIZE_UNIT (vtable_entry_type),
index);
vtbl = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl, index);
- TREE_CONSTANT (vtbl) = 1;
}
if (ctor_vtbl_p)
@@ -7462,8 +7462,6 @@ build_vtbl_initializer (tree binfo,
/* Take the address of the function, considering it to be of an
appropriate generic type. */
init = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
- /* The address of a function can't change. */
- TREE_CONSTANT (init) = 1;
}
/* And add it to the chain of initializers. */
@@ -7480,6 +7478,7 @@ build_vtbl_initializer (tree binfo,
TREE_OPERAND (init, 0),
build_int_2 (i, 0));
TREE_CONSTANT (fdesc) = 1;
+ TREE_INVARIANT (fdesc) = 1;
vfun_inits = tree_cons (NULL_TREE, fdesc, vfun_inits);
}