From patchwork Sat Aug 3 23:17:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Colomar X-Patchwork-Id: 95260 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 17AFB385828E for ; Sat, 3 Aug 2024 23:17:55 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by sourceware.org (Postfix) with ESMTPS id 617353858C50 for ; Sat, 3 Aug 2024 23:17:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 617353858C50 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kernel.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 617353858C50 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=139.178.84.217 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722727037; cv=none; b=rtyu0nbteVxOC0bnAldYQWhBX0FaopMrCPjSvsEGcKpqiz881GhHooZl3Sv28t+eEgJpc7QjLC0DY9ohnfGznn52VR4QMYh2kANvvoBKRYRs4D8jEDrEKXANLxh4jSvss0x4DN2JDIYdx6y2cZQHtgICVgTrRjqE6enUVOR9Maw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722727037; c=relaxed/simple; bh=QY/Npn0f1RDrkspLB6k7OW5viK/vz87m0cB8hVoV+40=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=V6pNOGV1UwCtSx8e7m0TXhtTf8G8rUzwac4kui539pC1tnIU6CQJ745EMONhZQwMBta45ZIiPl/x+o9luXD8/XGPd1FwrMXiQfWQrqYJr6uJ0PGfnSeS8MRTDFuZVMaG57jTmvEwZlfyiL96rt3OmzLWQId48TSN8502ffoBAMQ= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id EB01460BC9; Sat, 3 Aug 2024 23:17:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 06506C4AF09; Sat, 3 Aug 2024 23:17:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722727033; bh=QY/Npn0f1RDrkspLB6k7OW5viK/vz87m0cB8hVoV+40=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=hMyV602lEiC1g25ZT71JyXC2dT5RdfMDx0goclr3h3GjNWa9PAIz7I7kxhUBs6l82 FeV1BYbmP2uxEZnHj1Nn8xNSJztEsE9qN+xDox35gvN8aGxw9FEb/ugKyKKpSbWepR BLgGRzRltJQJ6Qyr4CyPw7wBNPzqkjeFyOuvvQUUOdhDKcF3OB36ZMrN99t2JWrVzK LeIZxKtSUEasdk7VOOgTvQ8Ejc7XjReOObEZ94V6CK1VKfDkwE3cAbvS/0RIU6WTxM cVXXaTE2PNCz2QqpJ0UO2Uvc7z0PieXHL5oRki5sZcTE7Z1QFKjhsDp7bS7qeQ3jI1 9GjwuzpGRtO/w== Date: Sun, 4 Aug 2024 01:17:10 +0200 From: Alejandro Colomar To: gcc-patches@gcc.gnu.org Cc: Alejandro Colomar , Xavier Del Campo Romero , Gabriel Ravier , Martin Uecker , Joseph Myers , Jakub Jelinek , Richard Biener Subject: [RFC v3 1/3] gcc/: Rename array_type_nelts() => array_type_nelts_minus_one() Message-ID: <20240803231702.89150-2-alx@kernel.org> X-Mailer: git-send-email 2.45.2 References: <20240728141547.302478-1-alx@kernel.org> <20240803231702.89150-1-alx@kernel.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20240803231702.89150-1-alx@kernel.org> X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org The old name was misleading. While at it, also rename some temporary variables that are used with this function, for consistency. Link: https://inbox.sourceware.org/gcc-patches/9fffd80-dca-2c7e-14b-6c9b509a7215@redhat.com/T/#m2f661c67c8f7b2c405c8c7fc3152dd85dc729120 Cc: Gabriel Ravier Cc: Martin Uecker Cc: Joseph Myers Cc: Xavier Del Campo Romero Cc: Jakub Jelinek gcc/ChangeLog: * tree.cc (array_type_nelts): Rename function ... (array_type_nelts_minus_one): ... to this name. The old name was misleading. * tree.h (array_type_nelts): Rename function ... (array_type_nelts_minus_one): ... to this name. The old name was misleading. * expr.cc (count_type_elements): Rename array_type_nelts() => array_type_nelts_minus_one() * config/aarch64/aarch64.cc (pure_scalable_type_info::analyze_array): Likewise. * config/i386/i386.cc (ix86_canonical_va_list_type): Likewise. gcc/c/ChangeLog: * c-decl.cc (one_element_array_type_p, get_parm_array_spec): Rename array_type_nelts() => array_type_nelts_minus_one() * c-fold.cc (c_fold_array_ref): Likewise. gcc/cp/ChangeLog: * decl.cc (reshape_init_array): Rename array_type_nelts() => array_type_nelts_minus_one() * init.cc (build_zero_init_1): Likewise. (build_value_init_noctor): Likewise. (build_vec_init): Likewise. (build_delete): Likewise. * lambda.cc (add_capture): Likewise. * tree.cc (array_type_nelts_top): Likewise. gcc/fortran/ChangeLog: * trans-array.cc (structure_alloc_comps): Rename array_type_nelts() => array_type_nelts_minus_one() * trans-openmp.cc (gfc_walk_alloc_comps): Likewise. (gfc_omp_clause_linear_ctor): Likewise. gcc/rust/ChangeLog: * backend/rust-tree.cc (array_type_nelts_top): Rename array_type_nelts() => array_type_nelts_minus_one() Suggested-by: Richard Biener Signed-off-by: Alejandro Colomar --- gcc/c/c-decl.cc | 10 +++++----- gcc/c/c-fold.cc | 7 ++++--- gcc/config/aarch64/aarch64.cc | 2 +- gcc/config/i386/i386.cc | 2 +- gcc/cp/decl.cc | 2 +- gcc/cp/init.cc | 8 ++++---- gcc/cp/lambda.cc | 3 ++- gcc/cp/tree.cc | 2 +- gcc/expr.cc | 8 ++++---- gcc/fortran/trans-array.cc | 2 +- gcc/fortran/trans-openmp.cc | 4 ++-- gcc/rust/backend/rust-tree.cc | 2 +- gcc/tree.cc | 4 ++-- gcc/tree.h | 2 +- 14 files changed, 30 insertions(+), 28 deletions(-) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 97f1d346835..4dced430d1f 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -5309,7 +5309,7 @@ one_element_array_type_p (const_tree type) { if (TREE_CODE (type) != ARRAY_TYPE) return false; - return integer_zerop (array_type_nelts (type)); + return integer_zerop (array_type_nelts_minus_one (type)); } /* Determine whether TYPE is a zero-length array type "[0]". */ @@ -6257,15 +6257,15 @@ get_parm_array_spec (const struct c_parm *parm, tree attrs) for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE; type = TREE_TYPE (type)) { - tree nelts = array_type_nelts (type); - if (error_operand_p (nelts)) + tree nelts_minus_one = array_type_nelts_minus_one (type); + if (error_operand_p (nelts_minus_one)) return attrs; - if (TREE_CODE (nelts) != INTEGER_CST) + if (TREE_CODE (nelts_minus_one) != INTEGER_CST) { /* Each variable VLA bound is represented by the dollar sign. */ spec += "$"; - tpbnds = tree_cons (NULL_TREE, nelts, tpbnds); + tpbnds = tree_cons (NULL_TREE, nelts_minus_one, tpbnds); } } tpbnds = nreverse (tpbnds); diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc index 57b67c74bd8..9ea174f79c4 100644 --- a/gcc/c/c-fold.cc +++ b/gcc/c/c-fold.cc @@ -73,11 +73,12 @@ c_fold_array_ref (tree type, tree ary, tree index) unsigned elem_nchars = (TYPE_PRECISION (elem_type) / TYPE_PRECISION (char_type_node)); unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars; - tree nelts = array_type_nelts (TREE_TYPE (ary)); + tree nelts_minus_one = array_type_nelts_minus_one (TREE_TYPE (ary)); bool dummy1 = true, dummy2 = true; - nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false); + nelts_minus_one = c_fully_fold_internal (nelts_minus_one, true, &dummy1, + &dummy2, false, false); unsigned HOST_WIDE_INT i = tree_to_uhwi (index); - if (!tree_int_cst_le (index, nelts) + if (!tree_int_cst_le (index, nelts_minus_one) || i >= len || i + elem_nchars > len) return NULL_TREE; diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 0d41a193ec1..eaef2a0e985 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -1082,7 +1082,7 @@ pure_scalable_type_info::analyze_array (const_tree type) /* An array of unknown, flexible or variable length will be passed and returned by reference whatever we do. */ - tree nelts_minus_one = array_type_nelts (type); + tree nelts_minus_one = array_type_nelts_minus_one (type); if (!tree_fits_uhwi_p (nelts_minus_one)) return DOESNT_MATTER; diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 9c2ebe74fc9..298d8c9131a 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -24519,7 +24519,7 @@ ix86_canonical_va_list_type (tree type) return ms_va_list_type_node; if ((TREE_CODE (type) == ARRAY_TYPE - && integer_zerop (array_type_nelts (type))) + && integer_zerop (array_type_nelts_minus_one (type))) || POINTER_TYPE_P (type)) { tree elem_type = TREE_TYPE (type); diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index e7bb4fa3089..fc3e28c4dec 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -6936,7 +6936,7 @@ reshape_init_array (tree type, reshape_iter *d, tree first_initializer_p, gcc_assert (TREE_CODE (type) == ARRAY_TYPE); if (TYPE_DOMAIN (type)) - max_index = array_type_nelts (type); + max_index = array_type_nelts_minus_one (type); return reshape_init_array_1 (TREE_TYPE (type), max_index, d, first_initializer_p, complain); diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index e9561c146d7..4558151b4c2 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -260,7 +260,7 @@ build_zero_init_1 (tree type, tree nelts, bool static_storage_p, else if (TYPE_DOMAIN (type) == NULL_TREE) return NULL_TREE; else - max_index = array_type_nelts (type); + max_index = array_type_nelts_minus_one (type); /* If we have an error_mark here, we should just return error mark as we don't know the size of the array yet. */ @@ -471,7 +471,7 @@ build_value_init_noctor (tree type, tsubst_flags_t complain) vec *v = NULL; /* Iterate over the array elements, building initializations. */ - tree max_index = array_type_nelts (type); + tree max_index = array_type_nelts_minus_one (type); /* If we have an error_mark here, we should just return error mark as we don't know the size of the array yet. */ @@ -4516,7 +4516,7 @@ build_vec_init (tree base, tree maxindex, tree init, : location_of (base)); if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype)) - maxindex = array_type_nelts (atype); + maxindex = array_type_nelts_minus_one (atype); if (maxindex == NULL_TREE || maxindex == error_mark_node) return error_mark_node; @@ -5172,7 +5172,7 @@ build_delete (location_t loc, tree otype, tree addr, error_at (loc, "unknown array size in delete"); return error_mark_node; } - return build_vec_delete (loc, addr, array_type_nelts (type), + return build_vec_delete (loc, addr, array_type_nelts_minus_one (type), auto_delete, use_global_delete, complain); } diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index 0770417810e..065113bc122 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -556,7 +556,8 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, integer_zero_node, tf_warning_or_error); initializer = build_constructor_va (init_list_type_node, 2, NULL_TREE, build_address (elt), - NULL_TREE, array_type_nelts (type)); + NULL_TREE, + array_type_nelts_minus_one (type)); type = vla_capture_type (type); } else if (!dependent_type_p (type) diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index dfd4a3a948b..3baeb8fa252 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -3080,7 +3080,7 @@ array_type_nelts_top (tree type) { return fold_build2_loc (input_location, PLUS_EXPR, sizetype, - array_type_nelts (type), + array_type_nelts_minus_one (type), size_one_node); } diff --git a/gcc/expr.cc b/gcc/expr.cc index ffbac513692..cba8b365856 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -6970,14 +6970,14 @@ count_type_elements (const_tree type, bool for_ctor_p) { case ARRAY_TYPE: { - tree nelts; + tree nelts_minus_one; - nelts = array_type_nelts (type); - if (nelts && tree_fits_uhwi_p (nelts)) + nelts_minus_one = array_type_nelts_minus_one (type); + if (nelts_minus_one && tree_fits_uhwi_p (nelts_minus_one)) { unsigned HOST_WIDE_INT n; - n = tree_to_uhwi (nelts) + 1; + n = tree_to_uhwi (nelts_minus_one) + 1; if (n == 0 || for_ctor_p) return n; else diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index 140d933e45d..b7927bcdf01 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -9572,7 +9572,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest, else { /* Otherwise use the TYPE_DOMAIN information. */ - tmp = array_type_nelts (decl_type); + tmp = array_type_nelts_minus_one (decl_type); tmp = fold_convert (gfc_array_index_type, tmp); } diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index df1bf144e23..14cd2f9fad7 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -582,7 +582,7 @@ gfc_walk_alloc_comps (tree decl, tree dest, tree var, tem = size_binop (MINUS_EXPR, tem, size_one_node); } else - tem = array_type_nelts (type); + tem = array_type_nelts_minus_one (type); tem = fold_convert (gfc_array_index_type, tem); } @@ -1309,7 +1309,7 @@ gfc_omp_clause_linear_ctor (tree clause, tree dest, tree src, tree add) nelems = size_binop (MINUS_EXPR, nelems, size_one_node); } else - nelems = array_type_nelts (type); + nelems = array_type_nelts_minus_one (type); nelems = fold_convert (gfc_array_index_type, nelems); gfc_omp_linear_clause_add_loop (&block, dest, src, add, nelems); diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc index 2a5ffcbf895..a2c12204667 100644 --- a/gcc/rust/backend/rust-tree.cc +++ b/gcc/rust/backend/rust-tree.cc @@ -869,7 +869,7 @@ tree array_type_nelts_top (tree type) { return fold_build2_loc (input_location, PLUS_EXPR, sizetype, - array_type_nelts (type), size_one_node); + array_type_nelts_minus_one (type), size_one_node); } // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p diff --git a/gcc/tree.cc b/gcc/tree.cc index 2d2d5b6db6e..dcaccc4c362 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -3698,7 +3698,7 @@ int_byte_position (const_tree field) ARRAY_TYPE) minus one. This counts only elements of the top array. */ tree -array_type_nelts (const_tree type) +array_type_nelts_minus_one (const_tree type) { tree index_type, min, max; @@ -14797,7 +14797,7 @@ is_empty_type (const_tree type) return true; } else if (TREE_CODE (type) == ARRAY_TYPE) - return (integer_minus_onep (array_type_nelts (type)) + return (integer_minus_onep (array_type_nelts_minus_one (type)) || TYPE_DOMAIN (type) == NULL_TREE || is_empty_type (TREE_TYPE (type))); return false; diff --git a/gcc/tree.h b/gcc/tree.h index 28e8e71b036..fdddbcf408e 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4921,7 +4921,7 @@ extern tree build_method_type_directly (tree, tree, tree); extern tree build_method_type (tree, tree); extern tree build_offset_type (tree, tree); extern tree build_complex_type (tree, bool named = false); -extern tree array_type_nelts (const_tree); +extern tree array_type_nelts_minus_one (const_tree); extern tree value_member (tree, tree); extern tree purpose_member (const_tree, tree); From patchwork Sat Aug 3 23:17:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Colomar X-Patchwork-Id: 95261 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 787CC3858C53 for ; Sat, 3 Aug 2024 23:18:06 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by sourceware.org (Postfix) with ESMTPS id 942583858C78 for ; Sat, 3 Aug 2024 23:17:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 942583858C78 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kernel.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 942583858C78 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=139.178.84.217 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722727041; cv=none; b=JO3u4R90NAYBkRhp85JhtVU4JcsgBRUpKKNpBUHTu++H2SxQRlQODmp+V1Vlum3qIi+Ig8MZQ7HuwBuI/hd1YOAAtdinuJvo6EmwwbzCpunvWl2QNPZCidEJKwhR+f7GNjyYP/qXT0vBcAjOkMFHrEm5QdDM6j4PJ1y+xvJ3yA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722727041; c=relaxed/simple; bh=3w6mpIfqnEwD2Rm0BXRvnnXbNP1evb4T0SQu2W2CfrU=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=O4bTtrddOwpp7/QH2HwNgtyKS0pbWsoLqXYPNZw2AcpiY5P17VW2iRItspzwesc4salpS7CG8TyP/Fv71PfyhZhM7xkwN+kf0POiy9TpUqa22xbsOJgi4vvlGT982Pe1GB1dJVxnI3vO1+68DBp37z3SorsM2MDgmbgl0DV01PA= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 3FA6E60BC7; Sat, 3 Aug 2024 23:17:18 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7B0DBC116B1; Sat, 3 Aug 2024 23:17:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722727037; bh=3w6mpIfqnEwD2Rm0BXRvnnXbNP1evb4T0SQu2W2CfrU=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=qjNaKwcX0a8r+zRev6G8gIdZdVEORm950JFHbnkIgAUlhQ0HSXcqMTaFXzQkxlyTH pN4Ugap9vSiWjwy2JG1DGr1emQq31Zs4wn18Uw3xY0tjn1aXswul25NsNhEHZQXXr2 00T0VOr3HfzTSMAeT0f0TLysBrLsq/7EVsW14pDyXrZnDI11qr9I4TU8BKsPpr8BY+ eK5Ad+fgbZ92DB2SIUIH48sJTEyB+CCP7KtWi8lk9JbsQU5VMnlkDeZzQez5XTWniW O69YzJTcAxqMrtFQnniad1I+jPh9HeQEV9N/CkRsn8NxAewdUcJ9aTL/2iPOPuU8OT 9Qg90pSLcXGOQ== Date: Sun, 4 Aug 2024 01:17:14 +0200 From: Alejandro Colomar To: gcc-patches@gcc.gnu.org Cc: Alejandro Colomar , Xavier Del Campo Romero , Gabriel Ravier , Martin Uecker , Joseph Myers , Jakub Jelinek Subject: [RFC v3 2/3] Merge definitions of array_type_nelts_top() Message-ID: <20240803231702.89150-3-alx@kernel.org> X-Mailer: git-send-email 2.45.2 References: <20240728141547.302478-1-alx@kernel.org> <20240803231702.89150-1-alx@kernel.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20240803231702.89150-1-alx@kernel.org> X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org There were two identical definitions, and none of them are available where they are needed for implementing __lengthof__(). Merge them, and provide the single definition in gcc/tree.{h,cc}, where it's available for __lengthof__(). Signed-off-by: Alejandro Colomar --- gcc/cp/cp-tree.h | 1 - gcc/cp/tree.cc | 13 ------------- gcc/rust/backend/rust-tree.cc | 13 ------------- gcc/rust/backend/rust-tree.h | 2 -- gcc/tree.cc | 13 +++++++++++++ gcc/tree.h | 1 + 6 files changed, 14 insertions(+), 29 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c1a371bc721..e6c1c63f872 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8099,7 +8099,6 @@ extern tree build_exception_variant (tree, tree); extern void fixup_deferred_exception_variants (tree, tree); extern tree bind_template_template_parm (tree, tree); extern tree array_type_nelts_total (tree); -extern tree array_type_nelts_top (tree); extern bool array_of_unknown_bound_p (const_tree); extern tree break_out_target_exprs (tree, bool = false); extern tree build_ctor_subob_ref (tree, tree, tree); diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 3baeb8fa252..1f3ecff1a21 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -3071,19 +3071,6 @@ cxx_print_statistics (void) depth_reached); } -/* Return, as an INTEGER_CST node, the number of elements for TYPE - (which is an ARRAY_TYPE). This counts only elements of the top - array. */ - -tree -array_type_nelts_top (tree type) -{ - return fold_build2_loc (input_location, - PLUS_EXPR, sizetype, - array_type_nelts_minus_one (type), - size_one_node); -} - /* Return, as an INTEGER_CST node, the number of elements for TYPE (which is an ARRAY_TYPE). This one is a recursive count of all ARRAY_TYPEs that are clumped together. */ diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc index a2c12204667..dd8eda84f9b 100644 --- a/gcc/rust/backend/rust-tree.cc +++ b/gcc/rust/backend/rust-tree.cc @@ -859,19 +859,6 @@ is_empty_class (tree type) return CLASSTYPE_EMPTY_P (type); } -// forked from gcc/cp/tree.cc array_type_nelts_top - -/* Return, as an INTEGER_CST node, the number of elements for TYPE - (which is an ARRAY_TYPE). This counts only elements of the top - array. */ - -tree -array_type_nelts_top (tree type) -{ - return fold_build2_loc (input_location, PLUS_EXPR, sizetype, - array_type_nelts_minus_one (type), size_one_node); -} - // forked from gcc/cp/tree.cc builtin_valid_in_constant_expr_p /* Test whether DECL is a builtin that may appear in a diff --git a/gcc/rust/backend/rust-tree.h b/gcc/rust/backend/rust-tree.h index 26c8b653ac6..e597c3ab81d 100644 --- a/gcc/rust/backend/rust-tree.h +++ b/gcc/rust/backend/rust-tree.h @@ -2993,8 +2993,6 @@ extern location_t rs_expr_location (const_tree); extern int is_empty_class (tree type); -extern tree array_type_nelts_top (tree); - extern bool is_really_empty_class (tree, bool); diff --git a/gcc/tree.cc b/gcc/tree.cc index dcaccc4c362..cbbc7627ad6 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -3729,6 +3729,19 @@ array_type_nelts_minus_one (const_tree type) ? max : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min)); } + +/* Return, as an INTEGER_CST node, the number of elements for TYPE + (which is an ARRAY_TYPE). This counts only elements of the top + array. */ + +tree +array_type_nelts_top (tree type) +{ + return fold_build2_loc (input_location, + PLUS_EXPR, sizetype, + array_type_nelts_minus_one (type), + size_one_node); +} /* If arg is static -- a reference to an object in static storage -- then return the object. This is not the same as the C meaning of `static'. diff --git a/gcc/tree.h b/gcc/tree.h index fdddbcf408e..a6c46440b1a 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4922,6 +4922,7 @@ extern tree build_method_type (tree, tree); extern tree build_offset_type (tree, tree); extern tree build_complex_type (tree, bool named = false); extern tree array_type_nelts_minus_one (const_tree); +extern tree array_type_nelts_top (tree); extern tree value_member (tree, tree); extern tree purpose_member (const_tree, tree); From patchwork Sat Aug 3 23:17:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alejandro Colomar X-Patchwork-Id: 95262 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 65963385C6D1 for ; Sat, 3 Aug 2024 23:18:11 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by sourceware.org (Postfix) with ESMTPS id DD3EB385C6D1 for ; Sat, 3 Aug 2024 23:17:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DD3EB385C6D1 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kernel.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DD3EB385C6D1 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=139.178.84.217 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722727046; cv=none; b=Xiw5BgP/20GajIdjqob5//ccDiD/jFvwyn2ViUbZbuHTFeQ++2qTfXOABd3r9LoYyc0zuLVybSh79WzCvpBjRXArpsHDgi3u4mnQSwwAcPlJpVRj2uHfBn5eP9LR5rjRN5h6AWSCdPbCxxSIR+ZAm412sIHVL+E+3nmMC8Wi84M= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722727046; c=relaxed/simple; bh=mzBWfL0QgS2lxSuSmbCOKNtphfaS/66PvxpMHP4PByQ=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=QmOUykkhom3scLF03a3fZzXhQcxnbPxLD9tr2f8XWdVfmqpMEwgmKccKPuZbBvDQkPY2YBDht+JsOFOGHjSgeS1vnD6jqAMKGz7Fb3oPJRMq6lqK9lar6XWii7QyW39/9nzYpQDCt7URYEwVKIgi1aMkVpXJHyJ2f+1iZlu+OM0= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 76F3960BC6; Sat, 3 Aug 2024 23:17:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B227AC116B1; Sat, 3 Aug 2024 23:17:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1722727042; bh=mzBWfL0QgS2lxSuSmbCOKNtphfaS/66PvxpMHP4PByQ=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=SCJKtAd+PdYV7EZYgAanxjmPyCoaZZmymmw5OsOW+SsYDc0VPe78tHD1Ul+ETb1++ +9mJ9viH5guBX9pYnqavki94+nad2PHSdFQPLrckM1WPz0MZl4MTVLrAZW8cLFGCWy +zK2nMWw3yqEaElH7be6cV/lkR/DIZcSyGDI2K/CzPpIe0zNyb/c+f3dYb8RbWOzmR DeZoOSY7OT+RXWQ4lBueqAK8dpmiVZQEfqgG0Rx7HvIaSZfPKLhSRaZCakfJKTV6+t q65kp8dBxcjZ28K89lHr14RlCZEwiXrbB02S8tCWdgeTwdO3GcbpG+61CvdtNMFfXC oXAciG5VO1p8w== Date: Sun, 4 Aug 2024 01:17:19 +0200 From: Alejandro Colomar To: gcc-patches@gcc.gnu.org Cc: Alejandro Colomar , Xavier Del Campo Romero , Gabriel Ravier , Martin Uecker , Joseph Myers , Jakub Jelinek Subject: [RFC v3 3/3] c: Add __lengthof__() operator Message-ID: <20240803231702.89150-4-alx@kernel.org> X-Mailer: git-send-email 2.45.2 References: <20240728141547.302478-1-alx@kernel.org> <20240803231702.89150-1-alx@kernel.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20240803231702.89150-1-alx@kernel.org> X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org This operator is similar to sizeof() but can only be applied to an array, and returns its length (number of elements). TO BE DECIDED BEFORE MERGING: It would be better to not evaluate the operand if the top-level array is not a VLA. FUTURE DIRECTIONS: We could make it work with array parameters to functions, and somehow magically return the length designator of the array, regardless of it being really a pointer. Link: Cc: Xavier Del Campo Romero Cc: Gabriel Ravier Cc: Martin Uecker Cc: Joseph Myers Cc: Jakub Jelinek Signed-off-by: Alejandro Colomar --- gcc/c-family/c-common.cc | 26 +++++++++++ gcc/c-family/c-common.def | 3 ++ gcc/c-family/c-common.h | 2 + gcc/c/c-decl.cc | 20 ++++++--- gcc/c/c-parser.cc | 61 +++++++++++++++++++------ gcc/c/c-tree.h | 4 ++ gcc/c/c-typeck.cc | 95 +++++++++++++++++++++++++++++++++++++-- gcc/cp/operators.def | 1 + gcc/doc/extend.texi | 12 +++++ gcc/target.h | 3 ++ 10 files changed, 203 insertions(+), 24 deletions(-) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index e7e371fd26f..91793dfbffc 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -465,6 +465,7 @@ const struct c_common_resword c_common_reswords[] = { "__inline", RID_INLINE, 0 }, { "__inline__", RID_INLINE, 0 }, { "__label__", RID_LABEL, 0 }, + { "__lengthof__", RID_LENGTHOF, 0 }, { "__null", RID_NULL, 0 }, { "__real", RID_REALPART, 0 }, { "__real__", RID_REALPART, 0 }, @@ -4070,6 +4071,31 @@ c_alignof_expr (location_t loc, tree expr) return fold_convert_loc (loc, size_type_node, t); } + +/* Implement the lengthof keyword: Return the length of an array, + that is, the number of elements in the array. */ + +tree +c_lengthof_type (location_t loc, tree type) +{ + enum tree_code type_code; + + type_code = TREE_CODE (type); + if (!COMPLETE_TYPE_P (type)) + { + error_at (loc, + "invalid application of % to incomplete type %qT", + type); + return error_mark_node; + } + if (type_code != ARRAY_TYPE) + { + error_at (loc, "invalid application of % to type %qT", type); + return error_mark_node; + } + + return array_type_nelts_top (type); +} /* Handle C and C++ default attributes. */ diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def index 5de96e5d4a8..6d162f67104 100644 --- a/gcc/c-family/c-common.def +++ b/gcc/c-family/c-common.def @@ -50,6 +50,9 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", tcc_expression, 1) number. */ DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3) +/* Represents a 'lengthof' expression. */ +DEFTREECODE (LENGTHOF_EXPR, "lengthof_expr", tcc_expression, 1) + /* Represents a 'sizeof' expression during C++ template expansion, or for the purpose of -Wsizeof-pointer-memaccess warning. */ DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1) diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index ccaea27c2b9..f815a4cf3bc 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -105,6 +105,7 @@ enum rid /* C extensions */ RID_ASM, RID_TYPEOF, RID_TYPEOF_UNQUAL, RID_ALIGNOF, RID_ATTRIBUTE, + RID_LENGTHOF, RID_VA_ARG, RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR, RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, @@ -885,6 +886,7 @@ extern tree c_common_truthvalue_conversion (location_t, tree); extern void c_apply_type_quals_to_decl (int, tree); extern tree c_sizeof_or_alignof_type (location_t, tree, bool, bool, int); extern tree c_alignof_expr (location_t, tree); +extern tree c_lengthof_type (location_t, tree); /* Print an error message for invalid operands to arith operation CODE. NOP_EXPR is used as a special case (see truthvalue_conversion). */ extern void binary_op_error (rich_location *, enum tree_code, tree, tree); diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 4dced430d1f..790c58b2558 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -8937,12 +8937,16 @@ start_struct (location_t loc, enum tree_code code, tree name, within a statement expr used within sizeof, et. al. This is not terribly serious as C++ doesn't permit statement exprs within sizeof anyhow. */ - if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof)) + if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof || in_lengthof)) warning_at (loc, OPT_Wc___compat, "defining type in %qs expression is invalid in C++", (in_sizeof ? "sizeof" - : (in_typeof ? "typeof" : "alignof"))); + : (in_typeof + ? "typeof" + : (in_alignof + ? "alignof" + : "lengthof")))); if (in_underspecified_init) error_at (loc, "%qT defined in underspecified object initializer", ref); @@ -9897,7 +9901,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, struct_types. */ if (warn_cxx_compat && struct_parse_info != NULL - && !in_sizeof && !in_typeof && !in_alignof) + && !in_sizeof && !in_typeof && !in_alignof && !in_lengthof) struct_parse_info->struct_types.safe_push (t); } @@ -10071,12 +10075,16 @@ start_enum (location_t loc, struct c_enum_contents *the_enum, tree name, /* FIXME: This will issue a warning for a use of a type defined within sizeof in a statement expr. This is not terribly serious as C++ doesn't permit statement exprs within sizeof anyhow. */ - if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof)) + if (warn_cxx_compat && (in_sizeof || in_typeof || in_alignof || in_lengthof)) warning_at (loc, OPT_Wc___compat, "defining type in %qs expression is invalid in C++", (in_sizeof ? "sizeof" - : (in_typeof ? "typeof" : "alignof"))); + : (in_typeof + ? "typeof" + : (in_alignof + ? "alignof" + : "lengthof")))); if (in_underspecified_init) error_at (loc, "%qT defined in underspecified object initializer", @@ -10270,7 +10278,7 @@ finish_enum (tree enumtype, tree values, tree attributes) struct_types. */ if (warn_cxx_compat && struct_parse_info != NULL - && !in_sizeof && !in_typeof && !in_alignof) + && !in_sizeof && !in_typeof && !in_alignof && !in_lengthof) struct_parse_info->struct_types.safe_push (enumtype); /* Check for consistency with previous definition */ diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 12c5ed5d92c..09bb19f9299 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -74,7 +74,17 @@ along with GCC; see the file COPYING3. If not see #include "bitmap.h" #include "analyzer/analyzer-language.h" #include "toplev.h" + +#define c_parser_sizeof_expression(parser) \ +( \ + c_parser_sizeof_or_lengthof_expression (parser, RID_SIZEOF) \ +) +#define c_parser_lengthof_expression(parser) \ +( \ + c_parser_sizeof_or_lengthof_expression (parser, RID_LENGTHOF) \ +) + /* We need to walk over decls with incomplete struct/union/enum types after parsing the whole translation unit. In finish_decl(), if the decl is static, has incomplete @@ -1687,7 +1697,7 @@ static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *, tree); static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *); static struct c_expr c_parser_unary_expression (c_parser *); -static struct c_expr c_parser_sizeof_expression (c_parser *); +static struct c_expr c_parser_sizeof_or_lengthof_expression (c_parser *, enum rid); static struct c_expr c_parser_alignof_expression (c_parser *); static struct c_expr c_parser_postfix_expression (c_parser *); static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *, @@ -9864,6 +9874,8 @@ c_parser_unary_expression (c_parser *parser) case CPP_KEYWORD: switch (c_parser_peek_token (parser)->keyword) { + case RID_LENGTHOF: + return c_parser_lengthof_expression (parser); case RID_SIZEOF: return c_parser_sizeof_expression (parser); case RID_ALIGNOF: @@ -9903,12 +9915,13 @@ c_parser_unary_expression (c_parser *parser) /* Parse a sizeof expression. */ static struct c_expr -c_parser_sizeof_expression (c_parser *parser) +c_parser_sizeof_or_lengthof_expression (c_parser *parser, enum rid rid) { + const char *op_name = (rid == RID_LENGTHOF) ? "lengthof" : "sizeof"; struct c_expr expr; struct c_expr result; location_t expr_loc; - gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF)); + gcc_assert (c_parser_next_token_is_keyword (parser, rid)); location_t start; location_t finish = UNKNOWN_LOCATION; @@ -9917,7 +9930,10 @@ c_parser_sizeof_expression (c_parser *parser) c_parser_consume_token (parser); c_inhibit_evaluation_warnings++; - in_sizeof++; + if (rid == RID_LENGTHOF) + in_lengthof++; + else + in_sizeof++; if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser))) { @@ -9936,7 +9952,10 @@ c_parser_sizeof_expression (c_parser *parser) { struct c_expr ret; c_inhibit_evaluation_warnings--; - in_sizeof--; + if (rid == RID_LENGTHOF) + in_lengthof--; + else + in_sizeof--; ret.set_error (); ret.original_code = ERROR_MARK; ret.original_type = NULL; @@ -9948,31 +9967,45 @@ c_parser_sizeof_expression (c_parser *parser) type_name, expr_loc); finish = expr.get_finish (); - goto sizeof_expr; + goto Xof_expr; } /* sizeof ( type-name ). */ if (scspecs) - error_at (expr_loc, "storage class specifier in %"); + error_at (expr_loc, "storage class specifier in %qs", op_name); if (type_name->specs->alignas_p) error_at (type_name->specs->locations[cdw_alignas], - "alignment specified for type name in %"); + "alignment specified for type name in %qs", op_name); c_inhibit_evaluation_warnings--; - in_sizeof--; - result = c_expr_sizeof_type (expr_loc, type_name); + if (rid == RID_LENGTHOF) + { + in_lengthof--; + result = c_expr_lengthof_type (expr_loc, type_name); + } + else + { + in_sizeof--; + result = c_expr_sizeof_type (expr_loc, type_name); + } } else { expr_loc = c_parser_peek_token (parser)->location; expr = c_parser_unary_expression (parser); finish = expr.get_finish (); - sizeof_expr: + Xof_expr: c_inhibit_evaluation_warnings--; - in_sizeof--; + if (rid == RID_LENGTHOF) + in_lengthof--; + else + in_sizeof--; mark_exp_read (expr.value); if (TREE_CODE (expr.value) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) - error_at (expr_loc, "% applied to a bit-field"); - result = c_expr_sizeof_expr (expr_loc, expr); + error_at (expr_loc, "%qs applied to a bit-field", op_name); + if (rid == RID_LENGTHOF) + result = c_expr_lengthof_expr (expr_loc, expr); + else + result = c_expr_sizeof_expr (expr_loc, expr); } if (finish == UNKNOWN_LOCATION) finish = start; diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 15da875a029..102fcfefea6 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -736,6 +736,7 @@ extern int c_type_dwarf_attribute (const_tree, int); /* in c-typeck.cc */ extern int in_alignof; extern int in_sizeof; +extern int in_lengthof; extern int in_typeof; extern bool c_in_omp_for; extern bool c_omp_array_section_p; @@ -786,6 +787,9 @@ extern tree build_external_ref (location_t, tree, bool, tree *); extern void pop_maybe_used (bool); extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr); extern struct c_expr c_expr_sizeof_type (location_t, struct c_type_name *); +extern struct c_expr c_expr_lengthof_expr (location_t, struct c_expr); +extern struct c_expr c_expr_lengthof_type (location_t loc, + struct c_type_name *); extern struct c_expr parser_build_unary_op (location_t, enum tree_code, struct c_expr); extern struct c_expr parser_build_binary_op (location_t, diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 7e0f01ed22b..121e74de25d 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -71,6 +71,9 @@ int in_alignof; /* The level of nesting inside "sizeof". */ int in_sizeof; +/* The level of nesting inside "sizeof". */ +int in_lengthof; + /* The level of nesting inside "typeof". */ int in_typeof; @@ -3255,7 +3258,7 @@ build_external_ref (location_t loc, tree id, bool fun, tree *type) if (TREE_CODE (ref) == FUNCTION_DECL && !in_alignof) { - if (!in_sizeof && !in_typeof) + if (!in_sizeof && !in_typeof && !in_lengthof) C_DECL_USED (ref) = 1; else if (DECL_INITIAL (ref) == NULL_TREE && DECL_EXTERNAL (ref) @@ -3311,7 +3314,7 @@ struct maybe_used_decl { /* The decl. */ tree decl; - /* The level seen at (in_sizeof + in_typeof). */ + /* The level seen at (in_sizeof + in_typeof + in_lengthof). */ int level; /* The next one at this level or above, or NULL. */ struct maybe_used_decl *next; @@ -3329,7 +3332,7 @@ record_maybe_used_decl (tree decl) { struct maybe_used_decl *t = XOBNEW (&parser_obstack, struct maybe_used_decl); t->decl = decl; - t->level = in_sizeof + in_typeof; + t->level = in_sizeof + in_typeof + in_lengthof; t->next = maybe_used_decls; maybe_used_decls = t; } @@ -3343,7 +3346,7 @@ void pop_maybe_used (bool used) { struct maybe_used_decl *p = maybe_used_decls; - int cur_level = in_sizeof + in_typeof; + int cur_level = in_sizeof + in_typeof + in_lengthof; while (p && p->level > cur_level) { if (used) @@ -3453,6 +3456,90 @@ c_expr_sizeof_type (location_t loc, struct c_type_name *t) return ret; } +/* Return the result of lengthof applied to EXPR. */ + +struct c_expr +c_expr_lengthof_expr (location_t loc, struct c_expr expr) +{ + struct c_expr ret; + if (expr.value == error_mark_node) + { + ret.value = error_mark_node; + ret.original_code = ERROR_MARK; + ret.original_type = NULL; + ret.m_decimal = 0; + pop_maybe_used (false); + } + else + { + bool expr_const_operands = true; + + tree folded_expr = c_fully_fold (expr.value, require_constant_value, + &expr_const_operands); + ret.value = c_lengthof_type (loc, TREE_TYPE (folded_expr)); + c_last_sizeof_arg = expr.value; + c_last_sizeof_loc = loc; + ret.original_code = LENGTHOF_EXPR; + ret.original_type = NULL; + ret.m_decimal = 0; + if (C_TYPE_VARIABLE_SIZE (TREE_TYPE (folded_expr))) + { + /* lengthof is evaluated when given a vla. */ + ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value), + folded_expr, ret.value); + C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !expr_const_operands; + SET_EXPR_LOCATION (ret.value, loc); + } + pop_maybe_used (C_TYPE_VARIABLE_SIZE (TREE_TYPE (folded_expr))); + } + return ret; +} + +/* Return the result of lengthof applied to T, a structure for the type + name passed to _lengthof (rather than the type itself). LOC is the + location of the original expression. */ + +struct c_expr +c_expr_lengthof_type (location_t loc, struct c_type_name *t) +{ + tree type; + struct c_expr ret; + tree type_expr = NULL_TREE; + bool type_expr_const = true; + type = groktypename (t, &type_expr, &type_expr_const); + ret.value = c_lengthof_type (loc, type); + c_last_sizeof_arg = type; + c_last_sizeof_loc = loc; + ret.original_code = LENGTHOF_EXPR; + ret.original_type = NULL; + ret.m_decimal = 0; + if (type == error_mark_node) + { + ret.value = error_mark_node; + ret.original_code = ERROR_MARK; + } + else + if ((type_expr || TREE_CODE (ret.value) == INTEGER_CST) + && C_TYPE_VARIABLE_SIZE (type)) + { + /* If the type is a [*] array, it is a VLA but is represented as + having a size of zero. In such a case we must ensure that + the result of lengthof does not get folded to a constant by + c_fully_fold, because if the length is evaluated the result is + not constant and so constraints on zero or negative size + arrays must not be applied when this lengthof call is inside + another array declarator. */ + if (!type_expr) + type_expr = integer_zero_node; + ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value), + type_expr, ret.value); + C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !type_expr_const; + } + pop_maybe_used (type != error_mark_node + ? C_TYPE_VARIABLE_SIZE (type) : false); + return ret; +} + /* Build a function call to function FUNCTION with parameters PARAMS. The function call is at LOC. PARAMS is a list--a chain of TREE_LIST nodes--in which the diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def index d8878923602..d640ed8bd91 100644 --- a/gcc/cp/operators.def +++ b/gcc/cp/operators.def @@ -91,6 +91,7 @@ DEF_OPERATOR ("co_await", CO_AWAIT_EXPR, "aw", OVL_OP_FLAG_UNARY) /* These are extensions. */ DEF_OPERATOR ("alignof", ALIGNOF_EXPR, "az", OVL_OP_FLAG_UNARY) +DEF_OPERATOR ("__lengthof__", LENGTHOF_EXPR, "lz", OVL_OP_FLAG_UNARY) DEF_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", OVL_OP_FLAG_UNARY) DEF_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", OVL_OP_FLAG_UNARY) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 0b572afca72..4d6066f8acd 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -10391,6 +10391,18 @@ If the operand of the @code{__alignof__} expression is a function, the expression evaluates to the alignment of the function which may be specified by attribute @code{aligned} (@pxref{Common Function Attributes}). +@node Length +@section Determining the Length of Arrays +@cindex length +@cindex array length + +The keyword @code{__lengthof__} determines the length of an array operand, +that is, the number of elements in the array. +Its syntax is just like @code{sizeof}, +and the operand is evaluated following the same rules. +(TODO: We probably want to restrict evaluation to top-level VLAs only. + This documentation describes the current implementation.) + @node Inline @section An Inline Function is As Fast As a Macro @cindex inline functions diff --git a/gcc/target.h b/gcc/target.h index c1f99b97b86..79890ae9944 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -245,6 +245,9 @@ enum type_context_kind { /* Directly measuring the alignment of T. */ TCTX_ALIGNOF, + /* Directly measuring the length of array T. */ + TCTX_LENGTHOF, + /* Creating objects of type T with static storage duration. */ TCTX_STATIC_STORAGE,