aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-10-09 15:06:55 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-10-09 15:06:55 +0000
commitc743425fce5517242dd67761fea298cd3459b4cc (patch)
tree8681015a93c746718344e21e388debb458823320 /gcc
parent4b9e1bc78110d65377acdf23ee3733f8c69baef9 (diff)
downloadgcc-c743425fce5517242dd67761fea298cd3459b4cc.zip
gcc-c743425fce5517242dd67761fea298cd3459b4cc.tar.gz
gcc-c743425fce5517242dd67761fea298cd3459b4cc.tar.bz2
[Ada] Fix spurious -Wuninitialized warnings for small records
This change is aimed at getting rid of spurious -Wuninitialized warnings issued for small records passed by copy and containing default values for some of their components. The source of the problem is that the _Init parameter of the initialization routine is declared as an in/out parameter, so the uninitialized object is passed by copy to it and this can be flagged by -Wuninitialized. That's why the mode of the parameter is changed to out, except for the cases where information really needs to be passed in: unconstrained array types, protected and task types. For the following record type Rec! type Rec is record B : Boolean := True; end record; the initialization routine must now be: procedure r__recIP (_init : out r__rec1) is begin _init.b := true; return; end r__recIP; 2018-10-09 Eric Botcazou <ebotcazou@adacore.com> gcc/ada/ * exp_ch3.adb (Is_Null_Statement_List): New predicate. (Build_Array_Init_Proc): Use it to find out whether the initialization procedure Is_Null_Init_Proc; if so, set Warnings_Off on the parameter. (Build_Init_Procedure): Likewise. (Init_Formals): Use an in/out first parameter only for unconstrained arrays and for records either containing or built for proteced types or task types; use an out parameter in all the other cases. * fe.h (Is_Init_Proc): Declare. * gcc-interface/decl.c (type_requires_init_of_formal): Do not return true for a discriminant in an unchecked union. (gnat_to_gnu_param): Do not create a PARM_DECL for the Out parameter of an initialization procedure. From-SVN: r264984
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog17
-rw-r--r--gcc/ada/exp_ch3.adb95
-rw-r--r--gcc/ada/fe.h6
-rw-r--r--gcc/ada/gcc-interface/decl.c9
4 files changed, 99 insertions, 28 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 924e8d6..3aa9a88 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,22 @@
2018-10-09 Eric Botcazou <ebotcazou@adacore.com>
+ * exp_ch3.adb (Is_Null_Statement_List): New predicate.
+ (Build_Array_Init_Proc): Use it to find out whether the
+ initialization procedure Is_Null_Init_Proc; if so, set
+ Warnings_Off on the parameter.
+ (Build_Init_Procedure): Likewise.
+ (Init_Formals): Use an in/out first parameter only for
+ unconstrained arrays and for records either containing or built
+ for proteced types or task types; use an out parameter in all
+ the other cases.
+ * fe.h (Is_Init_Proc): Declare.
+ * gcc-interface/decl.c (type_requires_init_of_formal): Do not
+ return true for a discriminant in an unchecked union.
+ (gnat_to_gnu_param): Do not create a PARM_DECL for the Out
+ parameter of an initialization procedure.
+
+2018-10-09 Eric Botcazou <ebotcazou@adacore.com>
+
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Constant>: If
this is not a definition, retrieve the expression in all cases
even if we are just annotating types.
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 9281896..e116cda 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -202,6 +202,11 @@ package body Exp_Ch3 is
-- Check if E is defined in the RTL (in a child of Ada or System). Used
-- to avoid to bring in the overhead of _Input, _Output for tagged types.
+ function Is_Null_Statement_List (Stmts : List_Id) return Boolean;
+ -- Returns true if Stmts is made of null statements only, possibly wrapped
+ -- in a case statement, recursively. This latter pattern may occur for the
+ -- initialization procedure of an unchecked union.
+
function Is_User_Defined_Equality (Prim : Node_Id) return Boolean;
-- Returns true if Prim is a user defined equality function
@@ -529,6 +534,7 @@ package body Exp_Ch3 is
Has_Default_Init : Boolean;
Index_List : List_Id;
Loc : Source_Ptr;
+ Parameters : List_Id;
Proc_Id : Entity_Id;
function Init_Component return List_Id;
@@ -722,13 +728,14 @@ package body Exp_Ch3 is
end if;
Body_Stmts := Init_One_Dimension (1);
+ Parameters := Init_Formals (A_Type);
Discard_Node (
Make_Subprogram_Body (Loc,
Specification =>
Make_Procedure_Specification (Loc,
Defining_Unit_Name => Proc_Id,
- Parameter_Specifications => Init_Formals (A_Type)),
+ Parameter_Specifications => Parameters),
Declarations => New_List,
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
@@ -753,18 +760,14 @@ package body Exp_Ch3 is
-- where we have to generate a null procedure in case it is called
-- by a client with Initialize_Scalars set). Such procedures have
-- to be generated, but do not have to be called, so we mark them
- -- as null to suppress the call.
+ -- as null to suppress the call. Kill also warnings for the _Init
+ -- out parameter, which is left entirely uninitialized.
Set_Init_Proc (A_Type, Proc_Id);
- if List_Length (Body_Stmts) = 1
-
- -- We must skip SCIL nodes because they may have been added to this
- -- list by Insert_Actions.
-
- and then Nkind (First_Non_SCIL_Node (Body_Stmts)) = N_Null_Statement
- then
+ if Is_Null_Statement_List (Body_Stmts) then
Set_Is_Null_Init_Proc (Proc_Id);
+ Set_Warnings_Off (Defining_Identifier (First (Parameters)));
else
-- Try to build a static aggregate to statically initialize
@@ -2803,18 +2806,14 @@ package body Exp_Ch3 is
-- where we have to generate a null procedure in case it is called
-- by a client with Initialize_Scalars set). Such procedures have
-- to be generated, but do not have to be called, so we mark them
- -- as null to suppress the call.
+ -- as null to suppress the call. Kill also warnings for the _Init
+ -- out parameter, which is left entirely uninitialized.
Set_Init_Proc (Rec_Type, Proc_Id);
- if List_Length (Body_Stmts) = 1
-
- -- We must skip SCIL nodes because they may have been added to this
- -- list by Insert_Actions.
-
- and then Nkind (First_Non_SCIL_Node (Body_Stmts)) = N_Null_Statement
- then
+ if Is_Null_Statement_List (Body_Stmts) then
Set_Is_Null_Init_Proc (Proc_Id);
+ Set_Warnings_Off (Defining_Identifier (First (Parameters)));
end if;
end Build_Init_Procedure;
@@ -8612,19 +8611,30 @@ package body Exp_Ch3 is
------------------
function Init_Formals (Typ : Entity_Id) return List_Id is
+ Unc_Arr : constant Boolean :=
+ Is_Array_Type (Typ) and then not Is_Constrained (Typ);
+ With_Prot : constant Boolean :=
+ Has_Protected (Typ)
+ or else (Is_Record_Type (Typ)
+ and then Is_Protected_Record_Type (Typ));
+ With_Task : constant Boolean :=
+ Has_Task (Typ)
+ or else (Is_Record_Type (Typ)
+ and then Is_Task_Record_Type (Typ));
Loc : constant Source_Ptr := Sloc (Typ);
Formals : List_Id;
begin
- -- First parameter is always _Init : in out typ. Note that we need this
- -- to be in/out because in the case of the task record value, there
- -- are default record fields (_Priority, _Size, -Task_Info) that may
- -- be referenced in the generated initialization routine.
+ -- The first parameter is always _Init : [in] out Typ. Note that we need
+ -- it to be in/out in the case of an unconstrained array, because of the
+ -- need to have the bounds, and in the case of protected or task record
+ -- value, because there are default record fields that may be referenced
+ -- in the generated initialization routine.
Formals := New_List (
Make_Parameter_Specification (Loc,
Defining_Identifier => Make_Defining_Identifier (Loc, Name_uInit),
- In_Present => True,
+ In_Present => Unc_Arr or else With_Prot or else With_Task,
Out_Present => True,
Parameter_Type => New_Occurrence_Of (Typ, Loc)));
@@ -8632,9 +8642,7 @@ package body Exp_Ch3 is
-- formals, _Master : Master_Id and _Chain : in out Activation_Chain
-- We also add these parameters for the task record type case.
- if Has_Task (Typ)
- or else (Is_Record_Type (Typ) and then Is_Task_Record_Type (Typ))
- then
+ if With_Task then
Append_To (Formals,
Make_Parameter_Specification (Loc,
Defining_Identifier =>
@@ -9022,6 +9030,43 @@ package body Exp_Ch3 is
end loop;
end Init_Secondary_Tags;
+ ----------------------------
+ -- Is_Null_Statement_List --
+ ----------------------------
+
+ function Is_Null_Statement_List (Stmts : List_Id) return Boolean is
+ Stmt : Node_Id;
+
+ begin
+ -- We must skip SCIL nodes because they may have been added to the
+ -- list by Insert_Actions.
+
+ Stmt := First_Non_SCIL_Node (Stmts);
+ while Present (Stmt) loop
+ if Nkind (Stmt) = N_Case_Statement then
+ declare
+ Alt : Node_Id;
+ begin
+ Alt := First (Alternatives (Stmt));
+ while Present (Alt) loop
+ if not Is_Null_Statement_List (Statements (Alt)) then
+ return False;
+ end if;
+
+ Next (Alt);
+ end loop;
+ end;
+
+ elsif Nkind (Stmt) /= N_Null_Statement then
+ return False;
+ end if;
+
+ Stmt := Next_Non_SCIL_Node (Stmt);
+ end loop;
+
+ return True;
+ end Is_Null_Statement_List;
+
------------------------------
-- Is_User_Defined_Equality --
------------------------------
diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h
index 7c32044..b0ccbdc 100644
--- a/gcc/ada/fe.h
+++ b/gcc/ada/fe.h
@@ -156,6 +156,12 @@ extern void Setup_Asm_Outputs (Node_Id);
extern void Get_Encoded_Name (Entity_Id);
extern void Get_External_Name (Entity_Id, Boolean, String_Pointer);
+/* exp_tss: */
+
+#define Is_Init_Proc exp_tss__is_init_proc
+
+extern Boolean Is_Init_Proc (Entity_Id);
+
/* exp_util: */
#define Is_Fully_Repped_Tagged_Type exp_util__is_fully_repped_tagged_type
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index a0d2cbe..c658aac 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -5153,7 +5153,7 @@ type_requires_init_of_formal (Entity_Id type)
Present (field);
field = Next_Entity (field))
{
- if (Ekind (field) == E_Discriminant)
+ if (Ekind (field) == E_Discriminant && !Is_Unchecked_Union (type))
return true;
if (Ekind (field) == E_Component
@@ -5334,11 +5334,14 @@ gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first,
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. */
+ the _Init parameter of an initialization procedure or the special
+ parameter of a valued procedure, never pass them in. */
if (Ekind (gnat_param) == E_Out_Parameter
&& !by_ref
&& !by_component_ptr
- && (!type_requires_init_of_formal (Etype (gnat_param)) || by_return))
+ && (!type_requires_init_of_formal (Etype (gnat_param))
+ || Is_Init_Proc (gnat_subprog)
+ || by_return))
return gnu_param_type;
gnu_param = create_param_decl (gnu_param_name, gnu_param_type);