]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[Ada] Tbuild cleanup
authorBob Duff <duff@adacore.com>
Sat, 8 May 2021 15:39:52 +0000 (11:39 -0400)
committerPierre-Marie de Rodat <derodat@adacore.com>
Tue, 6 Jul 2021 14:46:54 +0000 (14:46 +0000)
gcc/ada/

* tbuild.adb (Convert_To): Add assert, along with a comment.
(Make_DT_Access): Remove this function, which is not used.  It
was incorrect anyway (the call to New_Occurrence_Of should not
be there).
(Unchecked_Convert_To): Add assert.  The previous version's test
for unchecked conversion to the same type was redundant and
could never be true, because the previous 'if' already checked
for ANY expression of the same type. Remove that, and replace
with a test for unchecked conversion to a related type.
Otherwise, we somethings get things like
"finalize(some_type!(some_type!(x)))" in the generated code,
where x is already of type some_type, but we're converting it to
the private type and then to the full type or vice versa (so the
types aren't equal, so the previous 'if' doesn't catch it).
Avoid updating the Parent. This is not necessary; the Parent
will be updated if/when the node is attached to the tree.
* tbuild.ads: Fix comments. No need to say "this is safe" when
we just explained that a few lines earlier.  Remove
Make_DT_Access.
* sinfo.ads: Add comments.
* exp_ch7.adb (Make_Finalize_Address_Stmts): Minor comment fix.
* gen_il-gen.adb, gen_il-gen.ads, gen_il-gen-gen_nodes.adb,
gen_il-internals.ads: Implement a feature where you can put:
Nmake_Assert => "expr" where expr is a boolean expression in a
call to Create_Concrete_Node_Type. It is added in a pragma
Assert in the Nmake.Make_... function for that type.

gcc/ada/exp_ch7.adb
gcc/ada/gen_il-gen-gen_nodes.adb
gcc/ada/gen_il-gen.adb
gcc/ada/gen_il-gen.ads
gcc/ada/gen_il-internals.ads
gcc/ada/sinfo.ads
gcc/ada/tbuild.adb
gcc/ada/tbuild.ads

index 4c1e16d9e3206cecb7e28a7d6b068b17438cc066..b0374a39d4c36f03b3805484e24cabf75bac80eb 100644 (file)
@@ -9344,7 +9344,7 @@ package body Exp_Ch7 is
             Dope_Id : Entity_Id;
 
          begin
-            --  Ensure that Ptr_Typ a thin pointer, generate:
+            --  Ensure that Ptr_Typ is a thin pointer; generate:
             --    for Ptr_Typ'Size use System.Address'Size;
 
             Append_To (Decls,
index ef7dfa4c19081a4c7eb955bfee7953f644d76f5d..2427a1e8e891f2d096050faa797b3e01cd4968e0 100644 (file)
@@ -31,7 +31,8 @@ procedure Gen_IL.Gen.Gen_Nodes is
       renames Create_Abstract_Node_Type;
    procedure Cc -- Short for "ConCrete"
      (T : Concrete_Node; Parent : Abstract_Type;
-      Fields : Field_Sequence := No_Fields)
+      Fields : Field_Sequence := No_Fields;
+      Nmake_Assert : String := "")
       renames Create_Concrete_Node_Type;
 
    function Sy -- Short for "Syntactic"
