Defer folding of *&.
* typeck.c (cp_build_fold_indirect_ref): New. (cp_build_indirect_ref_1): Split out from cp_build_indirect_ref. Add 'fold' parameter. * cp-tree.h: Declare cp_build_fold_indirect_ref. * call.c, class.c, cp-ubsan.c, decl.c, except.c, init.c, lambda.c, parser.c, rtti.c, tree.c, typeck.c, typeck2.c: Use it. * parser.c (do_range_for_auto_deduction): Use RO_UNARY_STAR. (cp_convert_range_for): Likewise. * typeck2.c (build_x_arrow): Use RO_ARROW. From-SVN: r254712
This commit is contained in:
parent
cd920e1348
commit
04757a2a49
@ -1,5 +1,16 @@
|
||||
2017-11-13 Jason Merrill <jason@redhat.com>
|
||||
|
||||
Defer folding of *&.
|
||||
* typeck.c (cp_build_fold_indirect_ref): New.
|
||||
(cp_build_indirect_ref_1): Split out from cp_build_indirect_ref.
|
||||
Add 'fold' parameter.
|
||||
* cp-tree.h: Declare cp_build_fold_indirect_ref.
|
||||
* call.c, class.c, cp-ubsan.c, decl.c, except.c, init.c, lambda.c,
|
||||
parser.c, rtti.c, tree.c, typeck.c, typeck2.c: Use it.
|
||||
* parser.c (do_range_for_auto_deduction): Use RO_UNARY_STAR.
|
||||
(cp_convert_range_for): Likewise.
|
||||
* typeck2.c (build_x_arrow): Use RO_ARROW.
|
||||
|
||||
* cp-ubsan.c (cp_ubsan_check_member_access_r): Fix handling of
|
||||
INDIRECT_REF of ADDR_EXPR.
|
||||
|
||||
|
@ -8063,7 +8063,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
if (targ)
|
||||
arg = targ;
|
||||
else
|
||||
arg = cp_build_indirect_ref (arg, RO_NULL, complain);
|
||||
arg = cp_build_fold_indirect_ref (arg);
|
||||
|
||||
/* In C++17 we shouldn't be copying a TARGET_EXPR except into a base
|
||||
subobject. */
|
||||
@ -8100,9 +8100,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
else if ((trivial || TREE_CODE (arg) == TARGET_EXPR)
|
||||
&& !unsafe_copy_elision_p (fa, arg))
|
||||
{
|
||||
tree to = cp_stabilize_reference (cp_build_indirect_ref (fa,
|
||||
RO_NULL,
|
||||
complain));
|
||||
tree to = cp_stabilize_reference (cp_build_fold_indirect_ref (fa));
|
||||
|
||||
val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
|
||||
return val;
|
||||
@ -8114,7 +8112,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
&& !DECL_DELETED_FN (fn))
|
||||
{
|
||||
tree to = cp_stabilize_reference
|
||||
(cp_build_indirect_ref (argarray[0], RO_NULL, complain));
|
||||
(cp_build_fold_indirect_ref (argarray[0]));
|
||||
tree type = TREE_TYPE (to);
|
||||
tree as_base = CLASSTYPE_AS_BASE (type);
|
||||
tree arg = argarray[1];
|
||||
@ -8127,7 +8125,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
}
|
||||
else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
|
||||
{
|
||||
arg = cp_build_indirect_ref (arg, RO_NULL, complain);
|
||||
arg = cp_build_fold_indirect_ref (arg);
|
||||
val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
|
||||
/* Handle NSDMI that refer to the object being initialized. */
|
||||
replace_placeholders (arg, to);
|
||||
@ -8166,7 +8164,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
return force_target_expr (DECL_CONTEXT (fn), void_node,
|
||||
no_cleanup_complain);
|
||||
else
|
||||
return cp_build_indirect_ref (argarray[0], RO_NULL, complain);
|
||||
return cp_build_fold_indirect_ref (argarray[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,7 +425,7 @@ build_base_path (enum tree_code code,
|
||||
interesting to the optimizers anyway. */
|
||||
&& !has_empty)
|
||||
{
|
||||
expr = cp_build_indirect_ref (expr, RO_NULL, complain);
|
||||
expr = cp_build_fold_indirect_ref (expr);
|
||||
expr = build_simple_base_path (expr, binfo);
|
||||
if (rvalue)
|
||||
expr = move (expr);
|
||||
@ -452,7 +452,7 @@ build_base_path (enum tree_code code,
|
||||
t = TREE_TYPE (TYPE_VFIELD (current_class_type));
|
||||
t = build_pointer_type (t);
|
||||
v_offset = fold_convert (t, current_vtt_parm);
|
||||
v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
|
||||
v_offset = cp_build_fold_indirect_ref (v_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -465,8 +465,7 @@ build_base_path (enum tree_code code,
|
||||
if (t == NULL_TREE)
|
||||
t = expr;
|
||||
}
|
||||
v_offset = build_vfield_ref (cp_build_indirect_ref (t, RO_NULL,
|
||||
complain),
|
||||
v_offset = build_vfield_ref (cp_build_fold_indirect_ref (t),
|
||||
TREE_TYPE (TREE_TYPE (expr)));
|
||||
}
|
||||
|
||||
@ -477,7 +476,7 @@ build_base_path (enum tree_code code,
|
||||
v_offset = build1 (NOP_EXPR,
|
||||
build_pointer_type (ptrdiff_type_node),
|
||||
v_offset);
|
||||
v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
|
||||
v_offset = cp_build_fold_indirect_ref (v_offset);
|
||||
TREE_CONSTANT (v_offset) = 1;
|
||||
|
||||
offset = convert_to_integer (ptrdiff_type_node,
|
||||
@ -516,7 +515,7 @@ build_base_path (enum tree_code code,
|
||||
indout:
|
||||
if (!want_pointer)
|
||||
{
|
||||
expr = cp_build_indirect_ref (expr, RO_NULL, complain);
|
||||
expr = cp_build_fold_indirect_ref (expr);
|
||||
if (rvalue)
|
||||
expr = move (expr);
|
||||
}
|
||||
@ -552,7 +551,7 @@ build_simple_base_path (tree expr, tree binfo)
|
||||
in the back end. */
|
||||
temp = unary_complex_lvalue (ADDR_EXPR, expr);
|
||||
if (temp)
|
||||
expr = cp_build_indirect_ref (temp, RO_NULL, tf_warning_or_error);
|
||||
expr = cp_build_fold_indirect_ref (temp);
|
||||
|
||||
return expr;
|
||||
}
|
||||
@ -745,8 +744,7 @@ build_vfn_ref (tree instance_ptr, tree idx)
|
||||
{
|
||||
tree aref;
|
||||
|
||||
aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, RO_NULL,
|
||||
tf_warning_or_error),
|
||||
aref = build_vtbl_ref_1 (cp_build_fold_indirect_ref (instance_ptr),
|
||||
idx);
|
||||
|
||||
/* When using function descriptors, the address of the
|
||||
|
@ -7056,6 +7056,7 @@ extern tree build_x_indirect_ref (location_t, tree,
|
||||
ref_operator, tsubst_flags_t);
|
||||
extern tree cp_build_indirect_ref (tree, ref_operator,
|
||||
tsubst_flags_t);
|
||||
extern tree cp_build_fold_indirect_ref (tree);
|
||||
extern tree build_array_ref (location_t, tree, tree);
|
||||
extern tree cp_build_array_ref (location_t, tree, tree,
|
||||
tsubst_flags_t);
|
||||
|
@ -298,8 +298,7 @@ cp_ubsan_dfs_initialize_vtbl_ptrs (tree binfo, void *data)
|
||||
|
||||
/* Compute the location of the vtpr. */
|
||||
tree vtbl_ptr
|
||||
= build_vfield_ref (cp_build_indirect_ref (base_ptr, RO_NULL,
|
||||
tf_warning_or_error),
|
||||
= build_vfield_ref (cp_build_fold_indirect_ref (base_ptr),
|
||||
TREE_TYPE (binfo));
|
||||
gcc_assert (vtbl_ptr != error_mark_node);
|
||||
|
||||
|
@ -14899,7 +14899,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
|
||||
gcc_assert (TYPE_PTR_P (TREE_TYPE (t)));
|
||||
|
||||
cp_function_chain->x_current_class_ref
|
||||
= cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
|
||||
= cp_build_fold_indirect_ref (t);
|
||||
/* Set this second to avoid shortcut in cp_build_indirect_ref. */
|
||||
cp_function_chain->x_current_class_ptr = t;
|
||||
|
||||
|
@ -664,7 +664,7 @@ build_throw (tree exp)
|
||||
CLEANUP_EH_ONLY (allocate_expr) = 1;
|
||||
|
||||
object = build_nop (build_pointer_type (temp_type), ptr);
|
||||
object = cp_build_indirect_ref (object, RO_NULL, tf_warning_or_error);
|
||||
object = cp_build_fold_indirect_ref (object);
|
||||
|
||||
/* And initialize the exception object. */
|
||||
if (CLASS_TYPE_P (temp_type))
|
||||
|
@ -1260,8 +1260,7 @@ emit_mem_initializers (tree mem_inits)
|
||||
base_addr = build_base_path (PLUS_EXPR, current_class_ptr,
|
||||
subobject, 1, tf_warning_or_error);
|
||||
expand_aggr_init_1 (subobject, NULL_TREE,
|
||||
cp_build_indirect_ref (base_addr, RO_NULL,
|
||||
tf_warning_or_error),
|
||||
cp_build_fold_indirect_ref (base_addr),
|
||||
arguments,
|
||||
flags,
|
||||
tf_warning_or_error);
|
||||
@ -1351,7 +1350,7 @@ expand_virtual_init (tree binfo, tree decl)
|
||||
/* Compute the value to use, when there's a VTT. */
|
||||
vtt_parm = current_vtt_parm;
|
||||
vtbl2 = fold_build_pointer_plus (vtt_parm, vtt_index);
|
||||
vtbl2 = cp_build_indirect_ref (vtbl2, RO_NULL, tf_warning_or_error);
|
||||
vtbl2 = cp_build_fold_indirect_ref (vtbl2);
|
||||
vtbl2 = convert (TREE_TYPE (vtbl), vtbl2);
|
||||
|
||||
/* The actual initializer is the VTT value only in the subobject
|
||||
@ -1361,8 +1360,7 @@ expand_virtual_init (tree binfo, tree decl)
|
||||
}
|
||||
|
||||
/* Compute the location of the vtpr. */
|
||||
vtbl_ptr = build_vfield_ref (cp_build_indirect_ref (decl, RO_NULL,
|
||||
tf_warning_or_error),
|
||||
vtbl_ptr = build_vfield_ref (cp_build_fold_indirect_ref (decl),
|
||||
TREE_TYPE (binfo));
|
||||
gcc_assert (vtbl_ptr != error_mark_node);
|
||||
|
||||
@ -3268,7 +3266,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
|
||||
alloc_node, cookie_ptr);
|
||||
size_ptr_type = build_pointer_type (sizetype);
|
||||
cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
|
||||
cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
|
||||
cookie = cp_build_fold_indirect_ref (cookie_ptr);
|
||||
|
||||
cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
|
||||
|
||||
@ -3280,7 +3278,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
|
||||
NEGATE_EXPR, sizetype,
|
||||
size_in_bytes (sizetype)));
|
||||
|
||||
cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
|
||||
cookie = cp_build_fold_indirect_ref (cookie_ptr);
|
||||
cookie = build2 (MODIFY_EXPR, sizetype, cookie,
|
||||
size_in_bytes (elt_type));
|
||||
cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
|
||||
@ -3326,7 +3324,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
|
||||
the initializer anyway since we're going to throw it away and
|
||||
rebuild it at instantiation time, so just build up a single
|
||||
constructor call to get any appropriate diagnostics. */
|
||||
init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
|
||||
init_expr = cp_build_fold_indirect_ref (data_addr);
|
||||
if (type_build_ctor_call (elt_type))
|
||||
init_expr = build_special_member_call (init_expr,
|
||||
complete_ctor_identifier,
|
||||
@ -3384,7 +3382,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
|
||||
}
|
||||
else
|
||||
{
|
||||
init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
|
||||
init_expr = cp_build_fold_indirect_ref (data_addr);
|
||||
|
||||
if (type_build_ctor_call (type) && !explicit_value_init_p)
|
||||
{
|
||||
@ -4507,7 +4505,7 @@ build_vec_init (tree base, tree maxindex, tree init,
|
||||
{
|
||||
atype = build_pointer_type (atype);
|
||||
stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
|
||||
stmt_expr = cp_build_indirect_ref (stmt_expr, RO_NULL, complain);
|
||||
stmt_expr = cp_build_fold_indirect_ref (stmt_expr);
|
||||
TREE_NO_WARNING (stmt_expr) = 1;
|
||||
}
|
||||
|
||||
@ -4661,8 +4659,7 @@ build_delete (tree otype, tree addr, special_function_kind auto_delete,
|
||||
/* Make sure the destructor is callable. */
|
||||
if (type_build_dtor_call (type))
|
||||
{
|
||||
expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL,
|
||||
complain),
|
||||
expr = build_dtor_call (cp_build_fold_indirect_ref (addr),
|
||||
sfk_complete_destructor, flags, complain);
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
@ -4738,7 +4735,7 @@ build_delete (tree otype, tree addr, special_function_kind auto_delete,
|
||||
complain);
|
||||
}
|
||||
|
||||
expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL, complain),
|
||||
expr = build_dtor_call (cp_build_fold_indirect_ref (addr),
|
||||
auto_delete, flags, complain);
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
@ -4918,7 +4915,7 @@ build_vec_delete (tree base, tree maxindex,
|
||||
sizetype, TYPE_SIZE_UNIT (sizetype));
|
||||
cookie_addr = fold_build_pointer_plus (fold_convert (size_ptr_type, base),
|
||||
cookie_addr);
|
||||
maxindex = cp_build_indirect_ref (cookie_addr, RO_NULL, complain);
|
||||
maxindex = cp_build_fold_indirect_ref (cookie_addr);
|
||||
}
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
|
@ -557,8 +557,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
|
||||
{
|
||||
gcc_assert (POINTER_TYPE_P (type));
|
||||
type = TREE_TYPE (type);
|
||||
initializer = cp_build_indirect_ref (initializer, RO_NULL,
|
||||
tf_warning_or_error);
|
||||
initializer = cp_build_fold_indirect_ref (initializer);
|
||||
}
|
||||
|
||||
if (dependent_type_p (type))
|
||||
@ -862,8 +861,7 @@ maybe_resolve_dummy (tree object, bool add_capture_p)
|
||||
if (tree lam = resolvable_dummy_lambda (object))
|
||||
if (tree cap = lambda_expr_this_capture (lam, add_capture_p))
|
||||
if (cap != error_mark_node)
|
||||
object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
|
||||
RO_NULL, tf_warning_or_error);
|
||||
object = build_fold_indirect_ref (cap);
|
||||
|
||||
return object;
|
||||
}
|
||||
@ -1154,8 +1152,7 @@ maybe_add_lambda_conv_op (tree type)
|
||||
return expression for a deduced return call op to allow for simple
|
||||
implementation of the conversion operator. */
|
||||
|
||||
tree instance = cp_build_indirect_ref (thisarg, RO_NULL,
|
||||
tf_warning_or_error);
|
||||
tree instance = cp_build_fold_indirect_ref (thisarg);
|
||||
tree objfn = build_min (COMPONENT_REF, NULL_TREE,
|
||||
instance, DECL_NAME (callop), NULL_TREE);
|
||||
int nargs = list_length (DECL_ARGUMENTS (callop)) - 1;
|
||||
|
@ -11931,7 +11931,8 @@ do_range_for_auto_deduction (tree decl, tree range_expr)
|
||||
{
|
||||
iter_decl = build_decl (input_location, VAR_DECL, NULL_TREE,
|
||||
iter_type);
|
||||
iter_decl = build_x_indirect_ref (input_location, iter_decl, RO_NULL,
|
||||
iter_decl = build_x_indirect_ref (input_location, iter_decl,
|
||||
RO_UNARY_STAR,
|
||||
tf_warning_or_error);
|
||||
TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
|
||||
iter_decl, auto_node);
|
||||
@ -12048,7 +12049,7 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr,
|
||||
|
||||
/* The declaration is initialized with *__begin inside the loop body. */
|
||||
cp_finish_decl (range_decl,
|
||||
build_x_indirect_ref (input_location, begin, RO_NULL,
|
||||
build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
|
||||
tf_warning_or_error),
|
||||
/*is_constant_init*/false, NULL_TREE,
|
||||
LOOKUP_ONLYCONVERTING);
|
||||
@ -20843,7 +20844,7 @@ inject_this_parameter (tree ctype, cp_cv_quals quals)
|
||||
/* Clear this first to avoid shortcut in cp_build_indirect_ref. */
|
||||
current_class_ptr = NULL_TREE;
|
||||
current_class_ref
|
||||
= cp_build_indirect_ref (this_parm, RO_NULL, tf_warning_or_error);
|
||||
= cp_build_fold_indirect_ref (this_parm);
|
||||
current_class_ptr = this_parm;
|
||||
}
|
||||
|
||||
|
@ -206,8 +206,7 @@ build_headof (tree exp)
|
||||
index = build_int_cst (NULL_TREE,
|
||||
-2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
|
||||
|
||||
offset = build_vtbl_ref (cp_build_indirect_ref (exp, RO_NULL,
|
||||
tf_warning_or_error),
|
||||
offset = build_vtbl_ref (cp_build_fold_indirect_ref (exp),
|
||||
index);
|
||||
|
||||
type = cp_build_qualified_type (ptr_type_node,
|
||||
@ -303,7 +302,7 @@ get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain)
|
||||
/* Otherwise return the type_info for the static type of the expr. */
|
||||
t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
|
||||
|
||||
return cp_build_indirect_ref (t, RO_NULL, complain);
|
||||
return cp_build_fold_indirect_ref (t);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -365,7 +364,7 @@ build_typeid (tree exp, tsubst_flags_t complain)
|
||||
exp = cp_build_addr_expr (exp, complain);
|
||||
exp = save_expr (exp);
|
||||
cond = cp_convert (boolean_type_node, exp, complain);
|
||||
exp = cp_build_indirect_ref (exp, RO_NULL, complain);
|
||||
exp = cp_build_fold_indirect_ref (exp);
|
||||
}
|
||||
|
||||
exp = get_tinfo_decl_dynamic (exp, complain);
|
||||
@ -529,7 +528,7 @@ get_typeid (tree type, tsubst_flags_t complain)
|
||||
if (!type)
|
||||
return error_mark_node;
|
||||
|
||||
return cp_build_indirect_ref (get_tinfo_ptr (type), RO_NULL, complain);
|
||||
return cp_build_fold_indirect_ref (get_tinfo_ptr (type));
|
||||
}
|
||||
|
||||
/* Check whether TEST is null before returning RESULT. If TEST is used in
|
||||
|
@ -3841,7 +3841,7 @@ tree
|
||||
build_dummy_object (tree type)
|
||||
{
|
||||
tree decl = build1 (CONVERT_EXPR, build_pointer_type (type), void_node);
|
||||
return cp_build_indirect_ref (decl, RO_NULL, tf_warning_or_error);
|
||||
return cp_build_fold_indirect_ref (decl);
|
||||
}
|
||||
|
||||
/* We've gotten a reference to a member of TYPE. Return *this if appropriate,
|
||||
@ -5011,7 +5011,7 @@ stabilize_expr (tree exp, tree* initp)
|
||||
exp = cp_build_addr_expr (exp, tf_warning_or_error);
|
||||
init_expr = get_target_expr (exp);
|
||||
exp = TARGET_EXPR_SLOT (init_expr);
|
||||
exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
|
||||
exp = cp_build_fold_indirect_ref (exp);
|
||||
if (xval)
|
||||
exp = move (exp);
|
||||
}
|
||||
|
@ -2356,7 +2356,7 @@ build_class_member_access_expr (cp_expr object, tree member,
|
||||
{
|
||||
tree temp = unary_complex_lvalue (ADDR_EXPR, object);
|
||||
if (temp)
|
||||
object = cp_build_indirect_ref (temp, RO_NULL, complain);
|
||||
object = cp_build_fold_indirect_ref (temp);
|
||||
}
|
||||
|
||||
/* In [expr.ref], there is an explicit list of the valid choices for
|
||||
@ -3035,20 +3035,19 @@ build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring,
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* Helper function called from c-common. */
|
||||
tree
|
||||
build_indirect_ref (location_t /*loc*/,
|
||||
tree ptr, ref_operator errorstring)
|
||||
{
|
||||
return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error);
|
||||
}
|
||||
/* The implementation of the above, and of indirection implied by other
|
||||
constructs. If DO_FOLD is true, fold away INDIRECT_REF of ADDR_EXPR. */
|
||||
|
||||
tree
|
||||
cp_build_indirect_ref (tree ptr, ref_operator errorstring,
|
||||
tsubst_flags_t complain)
|
||||
static tree
|
||||
cp_build_indirect_ref_1 (tree ptr, ref_operator errorstring,
|
||||
tsubst_flags_t complain, bool do_fold)
|
||||
{
|
||||
tree pointer, type;
|
||||
|
||||
/* RO_NULL should only be used with the folding entry points below, not
|
||||
cp_build_indirect_ref. */
|
||||
gcc_checking_assert (errorstring != RO_NULL || do_fold);
|
||||
|
||||
if (ptr == current_class_ptr
|
||||
|| (TREE_CODE (ptr) == NOP_EXPR
|
||||
&& TREE_OPERAND (ptr, 0) == current_class_ptr
|
||||
@ -3092,7 +3091,7 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring,
|
||||
error ("%qT is not a pointer-to-object type", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (TREE_CODE (pointer) == ADDR_EXPR
|
||||
else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
|
||||
&& same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
|
||||
/* The POINTER was something like `&x'. We simplify `*&x' to
|
||||
`x'. */
|
||||
@ -3141,6 +3140,34 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring,
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Entry point used by c-common, which expects folding. */
|
||||
|
||||
tree
|
||||
build_indirect_ref (location_t /*loc*/,
|
||||
tree ptr, ref_operator errorstring)
|
||||
{
|
||||
return cp_build_indirect_ref_1 (ptr, errorstring, tf_warning_or_error, true);
|
||||
}
|
||||
|
||||
/* Entry point used by internal indirection needs that don't correspond to any
|
||||
syntactic construct. */
|
||||
|
||||
tree
|
||||
cp_build_fold_indirect_ref (tree pointer)
|
||||
{
|
||||
return cp_build_indirect_ref_1 (pointer, RO_NULL, tf_warning_or_error, true);
|
||||
}
|
||||
|
||||
/* Entry point used by indirection needs that correspond to some syntactic
|
||||
construct. */
|
||||
|
||||
tree
|
||||
cp_build_indirect_ref (tree ptr, ref_operator errorstring,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
return cp_build_indirect_ref_1 (ptr, errorstring, complain, false);
|
||||
}
|
||||
|
||||
/* This handles expressions of the form "a[i]", which denotes
|
||||
an array reference.
|
||||
|
||||
@ -3477,13 +3504,13 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
|
||||
/* Next extract the vtable pointer from the object. */
|
||||
vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
|
||||
instance_ptr);
|
||||
vtbl = cp_build_indirect_ref (vtbl, RO_NULL, complain);
|
||||
vtbl = cp_build_fold_indirect_ref (vtbl);
|
||||
if (vtbl == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* Finally, extract the function pointer from the vtable. */
|
||||
e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
|
||||
e2 = cp_build_indirect_ref (e2, RO_NULL, complain);
|
||||
e2 = cp_build_fold_indirect_ref (e2);
|
||||
if (e2 == error_mark_node)
|
||||
return error_mark_node;
|
||||
TREE_CONSTANT (e2) = 1;
|
||||
|
@ -1792,7 +1792,7 @@ build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
|
||||
return expr;
|
||||
}
|
||||
|
||||
return cp_build_indirect_ref (last_rval, RO_NULL, complain);
|
||||
return cp_build_indirect_ref (last_rval, RO_ARROW, complain);
|
||||
}
|
||||
|
||||
if (complain & tf_error)
|
||||
@ -1893,7 +1893,7 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
|
||||
value stored in the pointer-to-data-member. */
|
||||
ptype = build_pointer_type (type);
|
||||
datum = fold_build_pointer_plus (fold_convert (ptype, datum), component);
|
||||
datum = cp_build_indirect_ref (datum, RO_NULL, complain);
|
||||
datum = cp_build_fold_indirect_ref (datum);
|
||||
if (datum == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user