From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from rock.gnat.com (rock.gnat.com [205.232.38.15]) by sourceware.org (Postfix) with ESMTPS id C05403951878 for ; Thu, 17 Jun 2021 14:33:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C05403951878 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 897E8561BF; Thu, 17 Jun 2021 10:33:11 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id AbOWcJyg55E4; Thu, 17 Jun 2021 10:33:11 -0400 (EDT) Received: from tron.gnat.com (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) by rock.gnat.com (Postfix) with ESMTP id 6C7AF561BE; Thu, 17 Jun 2021 10:33:11 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4862) id 66B71A3; Thu, 17 Jun 2021 10:33:11 -0400 (EDT) Date: Thu, 17 Jun 2021 10:33:11 -0400 From: Pierre-Marie de Rodat To: gcc-patches@gcc.gnu.org Cc: Gary Dismukes Subject: [Ada] Implementation of Inox feature of fixed lower bounds on array types/subtypes Message-ID: <20210617143311.GA10718@adacore.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="7AUc2qLy4jB3hD7Z" Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Spam-Status: No, score=-6.6 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 Jun 2021 14:33:18 -0000 --7AUc2qLy4jB3hD7Z Content-Type: text/plain; charset=us-ascii Content-Disposition: inline This is a prototype implementation of the feature for defining array types and subtypes with fixed lower bounds for index ranges as proposed as part of the "Inox" language design effort. This feature is currently supported under control of the -gnatX (language extensions) switch, and allows unconstrained array types as well as unconstrained subtypes to be declared with indexes that use the special syntax "expression .. <>", to indicate that the lower bound of the array type or subtype is fixed at a value given by an expression. In contexts such as actual parameters, object declarations, return statements, and type conversions, if the context is such an unconstrained array subtype with a fixed lower bound, bounds sliding is performed. Also, in certain contexts, such as index constraints, consistency of the range imposed by the constraint with the fixed lower bound of the array type being constrained is enforced. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * checks.adb (Discrete_Range_Cond): For an index subtype that has a fixed lower bound, require that the range's lower bound match that of the subtype. (Selected_Range_Checks): Warn about the case where a static lower bound does not equal an index subtype's fixed lower bound. * einfo.ads (Is_Fixed_Lower_Bound_Array_Subtype, Is_Fixed_Lower_Bound_Index_Subtype): Document new entity flag. * exp_ch4.adb (Expand_N_Type_Conversion): If the operand is of an unconstrained array subtype with fixed lower bound, then Expand_Sliding_Conversion is applied to the operand. * exp_ch6.adb (Expand_Simple_Function_Return): If the result subtype is an unconstrained array subtype with fixed lower bound, then Expand_Sliding_Conversion is applied to the return object. * exp_util.ads (Expand_Sliding_Conversion): New procedure for applying a sliding subtype conversion to an array object of a fixed-lower-bound subtype when needed. * exp_util.adb: Add with_clause for Freeze. (Expand_Sliding_Conversion): New procedure for applying a sliding subtype conversion to an array object of a fixed-lower-bound subtype when needed. It traverses the indexes of the unconstrained array type/subtype to create a target constrained subtype and rewrites the array object to be a conversion to that subtype, when there's at least one index whose lower bound does not statically match the fixed-lower bound of the target subtype. * gen_il-fields.ads (type Opt_Field_Enum): Add literals Is_Fixed_Lower_Bound_Array_Subtype and Is_Fixed_Lower_Bound_Index_Subtype for new flags on type entities. * gen_il-gen-gen_entities.adb: Add calls to Create_Semantic_Field for the new fixed-lower-bound flags on type entities. * par-ch3.adb (P_Array_Type_Definition): Add handling for parsing of fixed-lower-bound index ranges in unconstrained array types. Report an error if such an index is encountered and GNAT language extensions are not enabled. (P_Index_Subtype_Def_With_Fixed_Lower_Bound): Support procedure for parsing unconstrained index ranges. (P_Index_Or_Discriminant_Constraint): Add handling for parsing of index constraints that specify ranges with fixed lower bounds. Report an error if such an index is encountered and GNAT language extensions are not enabled. * sem_ch3.adb (Analyze_Object_Declaration): If the object's nominal subtype is an array subtype with fixed lower bound, then Expand_Sliding_Conversion is applied to the object. (Array_Type_Declaration): Mark the array type and the subtypes of any indexes that specify a fixed lower bound as being fixed-lower-bound subtypes, and set the High_bound of the range of such an index to the upper bound of the named subtype. (Constrain_Array): For an array subtype with one or more index ranges specifying a fixed lower bound, set Is_Constrained to False and set the array subtype's Is_Fixed_Lower_Bound_Array_Subtype flag to True. (Constrain_Index): Mark the subtypes of an index that specifies a fixed lower bound as being a fixed-lower-bound index subtype, and set the High_bound of the range of such an index to the upper bound of the base type of the array type's corresponding index. * sem_res.adb (Resolve_Actuals): If a formal is of an unconstrained array subtype with fixed lower bound, then Expand_Sliding_Conversion is applied to the actual. * sem_util.adb (Build_Actual_Subtype): If the actual subtype corresponds to an unconstrained array subtype having any indexes with fixed lower bounds, then set the lower bounds of any such indexes of the actual subtype to the appropriate fixed lower bound of the formal subtype (rather than taking it from the formal itself). * sprint.adb (Sprint_Node_Actual, case N_Range): If a range's Etype has a fixed lower bound, then print "<>" rather than the High_Bound of the range. --7AUc2qLy4jB3hD7Z Content-Type: application/gzip Content-Disposition: attachment; filename="patch.diff.gz" Content-Transfer-Encoding: base64 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 s/8GIN+3pNOGAAA= --7AUc2qLy4jB3hD7Z--