@@ -562,7 +563,12 @@ begin -- Gen_IL.Gen.Gen_Nodes
        (Sy (Subtype_Mark, Node_Id, Default_Empty),
         Sy (Expression, Node_Id, Default_Empty),
         Sm (Kill_Range_Check, Flag),
-        Sm (No_Truncation, Flag)));
+        Sm (No_Truncation, Flag)),
+       Nmake_Assert => "True or else Nkind (Expression) /= N_Unchecked_Type_Conversion");
+--       Nmake_Assert => "Nkind (Expression) /= N_Unchecked_Type_Conversion");
+   --  Assert that we don't have unchecked conversions of unchecked
+   --  conversions; if Expression might be an unchecked conversion,
+   --  then Tbuild.Unchecked_Convert_To should be used.
 
    Cc (N_Subtype_Indication, N_Has_Etype,
        (Sy (Subtype_Mark, Node_Id, Default_Empty),
index 0f3698ea33be38463098eacb887df388562ecc31..94f7c9cb2d8d7420b73a8280d6ced69904e9a373 100644 (file)
@@ -47,9 +47,10 @@ package body Gen_IL.Gen is
    All_Entities : constant Type_Vector := To_Vector (Entity_Kind, Length => 1);
 
    procedure Create_Type
-     (T      : Node_Or_Entity_Type;
-      Parent : Opt_Abstract_Type;
-      Fields : Field_Sequence);
+     (T            : Node_Or_Entity_Type;
+      Parent       : Opt_Abstract_Type;
+      Fields       : Field_Sequence;
+      Nmake_Assert : String);
    --  Called by the Create_..._Type procedures exported by this package to
    --  create an entry in the Types_Table.
 
@@ -107,9 +108,10 @@ package body Gen_IL.Gen is
    -----------------
 
    procedure Create_Type
-     (T      : Node_Or_Entity_Type;
-      Parent : Opt_Abstract_Type;
-      Fields : Field_Sequence)
+     (T            : Node_Or_Entity_Type;
+      Parent       : Opt_Abstract_Type;
+      Fields       : Field_Sequence;
+      Nmake_Assert : String)
    is
    begin
       Check_Type (T);
@@ -132,7 +134,8 @@ package body Gen_IL.Gen is
         new Type_Info'
           (Is_Union => False, Parent => Parent,
            Children | Concrete_Descendants => Type_Vectors.Empty_Vector,
-           First | Last | Fields => <>); -- filled in later
+           First | Last | Fields => <>, -- filled in later
+           Nmake_Assert => new String'(Nmake_Assert));
 
       if Parent /= No_Type then
          Append (Type_Table (Parent).Children, T);
@@ -215,7 +218,7 @@ package body Gen_IL.Gen is
      (T      : Abstract_Node;
       Fields : Field_Sequence := No_Fields) is
    begin
-      Create_Type (T, Parent => No_Type, Fields => Fields);
+      Create_Type (T, Parent => No_Type, Fields => Fields, Nmake_Assert => "");
    end Create_Root_Node_Type;
 
    -------------------------------
@@ -227,7 +230,7 @@ package body Gen_IL.Gen is
       Fields : Field_Sequence := No_Fields)
    is
    begin
-      Create_Type (T, Parent, Fields);
+      Create_Type (T, Parent, Fields, Nmake_Assert => "");
    end Create_Abstract_Node_Type;
 
    -------------------------------
@@ -236,10 +239,11 @@ package body Gen_IL.Gen is
 
    procedure Create_Concrete_Node_Type
      (T      : Concrete_Node; Parent : Abstract_Type;
-      Fields : Field_Sequence := No_Fields)
+      Fields : Field_Sequence := No_Fields;
+      Nmake_Assert : String := "")
    is
    begin
-      Create_Type (T, Parent, Fields);
+      Create_Type (T, Parent, Fields, Nmake_Assert);
    end Create_Concrete_Node_Type;
 
    -----------------------------
@@ -250,7 +254,7 @@ package body Gen_IL.Gen is
      (T      : Abstract_Entity;
       Fields : Field_Sequence := No_Fields) is
    begin
-      Create_Type (T, Parent => No_Type, Fields => Fields);
+      Create_Type (T, Parent => No_Type, Fields => Fields, Nmake_Assert => "");
    end Create_Root_Entity_Type;
 
    ---------------------------------
@@ -262,7 +266,7 @@ package body Gen_IL.Gen is
       Fields : Field_Sequence := No_Fields)
    is
    begin
-      Create_Type (T, Parent, Fields);
+      Create_Type (T, Parent, Fields, Nmake_Assert => "");
    end Create_Abstract_Entity_Type;
 
    ---------------------------------
@@ -274,7 +278,7 @@ package body Gen_IL.Gen is
       Fields : Field_Sequence := No_Fields)
    is
    begin
