aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-11-13 17:12:55 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-11-13 17:12:55 -0500
commit04757a2a49bd21c71af386a64591f77c165a0d93 (patch)
tree1abdf8c3ce6efdfe6e521741c681eae3a746db70 /gcc/cp
parentcd920e1348eaa1100b90f378f44e110152816149 (diff)
downloadgcc-04757a2a49bd21c71af386a64591f77c165a0d93.zip
gcc-04757a2a49bd21c71af386a64591f77c165a0d93.tar.gz
gcc-04757a2a49bd21c71af386a64591f77c165a0d93.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/call.c12
-rw-r--r--gcc/cp/class.c16
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/cp-ubsan.c3
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/cp/except.c2
-rw-r--r--gcc/cp/init.c25
-rw-r--r--gcc/cp/lambda.c9
-rw-r--r--gcc/cp/parser.c7
-rw-r--r--gcc/cp/rtti.c9
-rw-r--r--gcc/cp/tree.c4
-rw-r--r--gcc/cp/typeck.c55
-rw-r--r--gcc/cp/typeck2.c4
14 files changed, 94 insertions, 66 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 83cb401..f71506b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e6e0f90..e18f077 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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]);
}
}
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 98e62c6..586a32c 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 874cbcb..ea61e87 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/cp-ubsan.c b/gcc/cp/cp-ubsan.c
index 73198b9..c87c030 100644
--- a/gcc/cp/cp-ubsan.c
+++ b/gcc/cp/cp-ubsan.c
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0ce8f2d..54077d5 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index ecc8941..47f267f 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -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))
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 1fcd91d..1084ab1 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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)
{
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index bb6c68a..7c8b640 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -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;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 77b9637..1860bf0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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;
}
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 10ecbfd..b158507 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -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
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index b63f2ae..c60d54a 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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);
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 38ec363..f9a5f85 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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;
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index e8e1339..e135b0d 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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;