[Ada] Unnesting: fix for constrained arrays and improve static constants
authorEd Schonberg <schonberg@adacore.com>
Tue, 11 Dec 2018 11:11:22 +0000 (11:11 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Tue, 11 Dec 2018 11:11:22 +0000 (11:11 +0000)
2018-12-11  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

* exp_unst.adb (Needs_Fat_Pointer): A fat pointer is required if
the entity has a private type whose full view is an
unconstrained array type.
(Rewrite_One_Ref): If the reference is to a static constant, use
its value rather than create a reference through the activation
record. This is more efficient, and furthermore indispensable if
the context requires a static constant, such as in a branch of a
case statement.

From-SVN: r267003

gcc/ada/ChangeLog
gcc/ada/exp_unst.adb

index 1f59c88..33d2a14 100644 (file)
@@ -1,5 +1,16 @@
 2018-12-11  Ed Schonberg  <schonberg@adacore.com>
 
+       * exp_unst.adb (Needs_Fat_Pointer): A fat pointer is required if
+       the entity has a private type whose full view is an
+       unconstrained array type.
+       (Rewrite_One_Ref): If the reference is to a static constant, use
+       its value rather than create a reference through the activation
+       record. This is more efficient, and furthermore indispensable if
+       the context requires a static constant, such as in a branch of a
+       case statement.
+
+2018-12-11  Ed Schonberg  <schonberg@adacore.com>
+
        * sem_ch3.adb (Analyze_Object_Declaration): Apply
        Dynamic_Predicate check to an object of an array type
        initialized with an aggregate.
index 882866e..57b2a9e 100644 (file)
@@ -246,10 +246,19 @@ package body Exp_Unst is
    -----------------------
 
    function Needs_Fat_Pointer (E : Entity_Id) return Boolean is
+      Typ : Entity_Id;
    begin
-      return Is_Formal (E)
-        and then Is_Array_Type (Etype (E))
-        and then not Is_Constrained (Etype (E));
+      if Is_Formal (E) then
+         Typ := Etype (E);
+         if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
+            Typ := Full_View (Typ);
+         end if;
+
+         return Is_Array_Type (Typ)
+           and then not Is_Constrained (Typ);
+      else
+         return False;
+      end if;
    end Needs_Fat_Pointer;
 
    ----------------
@@ -2168,6 +2177,21 @@ package body Exp_Unst is
                   goto Continue;
                end if;
 
+               --  If this is a reference to a global constant, use its value
+               --  rather than create a reference. It is more efficient and
+               --  furthermore indispensable if the context requires a
+               --  constant, such as a branch of a case statement.
+
+               if Ekind (UPJ.Ent) = E_Constant
+                 and then Is_True_Constant (UPJ.Ent)
+                 and then Present (Constant_Value (UPJ.Ent))
+                 and then Is_Static_Expression (Constant_Value (UPJ.Ent))
+               then
+                  Rewrite (UPJ.Ref,
+                    New_Copy_Tree (Constant_Value (UPJ.Ent)));
+                  goto Continue;
+               end if;
+
                --  Push the current scope, so that the pointer type Tnn, and
                --  any subsidiary entities resulting from the analysis of the
                --  rewritten reference, go in the right entity chain.