From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 6F9A63856249; Mon, 29 Aug 2022 15:33:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6F9A63856249 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1661787199; bh=2MMu4Na4DFLermf0kRmSGO+6FKbuNYqYi+QCHBfiw1A=; h=From:To:Subject:Date:From; b=LKoh0Br5qNMLdEkMyALFFJrQ0fbiAb8WbG7wgNUHfC5awcSB8pEnEPQshtawLe1Fl Mr2hQRinrbDjHe5YtYPbpETKfr1dK0q2Nwhiyi9cHUPTihHz7DUMxjwYQVfKSjp1tp lXtbGC4nJlCLKh09qgyV1USGgGNFRKhH1JuBrKwM= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Port over: X-Act-Checkin: gcc X-Git-Author: Philip Herron X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: 44b80bf0240aefb56d9abcce59c15a24a22048f4 X-Git-Newrev: 8a9b94d8c3ac6c691fa49585756c0df234602d8b Message-Id: <20220829153319.6F9A63856249@sourceware.org> Date: Mon, 29 Aug 2022 15:33:19 +0000 (GMT) List-Id: https://gcc.gnu.org/g:8a9b94d8c3ac6c691fa49585756c0df234602d8b commit 8a9b94d8c3ac6c691fa49585756c0df234602d8b Author: Philip Herron Date: Wed Jul 20 13:40:18 2022 +0100 Port over: - cxx_bind_parameters_in_call - addr_of_non_const_var - adjust_temp_type There is alot of cleanup we can do when we get more of this working but for now its best to keep porting like this. Diff: --- gcc/rust/backend/rust-constexpr.cc | 134 +++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc index c1d5cad1448..aa2d4708a9b 100644 --- a/gcc/rust/backend/rust-constexpr.cc +++ b/gcc/rust/backend/rust-constexpr.cc @@ -47,6 +47,8 @@ static HOST_WIDE_INT find_array_ctor_elt (tree ary, tree dindex, bool insert = false); static int array_index_cmp (tree key, tree index); +inline tree +get_nth_callarg (tree t, int n); struct constexpr_global_ctx { @@ -388,6 +390,138 @@ eval_binary_expression (const constexpr_ctx *ctx, tree t, bool lval, return fold_binary_loc (loc, code, type, lhs, rhs); } +/* TEMP is the constant value of a temporary object of type TYPE. Adjust + the type of the value to match. */ + +static tree +adjust_temp_type (tree type, tree temp) +{ + if (same_type_p (TREE_TYPE (temp), type)) + return temp; + + gcc_assert (scalarish_type_p (type)); + /* Now we know we're dealing with a scalar, and a prvalue of non-class + type is cv-unqualified. */ + return fold_convert (cv_unqualified (type), temp); +} + +/* Helper function of cxx_bind_parameters_in_call. Return non-NULL + if *TP is address of a static variable (or part of it) currently being + constructed or of a heap artificial variable. */ + +static tree +addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data) +{ + if (TREE_CODE (*tp) == ADDR_EXPR) + if (tree var = get_base_address (TREE_OPERAND (*tp, 0))) + if (VAR_P (var) && TREE_STATIC (var)) + { + if (DECL_NAME (var) == heap_uninit_identifier + || DECL_NAME (var) == heap_identifier + || DECL_NAME (var) == heap_vec_uninit_identifier + || DECL_NAME (var) == heap_vec_identifier) + return var; + + constexpr_global_ctx *global = (constexpr_global_ctx *) data; + if (global->values.get (var)) + return var; + } + if (TYPE_P (*tp)) + *walk_subtrees = false; + return NULL_TREE; +} + +/* Subroutine of cxx_eval_call_expression. + We are processing a call expression (either CALL_EXPR or + AGGR_INIT_EXPR) in the context of CTX. Evaluate + all arguments and bind their values to correspondings + parameters, making up the NEW_CALL context. */ + +static tree +rs_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun, + bool *non_constant_p, bool *overflow_p, + bool *non_constant_args) +{ + const int nargs = call_expr_nargs (t); + tree parms = DECL_ARGUMENTS (fun); + int i; + /* We don't record ellipsis args below. */ + int nparms = list_length (parms); + int nbinds = nargs < nparms ? nargs : nparms; + tree binds = make_tree_vec (nbinds); + for (i = 0; i < nargs; ++i) + { + tree x, arg; + tree type = parms ? TREE_TYPE (parms) : void_type_node; + if (parms && DECL_BY_REFERENCE (parms)) + type = TREE_TYPE (type); + x = get_nth_callarg (t, i); + + if (TREE_ADDRESSABLE (type)) + /* Undo convert_for_arg_passing work here. */ + x = convert_from_reference (x); + /* Normally we would strip a TARGET_EXPR in an initialization context + such as this, but here we do the elision differently: we keep the + TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */ + arg = constexpr_expression (ctx, x, /*lval=*/false, non_constant_p, + overflow_p); + /* Don't VERIFY_CONSTANT here. */ + if (*non_constant_p && ctx->quiet) + break; + /* Just discard ellipsis args after checking their constantitude. */ + if (!parms) + continue; + + if (!*non_constant_p) + { + /* Make sure the binding has the same type as the parm. But + only for constant args. */ + if (!TYPE_REF_P (type)) + arg = adjust_temp_type (type, arg); + if (!TREE_CONSTANT (arg)) + *non_constant_args = true; + else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) + /* The destructor needs to see any modifications the callee makes + to the argument. */ + *non_constant_args = true; + /* If arg is or contains address of a heap artificial variable or + of a static variable being constructed, avoid caching the + function call, as those variables might be modified by the + function, or might be modified by the callers in between + the cached function and just read by the function. */ + else if (!*non_constant_args + && rs_walk_tree (&arg, addr_of_non_const_var, ctx->global, + NULL)) + *non_constant_args = true; + + // /* For virtual calls, adjust the this argument, so that it is + // the object on which the method is called, rather than + // one of its bases. */ + // if (i == 0 && DECL_VIRTUAL_P (fun)) + // { + // tree addr = arg; + // STRIP_NOPS (addr); + // if (TREE_CODE (addr) == ADDR_EXPR) + // { + // tree obj = TREE_OPERAND (addr, 0); + // while (TREE_CODE (obj) == COMPONENT_REF + // && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1)) + // && !same_type_ignoring_top_level_qualifiers_p ( + // TREE_TYPE (obj), DECL_CONTEXT (fun))) + // obj = TREE_OPERAND (obj, 0); + // if (obj != TREE_OPERAND (addr, 0)) + // arg = build_fold_addr_expr_with_type (obj, TREE_TYPE + // (arg)); + // } + // } + TREE_VEC_ELT (binds, i) = arg; + } + parms = TREE_CHAIN (parms); + } + + return binds; +} + // Subroutine of cxx_eval_constant_expression. // Evaluate the call expression tree T in the context of OLD_CALL expression // evaluation.