From patchwork Mon Nov 13 21:47:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 837571 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-466682-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="DId6fJQF"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ybPQp3rnGz9rvt for ; Tue, 14 Nov 2017 08:48:33 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=eiyy0xlwZ24tFaoCtrkpRRUCBJn6q3cMpfTID2jXAaq44N yOnqNkwG0TCsqbeXhdb8Bo08llIpNfYX2Q0Q8AG6811NaTu1wmJdaxmlONKIfBwb G9VJXvQEPxNqlkJEMjEcYdeus+5XOQSLU0LkbSdM8FqPemyJ6+ws7HUAuBm3Q= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=cWdja/lO/bfUTf+EkiW7i5X8lHU=; b=DId6fJQFD20b5h4U8NDn j2rBJwv5qkHDic5nCv2qIpSL72NFRUFepiZRrvIdsV6Q112g5sWwlShBioRWKIRC 8qqamkX8xSUnftxupxxjMnw0hITQ+IWXvPE3mSgxIQqBxzrKPeSJ5XR4JRIAYOt+ QsSocbkhOI4049SKKmyB1vw= Received: (qmail 27192 invoked by alias); 13 Nov 2017 21:48:23 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 130548 invoked by uid 89); 13 Nov 2017 21:48:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=5578 X-HELO: mail-io0-f172.google.com Received: from mail-io0-f172.google.com (HELO mail-io0-f172.google.com) (209.85.223.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 13 Nov 2017 21:48:02 +0000 Received: by mail-io0-f172.google.com with SMTP id x63so10062055ioe.6 for ; Mon, 13 Nov 2017 13:48:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=obz7m0RWlVzFN51376K2tq0Rtwhn5zQv0uK8ajCw1bM=; b=iepUHUWssQzkQ5W5XxIyUUerIwRodIaAuKwI/TojMX5wIQHY3Yacv1aYoCoGkXn6MP GSwobjV4ICo/40lKNdPjTz37RHxaORlHHUU3xiFVug81lckylLtfvBmrb+Gl6SrGkyE6 z03fVnaBpuqqZKUaTusL+jLd1evenmSeIYjCCz6+PXc3rN9o8TioX3yIVaLODsIBMRuV 79O7km5l7oXH1TG0b41uONYNaZc+F4NjDfIWCXjJ2JrTmrrxzfjlNp709mIIWYQ/+0nD XQ1MwtZCV4uoMf95nBkH4KGHHRr9hdbRpCtv2Fq0WTwPZzir4U4b4n67teKguRJNpfeP 2bjQ== X-Gm-Message-State: AJaThX7As54ubdkZpWQZidMPHqUFf42v/+y0TMcyHuwaDc6tnuh+garZ dc2+lW7iH/oehjiCiLjqct3bN7DkdfbYozcDUTnclYmV X-Google-Smtp-Source: AGs4zMa3AcgsVjK4iHrLc9eZ8Kstam72jdstJXKBgPjESm6xB13BbCgk3jfveWjnEXPZVW7d3Ty9a0J6MSMQx3jF9Jk= X-Received: by 10.107.146.86 with SMTP id u83mr11830024iod.37.1510609679897; Mon, 13 Nov 2017 13:47:59 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.171.196 with HTTP; Mon, 13 Nov 2017 13:47:39 -0800 (PST) From: Jason Merrill Date: Mon, 13 Nov 2017 16:47:39 -0500 Message-ID: Subject: C++ PATCH to defer folding of *& To: gcc-patches List X-IsSubscribed: yes While working on another issue, I noticed that cp_build_indirect_ref was still folding away *&, which is incorrect because (int)*&var is an odr-use of var, whereas (int)var may not be. However, many of the existing users of cp_build_indirect_ref don't care about that distinction, and indeed rely on the folding, so I've introduce cp_build_fold_indirect_ref for such users. This function replaces most of the calls to cp_build_indirect_ref with a RO_NULL argument; the others are corrected to use the right RO_ argument instead. This patch revealed a typo bug in cp-ubsan, which I've also fixed. Tested x86_64-pc-linux-gnu, applying to trunk. commit 7bbb15a282fbdf160009d51eb8af31c24ddc6f60 Author: Jason Merrill Date: Fri Nov 10 13:19:29 2017 -0500 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. commit b6b55e177d45b6029a00fc3e1b488fa0b3e21dd0 Author: Jason Merrill Date: Mon Nov 13 11:59:01 2017 -0500 Fix cp-ubsan typo. * cp-ubsan.c (cp_ubsan_check_member_access_r): Fix handling of INDIRECT_REF of ADDR_EXPR. diff --git a/gcc/cp/cp-ubsan.c b/gcc/cp/cp-ubsan.c index cd2b60ad488..73198b9cff2 100644 --- a/gcc/cp/cp-ubsan.c +++ b/gcc/cp/cp-ubsan.c @@ -205,7 +205,7 @@ cp_ubsan_check_member_access_r (tree *stmt_p, int *walk_subtrees, void *data) if (TREE_CODE (t) == ADDR_EXPR) { *walk_subtrees = 0; - t = TREE_OPERAND (stmt, 0); + t = TREE_OPERAND (t, 0); cp_walk_tree (&t, cp_ubsan_check_member_access_r, data, ucmd->pset); } break; diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e6e0f901166..e18f0770614 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 98e62c6ad45..586a32c436f 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 874cbcbd2bd..ea61e87b2ec 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 73198b9cff2..c87c0303f57 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 0ce8f2d3435..54077d5e331 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 ecc8941984b..47f267ffb93 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 9e6e3aff779..98cdf9e8067 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 **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 **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 **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 **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 bb6c68a100a..7c8b6409409 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 77b96376e13..1860bf0f175 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 10ecbfd9589..b158507d7a8 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 b63f2ae4c5d..c60d54ab01f 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 38ec363dc95..6dad64133b2 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,17 +3035,12 @@ 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; @@ -3092,7 +3087,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 +3136,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 +3500,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 e8e13395431..e135b0de363 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;