-      Create_Type (T, Parent, Fields);
+      Create_Type (T, Parent, Fields, Nmake_Assert => "");
    end Create_Concrete_Entity_Type;
 
    ------------------
@@ -352,7 +356,7 @@ package body Gen_IL.Gen is
               Image (Field);
          end if;
 
-         if Pre /= Field_Table (Field).Pre.all then
+         if Pre_Set /= Field_Table (Field).Pre_Set.all then
             raise Illegal with
               "mismatched extra setter-only preconditions for " &
               Image (Field);
@@ -2561,6 +2565,11 @@ package body Gen_IL.Gen is
                   end;
                end if;
 
+               if Type_Table (T).Nmake_Assert.all /= "" then
+                  Put (S, "pragma Assert (" &
+                           Type_Table (T).Nmake_Assert.all & ");" & LF);
+               end if;
+
                Put (S, "return N;" & LF);
                Decrease_Indent (S, 3);
 
@@ -2628,6 +2637,7 @@ package body Gen_IL.Gen is
          Increase_Indent (B, 3);
 
          Put (B, "--  This package is automatically generated." & LF & LF);
+         Put (B, "pragma Style_Checks (""M200"");" & LF);
 
          Put_Make_Bodies (B, Node_Kind);
 
index 34ce2d6081e82fecc5422484be84cda26ae667ea..1d24ebf10928c4d909a700aadb16268af632203a 100644 (file)
@@ -102,9 +102,12 @@ package Gen_IL.Gen is
 
    procedure Create_Concrete_Node_Type
      (T : Concrete_Node; Parent : Abstract_Type;
-      Fields : Field_Sequence := No_Fields);
+      Fields : Field_Sequence := No_Fields;
+      Nmake_Assert : String := "");
    --  Create a concrete node type. Every node is an instance of a concrete
