From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 0ACFA3858C2C; Mon, 29 Aug 2022 15:34:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0ACFA3858C2C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1661787240; bh=gP7Z5n8hhGgdr7xDFX7L5sA2EC/MCdcidUqSxPs/ui8=; h=From:To:Subject:Date:From; b=n4klNWi/zh1GiB8acufmnX02Dq8rvmMtImy9yb4fkevGH45gPF14xu97RcrVdRLzO RLeDyQzJ9zjcrU6NNdVei8Ak0JS7ROTrLBBWsdsDvT6XEGbAlv2HRevdXvXCk8IrNy 0O9htt4hhTjWfHOX1iHVAetHbPQMfFjb9thbPvIw= 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] rust-constexpr.cc: port over NOP_EXPR case and fold_indrect_ref_1() X-Act-Checkin: gcc X-Git-Author: Faisal Abbas <90.abbasfaisal@gmail.com> X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: 23bde7d7c663302c803f0a7e4324630eae825008 X-Git-Newrev: fdbe92d898f11a4d395b5ee9a547707675edf442 Message-Id: <20220829153400.0ACFA3858C2C@sourceware.org> Date: Mon, 29 Aug 2022 15:34:00 +0000 (GMT) List-Id: https://gcc.gnu.org/g:fdbe92d898f11a4d395b5ee9a547707675edf442 commit fdbe92d898f11a4d395b5ee9a547707675edf442 Author: Faisal Abbas <90.abbasfaisal@gmail.com> Date: Fri Jul 29 06:14:41 2022 +0100 rust-constexpr.cc: port over NOP_EXPR case and fold_indrect_ref_1() Diff: --- gcc/rust/backend/rust-constexpr.cc | 149 +++++++++++++++++++++++++++++++++++++ gcc/rust/backend/rust-tree.h | 4 + 2 files changed, 153 insertions(+) diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc index 6ef601d66c2..1244047ef4f 100644 --- a/gcc/rust/backend/rust-constexpr.cc +++ b/gcc/rust/backend/rust-constexpr.cc @@ -697,6 +697,29 @@ eval_constant_expression (const constexpr_ctx *ctx, tree t, bool lval, non_constant_p, overflow_p); break; + case BREAK_STMT: + case CONTINUE_STMT: + if (jump_target) + *jump_target = t; + else + { + /* Can happen with ({ return true; }) && false; passed to + maybe_constant_value. There is nothing to jump over in this + case, and the bug will be diagnosed later. */ + gcc_assert (ctx->quiet); + *non_constant_p = true; + } + break; + + case NOP_EXPR: + if (REINTERPRET_CAST_P (t)) + { + if (!ctx->quiet) + error_at (loc, "% is not a constant expression"); + *non_constant_p = true; + return t; + } + case MODIFY_EXPR: r = eval_store_expression (ctx, t, false, non_constant_p, overflow_p); break; @@ -3032,6 +3055,132 @@ eval_unary_expression (const constexpr_ctx *ctx, tree t, bool /*lval*/, return r; } +// forked from gcc/cp/constexpr.cc cxx_union_active_member + +/* Try to determine the currently active union member for an expression + with UNION_TYPE. If it can be determined, return the FIELD_DECL, + otherwise return NULL_TREE. */ + +static tree +union_active_member (const constexpr_ctx *ctx, tree t) +{ + constexpr_ctx new_ctx = *ctx; + new_ctx.quiet = true; + bool non_constant_p = false, overflow_p = false; + tree ctor = eval_constant_expression (&new_ctx, t, false, &non_constant_p, + &overflow_p); + if (TREE_CODE (ctor) == CONSTRUCTOR && CONSTRUCTOR_NELTS (ctor) == 1 + && CONSTRUCTOR_ELT (ctor, 0)->index + && TREE_CODE (CONSTRUCTOR_ELT (ctor, 0)->index) == FIELD_DECL) + return CONSTRUCTOR_ELT (ctor, 0)->index; + return NULL_TREE; +} + +// forked from gcc/cp/constexpr.cc cxx_fold_indirect_ref_1 + +static tree +fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type, + tree op, unsigned HOST_WIDE_INT off, bool *empty_base) +{ + tree optype = TREE_TYPE (op); + unsigned HOST_WIDE_INT const_nunits; + if (off == 0 && similar_type_p (optype, type)) + return op; + else if (TREE_CODE (optype) == COMPLEX_TYPE + && similar_type_p (type, TREE_TYPE (optype))) + { + /* *(foo *)&complexfoo => __real__ complexfoo */ + if (off == 0) + return build1_loc (loc, REALPART_EXPR, type, op); + /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ + else if (tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off) + return build1_loc (loc, IMAGPART_EXPR, type, op); + } + /* ((foo*)&vectorfoo)[x] => BIT_FIELD_REF */ + else if (VECTOR_TYPE_P (optype) && similar_type_p (type, TREE_TYPE (optype)) + && TYPE_VECTOR_SUBPARTS (optype).is_constant (&const_nunits)) + { + unsigned HOST_WIDE_INT part_width = tree_to_uhwi (TYPE_SIZE_UNIT (type)); + unsigned HOST_WIDE_INT max_offset = part_width * const_nunits; + if (off < max_offset && off % part_width == 0) + { + tree index = bitsize_int (off * BITS_PER_UNIT); + return build3_loc (loc, BIT_FIELD_REF, type, op, TYPE_SIZE (type), + index); + } + } + /* ((foo *)&fooarray)[x] => fooarray[x] */ + else if (TREE_CODE (optype) == ARRAY_TYPE + && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype))) + && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype)))) + { + tree type_domain = TYPE_DOMAIN (optype); + tree min_val = size_zero_node; + if (type_domain && TYPE_MIN_VALUE (type_domain)) + min_val = TYPE_MIN_VALUE (type_domain); + unsigned HOST_WIDE_INT el_sz + = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (optype))); + unsigned HOST_WIDE_INT idx = off / el_sz; + unsigned HOST_WIDE_INT rem = off % el_sz; + if (tree_fits_uhwi_p (min_val)) + { + tree index = size_int (idx + tree_to_uhwi (min_val)); + op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index, + NULL_TREE, NULL_TREE); + return fold_indirect_ref_1 (ctx, loc, type, op, rem, empty_base); + } + } + /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */ + else if (TREE_CODE (optype) == RECORD_TYPE + || TREE_CODE (optype) == UNION_TYPE) + { + if (TREE_CODE (optype) == UNION_TYPE) + /* For unions prefer the currently active member. */ + if (tree field = union_active_member (ctx, op)) + { + unsigned HOST_WIDE_INT el_sz + = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field))); + if (off < el_sz) + { + tree cop = build3 (COMPONENT_REF, TREE_TYPE (field), op, field, + NULL_TREE); + if (tree ret = fold_indirect_ref_1 (ctx, loc, type, cop, off, + empty_base)) + return ret; + } + } + for (tree field = TYPE_FIELDS (optype); field; field = DECL_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && TREE_TYPE (field) != error_mark_node + && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (field)))) + { + tree pos = byte_position (field); + if (!tree_fits_uhwi_p (pos)) + continue; + unsigned HOST_WIDE_INT upos = tree_to_uhwi (pos); + unsigned HOST_WIDE_INT el_sz + = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field))); + if (upos <= off && off < upos + el_sz) + { + tree cop = build3 (COMPONENT_REF, TREE_TYPE (field), op, field, + NULL_TREE); + if (tree ret = fold_indirect_ref_1 (ctx, loc, type, cop, + off - upos, empty_base)) + return ret; + } + } + /* Also handle conversion to an empty base class, which + is represented with a NOP_EXPR. */ + if (is_empty_class (type) && CLASS_TYPE_P (optype)) + { + *empty_base = true; + return op; + } + } + + return NULL_TREE; +} + // #include "gt-rust-rust-constexpr.h" } // namespace Compile diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h index 757b721791f..b7c4676f0ab 100644 --- a/gcc/rust/backend/rust-tree.h +++ b/gcc/rust/backend/rust-tree.h @@ -1244,6 +1244,10 @@ extern GTY (()) tree cp_global_trees[CPTI_MAX]; in constructors/destructors of targetm.cxx.cdtor_returns_this targets. */ #define LABEL_DECL_CDTOR(NODE) DECL_LANG_FLAG_2 (LABEL_DECL_CHECK (NODE)) +/* Nonzero if this NOP_EXPR is a reinterpret_cast. Such conversions + are not constexprs. Other NOP_EXPRs are. */ +#define REINTERPRET_CAST_P(NODE) TREE_LANG_FLAG_0 (NOP_EXPR_CHECK (NODE)) + #if defined ENABLE_TREE_CHECKING #define LANG_DECL_MIN_CHECK(NODE) \