From 8dcefdc00380da344956659fdb05d9b9e1aa1c8c Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 9 Oct 2018 15:05:49 +0000 Subject: [PATCH] [Ada] Remove spurious -Wuninitialized warning for small array at -O2 2018-10-09 Eric Botcazou gcc/ada/ * gcc-interface/decl.c (type_requires_init_of_formal): New predicate. (gnat_to_gnu_param): Use it to determine whether a PARM_DECL must be created for an Out parameter passed by copy. From-SVN: r264971 --- gcc/ada/ChangeLog | 7 ++++ gcc/ada/gcc-interface/decl.c | 71 ++++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 41402f68b98..7f068b7e41e 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2018-10-09 Eric Botcazou + + * gcc-interface/decl.c (type_requires_init_of_formal): New + predicate. + (gnat_to_gnu_param): Use it to determine whether a PARM_DECL + must be created for an Out parameter passed by copy. + 2018-10-09 Arnaud Charlet * libgnat/a-coboho.ads (Storage_Element): Fix a typo. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 4a1845a33b6..ff87529790a 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -5129,6 +5129,43 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition, return gnu_type; } +/* Return whether TYPE requires that formal parameters of TYPE be initialized + when they are Out parameters passed by copy. + + This just implements the set of conditions listed in RM 6.4.1(12). */ + +static bool +type_requires_init_of_formal (Entity_Id type) +{ + type = Underlying_Type (type); + + if (Is_Access_Type (type)) + return true; + + if (Is_Scalar_Type (type)) + return Has_Default_Aspect (type); + + if (Is_Array_Type (type)) + return Has_Default_Aspect (type) + || type_requires_init_of_formal (Component_Type (type)); + + if (Is_Record_Type (type)) + for (Entity_Id field = First_Entity (type); + Present (field); + field = Next_Entity (field)) + { + if (Ekind (field) == E_Discriminant) + return true; + + if (Ekind (field) == E_Component + && (Present (Expression (Parent (field))) + || type_requires_init_of_formal (Etype (field)))) + return true; + } + + return false; +} + /* Return a GCC tree for a parameter corresponding to GNAT_PARAM, to be placed in the parameter list of GNAT_SUBPROG. GNU_PARAM_TYPE is the GCC tree for the type of the parameter. FIRST is true if this is the first parameter in @@ -5143,7 +5180,6 @@ static tree gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first, Entity_Id gnat_subprog, bool *cico) { - Entity_Id gnat_param_type = Etype (gnat_param); Mechanism_Type mech = Mechanism (gnat_param); tree gnu_param_name = get_entity_name (gnat_param); bool foreign = Has_Foreign_Convention (gnat_subprog); @@ -5295,34 +5331,15 @@ gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first, if (mech == By_Copy && (by_ref || by_component_ptr)) post_error ("?cannot pass & by copy", gnat_param); - /* If this is an Out parameter that isn't passed by reference and isn't - a pointer or aggregate, we don't make a PARM_DECL for it. Instead, - it will be a VAR_DECL created when we process the procedure, so just - return its type. For the special parameter of a valued procedure, - never pass it in. - - An exception is made to cover the RM-6.4.1 rule requiring "by copy" - Out parameters with discriminants or implicit initial values to be - handled like In Out parameters. These type are normally built as - aggregates, hence passed by reference, except for some packed arrays - which end up encoded in special integer types. Note that scalars can - be given implicit initial values using the Default_Value aspect. - - The exception we need to make is then for packed arrays of records - with discriminants or implicit initial values. We have no light/easy - way to check for the latter case, so we merely check for packed arrays - of records. This may lead to useless copy-in operations, but in very - rare cases only, as these would be exceptions in a set of already - exceptional situations. */ + /* If this is an Out parameter that isn't passed by reference and whose + type doesn't require the initialization of formals, we don't make a + PARM_DECL for it. Instead, it will be a VAR_DECL created when we + process the procedure, so just return its type here. Likewise for + the special parameter of a valued procedure, never pass it in. */ if (Ekind (gnat_param) == E_Out_Parameter && !by_ref - && (by_return - || (!POINTER_TYPE_P (gnu_param_type) - && !AGGREGATE_TYPE_P (gnu_param_type) - && !Has_Default_Aspect (gnat_param_type))) - && !(Is_Array_Type (gnat_param_type) - && Is_Packed (gnat_param_type) - && Is_Composite_Type (Component_Type (gnat_param_type)))) + && !by_component_ptr + && (!type_requires_init_of_formal (Etype (gnat_param)) || by_return)) return gnu_param_type; gnu_param = create_param_decl (gnu_param_name, gnu_param_type); -- 2.30.2