-   --  node type.
+   --  node type. Nmake_Assert is an assertion to put in the Make_... function
+   --  in the generated Nmake package. It should be a String that represents a
+   --  Boolean expression.
 
    procedure Create_Root_Entity_Type
      (T : Abstract_Entity;
@@ -151,13 +154,14 @@ package Gen_IL.Gen is
    --  only for syntactic fields. Flag fields of syntactic nodes always have a
    --  default value, which is False unless specified as Default_True. Pre is
    --  an additional precondition for the field getter and setter, in addition
-   --  to the precondition that asserts that the type has that field. Pre_Get
-   --  and Pre_Set are similar to Pre, but for the getter or setter only,
-   --  respectively.
+   --  to the precondition that asserts that the type has that field. It should
+   --  be a String that represents a Boolean expression. Pre_Get and Pre_Set
+   --  are similar to Pre, but for the getter or setter only, respectively.
    --
    --  If multiple calls to these occur for the same Field but different types,
-   --  the Field_Type and Pre must match. Default_Value should match for
-   --  syntactic fields. See the declaration of Type_Only_Enum for Type_Only.
+   --  the Field_Type, Pre, Pre_Get, and Pre_Set must match. Default_Value
+   --  should match for syntactic fields. See the declaration of Type_Only_Enum
+   --  for Type_Only.
    --
    --  (The matching Default_Value requirement is a simplification from the
    --  earlier hand-written version.)
index 9c5779bd2d8292c92f851658fb631fbf9c476c25..b8911ec3c0afb7a632d76ff4e06e09dae853b16b 100644 (file)
@@ -104,6 +104,8 @@ package Gen_IL.Internals is
             --  includes two or more types.
 
             Fields : Field_Vector;
+
+            Nmake_Assert : String_Access; -- only for concrete node types
       end case;
    end record;
 
index 8f23f7dfe1a2a4fa5d76650f362763c556370613..f6c5e0dcc59f5048ca0d49b39d9738a4981832d3 100644 (file)
@@ -8420,8 +8420,11 @@ package Sinfo is
       --  An unchecked type conversion node represents the semantic action
       --  corresponding to a call to an instantiation of Unchecked_Conversion.
       --  It is generated as a result of actual use of Unchecked_Conversion
-      --  and also the expander generates unchecked type conversion nodes
-      --  directly for expansion of complex semantic actions.
+      --  and also by the expander.
+
+      --  Unchecked type conversion nodes should normally be created by calling
+      --  Tbuild.Unchecked_Convert_To, rather than by directly calling
+      --  Nmake.Make_Unchecked_Type_Conversion.
 
       --  Note: an unchecked type conversion is a variable as far as the
       --  semantics are concerned, which is convenient for the expander.
index 4c53cdb4338a4c1d7b4f8b6eb8acd42d9960e492..e7186444365b74f99b8ff17b5b1d92daf30dc984 100644 (file)
@@ -29,14 +29,12 @@ with Csets;          use Csets;
 with Einfo;          use Einfo;
 with Einfo.Entities; use Einfo.Entities;
 with Einfo.Utils;    use Einfo.Utils;
-with Elists;         use Elists;
 with Lib;            use Lib;
 with Nlists;         use Nlists;
 with Nmake;          use Nmake;
 with Opt;            use Opt;
 with Restrict;       use Restrict;
 with Rident;         use Rident;
-with Sem_Aux;        use Sem_Aux;
 with Sinfo.Utils;    use Sinfo.Utils;
 with Sem_Util;       use Sem_Util;
 with Snames;         use Snames;
@@ -117,6 +115,7 @@ package body Tbuild is
    ----------------
 
    function Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id is
+      pragma Assert (Is_Type (Typ));
       Result : Node_Id;
 
    begin
@@ -185,32 +184,6 @@ package body Tbuild is
       return N;
    end Make_Byte_Aligned_Attribute_Reference;
 
-   --------------------
-   -- Make_DT_Access --
-   --------------------
-
-   function Make_DT_Access
-     (Loc : Source_Ptr;
-      Rec : Node_Id;
-      Typ : Entity_Id) return Node_Id
-   is
-      Full_Type : Entity_Id := Typ;
-
-   begin
-      if Is_Private_Type (Typ) then
-         Full_Type := Underlying_Type (Typ);
-      end if;
-
-      return
-        Unchecked_Convert_To (
-          New_Occurrence_Of
-            (Etype (Node (First_Elmt (Access_Disp_Table (Full_Type)))), Loc),
-          Make_Selected_Component (Loc,
-            Prefix => New_Copy (Rec),
-            Selector_Name =>
-              New_Occurrence_Of (First_Tag_Component (Full_Type), Loc)));
-   end Make_DT_Access;
-
    ------------------------
    -- Make_Float_Literal --
    ------------------------
@@ -906,26 +879,34 @@ package body Tbuild is
      (Typ  : Entity_Id;
       Expr : Node_Id) return Node_Id
    is
+      pragma Assert (Ekind (Typ) in E_Void | Type_Kind);
+      --  We don't really want to allow E_Void here, but existing code passes
+      --  it.
+
       Loc         : constant Source_Ptr := Sloc (Expr);
       Result      : Node_Id;
-      Expr_Parent : Node_Id;
 
    begin
       --  If the expression is already of the correct type, then nothing
-      --  to do, except for relocating the node in case this is required.
+      --  to do, except for relocating the node
 
       if Present (Etype (Expr))
-        and then (Base_Type (Etype (Expr)) = Typ
-                   or else Etype (Expr) = Typ)
+        and then (Base_Type (Etype (Expr)) = Typ or else Etype (Expr) = Typ)
       then
          return Relocate_Node (Expr);
 
-      --  Case where the expression is itself an unchecked conversion to
-      --  the same type, and we can thus eliminate the outer conversion.
+      --  Case where the expression is already an unchecked conversion. We
+      --  replace the type being converted to, to avoid creating an unchecked
+      --  conversion of an unchecked conversion. Extra unchecked conversions
+      --  make the .dg output less readable. We can't do this in cases
+      --  involving bitfields, because the sizes might not match. The
+      --  Is_Composite_Type checks avoid such cases.
 
       elsif Nkind (Expr) = N_Unchecked_Type_Conversion
-        and then Entity (Subtype_Mark (Expr)) = Typ
+        and then Is_Composite_Type (Etype (Expr))
+        and then Is_Composite_Type (Typ)
       then
+         Set_Subtype_Mark (Expr, New_Occurrence_Of (Typ, Loc));
          Result := Relocate_Node (Expr);
 
       elsif Nkind (Expr) = N_Null
@@ -938,18 +919,10 @@ package body Tbuild is
       --  All other cases
 
       else
-         --  Capture the parent of the expression before relocating it and
-         --  creating the conversion, so the conversion's parent can be set
-         --  to the original parent below.
-
-         Expr_Parent := Parent (Expr);
-
          Result :=
            Make_Unchecked_Type_Conversion (Loc,
              Subtype_Mark => New_Occurrence_Of (Typ, Loc),
              Expression   => Relocate_Node (Expr));
-
-         Set_Parent (Result, Expr_Parent);
       end if;
 
       Set_Etype (Result, Typ);
index 07cd7a7a676728090d9adf62035867c88ed5d961..f2f9809eb7340474c100cc3371ea3c8b08f2f6c9 100644 (file)
@@ -41,19 +41,16 @@ package Tbuild is
    --  except that it will be analyzed and resolved with checks off.
 
    function Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id;
-   --  Returns an expression that represents the result of a checked convert
-   --  of expression Exp to type T. If the base type of Exp is T, then no
-   --  conversion is required, and Exp is returned unchanged. Otherwise an
-   --  N_Type_Conversion node is constructed to convert the expression.
-   --  If an N_Type_Conversion node is required, Relocate_Node is used on
-   --  Exp. This means that it is safe to replace a node by a Convert_To
-   --  of itself to some other type.
+   --  Returns an expression that is a type conversion of expression Expr to
+   --  type Typ. If the type of Expr is Typ, then no conversion is required.
+   --  Otherwise an N_Type_Conversion node is constructed to convert the
+   --  expression. Relocate_Node is applied to Expr, so that it is safe to
+   --  replace a node by a Convert_To of itself to some other type.
 
    procedure Convert_To_And_Rewrite (Typ : Entity_Id; Expr : Node_Id);
    pragma Inline (Convert_To_And_Rewrite);
    --  Like the function, except that there is an extra step of calling
    --  Rewrite on the Expr node and replacing it with the converted result.
-   --  As noted above, this is safe, because Relocate_Node is called.
 
    procedure Discard_Node (N : Node_Or_Entity_Id);
    pragma Inline (Discard_Node);
@@ -78,11 +75,6 @@ package Tbuild is
    --  Must_Be_Byte_Aligned is set in the attribute reference node. The
    --  Attribute_Name must be Name_Address or Name_Unrestricted_Access.
 
-   function Make_DT_Access
-     (Loc : Source_Ptr; Rec : Node_Id; Typ : Entity_Id) return Node_Id;
-   --  Create an access to the Dispatch Table by using the Tag field of a
-   --  tagged record : Acc_Dt (Rec.tag).all
-
    function Make_Float_Literal
      (Loc         : Source_Ptr;
       Radix       : Uint;
@@ -319,13 +311,12 @@ package Tbuild is
    function New_Occurrence_Of
      (Def_Id : Entity_Id;
       Loc    : Source_Ptr) return Node_Id;
-   --  New_Occurrence_Of creates an N_Identifier node which is an occurrence
-   --  of the defining identifier which is passed as its argument. The Entity
-   --  and Etype of the result are set from the given defining identifier as
-   --  follows: Entity is simply a copy of Def_Id. Etype is a copy of Def_Id
-   --  for types, and a copy of the Etype of Def_Id for other entities. Note
-   --  that Is_Static_Expression is set if this call creates an occurrence of
-   --  an enumeration literal.
+   --  New_Occurrence_Of creates an N_Identifier node that is an occurrence of
+   --  the defining identifier Def_Id. The Entity and Etype of the result are
+   --  set from the given defining identifier as follows: Entity is a copy of
+   --  Def_Id. Etype is a copy of Def_Id for types, and a copy of the Etype of
+   --  Def_Id for other entities. Note that Is_Static_Expression is set if this
+   --  call creates an occurrence of an enumeration literal.
 
    function New_Suffixed_Name
      (Related_Id : Name_Id;