public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-898] [Ada] Fix predicate check on object declaration
@ 2022-06-01  8:46 Pierre-Marie de Rodat
  0 siblings, 0 replies; only message in thread
From: Pierre-Marie de Rodat @ 2022-06-01  8:46 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:2977b006df03998f6c773f593600881348a4e517

commit r13-898-g2977b006df03998f6c773f593600881348a4e517
Author: Marc Poulhiès <poulhies@adacore.com>
Date:   Fri Apr 22 17:52:49 2022 +0200

    [Ada] Fix predicate check on object declaration
    
    When subtype predicate checks are added for object declarations, it
    could lead to a compiler crash or to an incorrect check.
    
    When the subtype for the object being declared is built later by
    Analyze_Object_Declaration, the predicate check can't be applied on the
    object instead of a copy as the call will be incorrect after the subtype
    has been built.
    
    When subtypes for LHS and RHS do not statically match, only checking the
    predicate on the object after it has been initialized may miss a failing
    predicate on the RHS.
    
    In both cases, skip the optimization and check the predicate on a copy.
    
    Rename Should_Build_Subtype into Build_Default_Subtype_OK and move it
    out of sem_ch3 to make it available to other part of the compiler (in
    particular to checks.adb).
    
    gcc/ada/
    
            * checks.adb (Apply_Predicate_Check): Refine condition for
            applying optimization.
            * sem_ch3.adb (Analyze_Component_Declaration): Adjust calls to
            Should_Build_Subtype.
            (Analyze_Object_Declaration): Likewise.
            (Should_Build_Subtype): Rename/move to ...
            * sem_util.ads (Build_Default_Subtype_OK): ... this.
            * sem_util.adb (Build_Default_Subtype_OK): Moved from
            sem_ch3.adb.

Diff:
---
 gcc/ada/checks.adb   | 26 ++++++++++++----
 gcc/ada/sem_ch3.adb  | 88 ++--------------------------------------------------
 gcc/ada/sem_util.adb | 74 +++++++++++++++++++++++++++++++++++++++++++
 gcc/ada/sem_util.ads | 10 ++++++
 4 files changed, 106 insertions(+), 92 deletions(-)

diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 14f4f95f88c..204d13efc72 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -2944,14 +2944,28 @@ package body Checks is
 
          --  Similarly, if the expression is an aggregate in an object
          --  declaration, apply it to the object after the declaration.
-         --  This is only necessary in rare cases of tagged extensions
-         --  initialized with an aggregate with an "others => <>" clause.
+
+         --  This is only necessary in cases of tagged extensions
+         --  initialized with an aggregate with an "others => <>" clause,
+         --  when the subtypes of LHS and RHS do not statically match or
+         --  when we know the object's type will be rewritten later.
+         --  The condition for the later is copied from the
+         --  Analyze_Object_Declaration procedure when it actually builds the
+         --  subtype.
 
          elsif Nkind (Par) = N_Object_Declaration then
-            Insert_Action_After (Par,
-              Make_Predicate_Check (Typ,
-                New_Occurrence_Of (Defining_Identifier (Par), Sloc (N))));
-            return;
+            if Subtypes_Statically_Match
+                 (Etype (Defining_Identifier (Par)), Typ)
+              and then (Nkind (N) = N_Extension_Aggregate
+                         or else (Is_Definite_Subtype (Typ)
+                                   and then Build_Default_Subtype_OK (Typ)))
+            then
+               Insert_Action_After (Par,
+                  Make_Predicate_Check (Typ,
+                    New_Occurrence_Of (Defining_Identifier (Par), Sloc (N))));
+               return;
+            end if;
+
          end if;
       end if;
 
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index f91d3edfefd..2dbba159980 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -725,16 +725,6 @@ package body Sem_Ch3 is
    --  sets the flags SSO_Set_Low_By_Default/SSO_Set_High_By_Default according
    --  to the setting of Opt.Default_SSO.
 
-   function Should_Build_Subtype (T : Entity_Id) return Boolean;
-   --  When analyzing components or object declarations, it is possible, in
-   --  some cases, to build subtypes for discriminated types. This is
-   --  worthwhile to avoid the backend allocating the maximum possible size for
-   --  objects of the type.
-   --  In particular, when T is limited, the discriminants and therefore the
-   --  size of an object of type T cannot change. Furthermore, if T is definite
-   --  with statically initialized defaulted discriminants, we are able and
-   --  want to build a constrained subtype of the right size.
-
    procedure Signed_Integer_Type_Declaration (T : Entity_Id; Def : Node_Id);
    --  Create a new signed integer entity, and apply the constraint to obtain
    --  the required first named subtype of this type.
@@ -2214,7 +2204,7 @@ package body Sem_Ch3 is
 
       --  When possible, build the default subtype
 
-      if Should_Build_Subtype (T) then
+      if Build_Default_Subtype_OK (T) then
          declare
             Act_T : constant Entity_Id := Build_Default_Subtype (T, N);
 
@@ -4815,7 +4805,7 @@ package body Sem_Ch3 is
 
       --  When possible, build the default subtype
 
-      elsif Should_Build_Subtype (T) then
+      elsif Build_Default_Subtype_OK (T) then
          if No (E) then
             Act_T := Build_Default_Subtype (T, N);
          else
@@ -22963,80 +22953,6 @@ package body Sem_Ch3 is
       end if;
    end Set_Stored_Constraint_From_Discriminant_Constraint;
 
