]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[Ada] Unnesting: fix for constrained arrays and improve static constants
authorpmderodat <pmderodat@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Dec 2018 11:11:22 +0000 (11:11 +0000)
committerpmderodat <pmderodat@138bc75d-0d04-0410-961f-82ee72b054a4>
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@267003 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 1f59c88303b14e83b5dee544a565a1821e11d195..33d2a1499d4ac1dc4c52ee76143be2288b70c2a9 100644 (file)
@@ -1,3 +1,14 @@
+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
index 882866e38e0cb856344a568231c0243409b824e5..57b2a9e190c65e78b354f4b86dec1d6de0321cd0 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.