[Ada] Fix ICE related to type freezing
authorEd Schonberg <schonberg@adacore.com>
Wed, 26 Sep 2018 09:16:28 +0000 (09:16 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Wed, 26 Sep 2018 09:16:28 +0000 (09:16 +0000)
2018-09-26  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

* contracts.adb (Expand_Subprogram_Contract,
Process_Preconditions_For): Apply Freeze_Expr_Types to the
expression for a precondition of an expression function that is
a completion, when the completion appears in the private part
and the declaration it completes is in the visible part of the
same package.
* freeze.adb (Freeze_Expr_Types): Do not establish the scope of
the operation if it is already installed, as will be the case
when called to analyze the contract oc the subprogram (which
happens when generating code inside the subprogram body).

From-SVN: r264602

gcc/ada/ChangeLog
gcc/ada/contracts.adb
gcc/ada/freeze.adb

index 8d7f5c24e7f54bbb86e9a9dfa71be97283802d42..e5be5bbadff820b8efbe6ecbff17c2e0a23f143c 100644 (file)
@@ -1,3 +1,16 @@
+2018-09-26  Ed Schonberg  <schonberg@adacore.com>
+
+       * contracts.adb (Expand_Subprogram_Contract,
+       Process_Preconditions_For): Apply Freeze_Expr_Types to the
+       expression for a precondition of an expression function that is
+       a completion, when the completion appears in the private part
+       and the declaration it completes is in the visible part of the
+       same package.
+       * freeze.adb (Freeze_Expr_Types): Do not establish the scope of
+       the operation if it is already installed, as will be the case
+       when called to analyze the contract oc the subprogram (which
+       happens when generating code inside the subprogram body).
+
 2018-09-26  Maroua Maalej  <maalej@adacore.com>
 
        * sem_spark.adb (Check_Param_In, Setup_Parameter_Or_Global):
index 26a8d2894b2ea0ab704e1d517fba755934919c87..136c05c66d1f84116988878be2b9800d4304fd9d 100644 (file)
@@ -33,6 +33,7 @@ with Exp_Prag; use Exp_Prag;
 with Exp_Tss;  use Exp_Tss;
 with Exp_Util; use Exp_Util;
 with Freeze;   use Freeze;
+with Lib;      use Lib;
 with Namet;    use Namet;
 with Nlists;   use Nlists;
 with Nmake;    use Nmake;
@@ -591,7 +592,8 @@ package body Contracts is
          if Skip_Assert_Exprs then
             null;
 
-         --  Otherwise analyze the pre/postconditions. Their expressions
+         --  Otherwise analyze the pre/postconditions.
+         --  If these come from an aspect specification, their expressions
          --  might include references to types that are not frozen yet, in the
          --  case where the body is a rewritten expression function that is a
          --  completion, so freeze all types within before constructing the
@@ -2856,12 +2858,25 @@ package body Contracts is
          procedure Process_Preconditions_For (Subp_Id : Entity_Id) is
             Items : constant Node_Id := Contract (Subp_Id);
 
+            Bod       : constant Node_Id := Unit_Declaration_Node (Body_Id);
             Decl      : Node_Id;
+            Freeze_T  : Boolean;
             Prag      : Node_Id;
             Subp_Decl : Node_Id;
 
          begin
-            --  Process the contract
+            --  Process the contract. If the body is an expression function
+            --  that is a completion, freeze types within, because this may
+            --  not have been done yet, when the subprogram declaration and
+            --  its completion by an expression function appear in distinct
+            --  declarative lists of the same unit (visible and private).
+
+            Freeze_T := Was_Expression_Function (Bod)
+                          and then Sloc (Body_Id) /= Sloc (Subp_Id)
+                          and then In_Same_Source_Unit (Body_Id, Subp_Id)
+                          and then List_Containing (Bod) /=
+                            List_Containing (Unit_Declaration_Node (Subp_Id))
+                          and then not In_Instance;
 
             if Present (Items) then
                Prag := Pre_Post_Conditions (Items);
@@ -2869,6 +2884,13 @@ package body Contracts is
                   if Pragma_Name (Prag) = Name_Precondition
                     and then Is_Checked (Prag)
                   then
+                     if Freeze_T
+                        and then Present (Corresponding_Aspect (Prag))
+                     then
+                        Freeze_Expr_Types (Subp_Id, Standard_Boolean,
+                          Expression (Corresponding_Aspect (Prag)), Bod);
+                     end if;
+
                      Prepend_To_Decls_Or_Save (Prag);
                   end if;
 
index 5036a7991eda65932c031bcedbd0f12de06760c2..4ff0d385ae48b4e4ab73a6a6f39df8d4373d6c34 100644 (file)
@@ -7824,11 +7824,20 @@ package body Freeze is
       --  minimum decoration needed to locate referenced unfrozen types
       --  without adding any decoration to the function expression.
 
-      Push_Scope (Def_Id);
-      Install_Formals (Def_Id);
+      --  This routine is also applied to expressions in the contract for
+      --  the subprogram. If that happens when expanding the code for
+      --  pre/postconditions during expansion of the subprogram body, the
+      --  subprogram is already installed.
 
-      Preanalyze_Spec_Expression (Dup_Expr, Typ);
-      End_Scope;
+      if Def_Id /= Current_Scope then
+         Push_Scope (Def_Id);
+         Install_Formals (Def_Id);
+
+         Preanalyze_Spec_Expression (Dup_Expr, Typ);
+         End_Scope;
+      else
+         Preanalyze_Spec_Expression (Dup_Expr, Typ);
+      end if;
 
       --  Restore certain attributes of Def_Id since the preanalysis may
       --  have introduced itypes to this scope, thus modifying attributes