-   --------------------------
-   -- Should_Build_Subtype --
-   --------------------------
-
-   function Should_Build_Subtype (T : Entity_Id) return Boolean is
-
-      function Default_Discriminant_Values_Known_At_Compile_Time
-         (T : Entity_Id) return Boolean;
-         --  For an unconstrained type T, return False if the given type has a
-         --  discriminant with default value not known at compile time. Return
-         --  True otherwise.
-
-      ---------------------------------------------------------
-      -- Default_Discriminant_Values_Known_At_Compile_Time --
-      ---------------------------------------------------------
-
-      function Default_Discriminant_Values_Known_At_Compile_Time
-         (T : Entity_Id) return Boolean
-      is
-         Discr : Entity_Id;
-         DDV : Node_Id;
-
-      begin
-
-         --  If the type has no discriminant, we know them all at compile time
-
-         if not Has_Discriminants (T) then
-            return True;
-         end if;
-
-         --  The type has discriminants, check that none of them has a default
-         --  value not known at compile time.
-
-         Discr := First_Discriminant (T);
-
-         while Present (Discr) loop
-            DDV := Discriminant_Default_Value (Discr);
-
-            if Present (DDV) and then not Compile_Time_Known_Value (DDV) then
-               return False;
-            end if;
-
-            Next_Discriminant (Discr);
-         end loop;
-
-         return True;
-      end Default_Discriminant_Values_Known_At_Compile_Time;
-
-   --  Start of processing for Should_Build_Subtype
-
-   begin
-
-      if Is_Constrained (T) then
-
-         --  We won't build a new subtype if T is constrained
-
-         return False;
-      end if;
-
-      if not Default_Discriminant_Values_Known_At_Compile_Time (T) then
-
-         --  This is a special case of definite subtypes. To allocate a
-         --  specific size to the subtype, we need to know the value at compile
-         --  time. This might not be the case if the default value is the
-         --  result of a function. In that case, the object might be definite
-         --  and limited but the needed size might not be statically known or
-         --  too tricky to obtain. In that case, we will not build the subtype.
-
-         return False;
-      end if;
-
-      return Is_Definite_Subtype (T) and then Is_Limited_View (T);
-   end Should_Build_Subtype;
-
    -------------------------------------
    -- Signed_Integer_Type_Declaration --
    -------------------------------------
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 3ca19323eac..eb0a1f11733 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -2533,6 +2533,80 @@ package body Sem_Util is
       end;
    end Build_Default_Subtype;
 
+   ------------------------------
+   -- Build_Default_Subtype_OK --
+   ------------------------------
+
+   function Build_Default_Subtype_OK (T : Entity_Id) return Boolean is
+
+      function Default_Discriminant_Values_Known_At_Compile_Time
+         (T : Entity_Id) return Boolean;
+         --  For an unconstrained type T, return False if the given type has a
+         --  discriminant with default value not known at compile time. Return
+         --  True otherwise.
+
+      ---------------------------------------------------------
+      -- Default_Discriminant_Values_Known_At_Compile_Time --
+      ---------------------------------------------------------
+
+      function Default_Discriminant_Values_Known_At_Compile_Time
+         (T : Entity_Id) return Boolean
+      is
+         Discr : Entity_Id;
+         DDV : Node_Id;
+
+      begin
+
+         --  If the type has no discriminant, we know them all at compile time
+
+         if not Has_Discriminants (T) then
+            return True;
+         end if;
+
+         --  The type has discriminants, check that none of them has a default
+         --  value not known at compile time.
+
+         Discr := First_Discriminant (T);
+
+         while Present (Discr) loop
+            DDV := Discriminant_Default_Value (Discr);
+
+            if Present (DDV) and then not Compile_Time_Known_Value (DDV) then
+               return False;
+            end if;
+
+            Next_Discriminant (Discr);
+         end loop;
+
+         return True;
+      end Default_Discriminant_Values_Known_At_Compile_Time;
+
+   --  Start of processing for Build_Default_Subtype_OK
+
+   begin
+
+      if Is_Constrained (T) then
+
+         --  We won't build a new subtype if T is constrained
+
+         return False;
+      end if;
+
+      if not Default_Discriminant_Values_Known_At_Compile_Time (T) then
+
+         --  This is a special case of definite subtypes. To allocate a
+         --  specific size to the subtype, we need to know the value at compile
+         --  time. This might not be the case if the default value is the
+         --  result of a function. In that case, the object might be definite
+         --  and limited but the needed size might not be statically known or
+         --  too tricky to obtain. In that case, we will not build the subtype.
+
+         return False;
+      end if;
+
+      return Is_Definite_Subtype (T) and then Is_Limited_View (T);
+   end Build_Default_Subtype_OK;
+
    --------------------------------------------
    -- Build_Discriminal_Subtype_Of_Component --
    --------------------------------------------
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index bfd952a2947..37118ccb809 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -320,6 +320,16 @@ package Sem_Util is
    --  declaration in the tree before N, and return the entity of that
    --  subtype. Otherwise, simply return T.
 
+   function Build_Default_Subtype_OK (T : Entity_Id) return Boolean;
+   --  When analyzing components or object declarations, it is possible, in
+   --  some cases, to build subtypes for discriminated types. This is
+   --  worthwhile to avoid the backend allocating the maximum possible size for
+   --  objects of the type.
+   --  In particular, when T is limited, the discriminants and therefore the
+   --  size of an object of type T cannot change. Furthermore, if T is definite
+   --  with statically initialized defaulted discriminants, we are able and
+   --  want to build a constrained subtype of the right size.
+
    function Build_Discriminal_Subtype_Of_Component
      (T : Entity_Id) return Node_Id;
    --  Determine whether a record component has a type that depends on


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-01  8:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-01  8:46 [gcc r13-898] [Ada] Fix predicate check on object declaration Pierre-Marie de Rodat

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).