Patchwork [Ada] Attributes of arrays with an index type derived from a formal type

login
register
mail settings
Submitter Arnaud Charlet
Date June 23, 2010, 6:26 a.m.
Message ID <20100623062644.GA29656@adacore.com>
Download mbox | patch
Permalink /patch/56593/
State New
Headers show

Comments

Arnaud Charlet - June 23, 2010, 6:26 a.m.
The attributes of formal discrete types, and of arrays whose indices are
formal types, are not static and cannot be constant-folded. The same is true
if an index type is derived from a formal type. The check for types derived
from formal types was missing, leading to improper static evaluation..

The following must compile and execute quietly:

with G1;
procedure Q is
   type Indx is range 1 .. 10;
   package Inst is new G1 (Indx);
   use Inst;
   Obj : R := ((others => 0), 10);
begin
   if not Is_Full (Obj) then
      raise Program_Error;
   end if;
end;
---
generic
   type Ix is range <>;
package G1 is
   type Iterator is new Ix;
   type Arr is array (Iterator) of integer;
   type R is record
      Nodes : Arr;
      Count : Positive;
   end record;

   function Is_Full (It : R) return Boolean;
end G1;
---
package body G1 is
   function Is_Full (It : R) return Boolean is
   begin
      return It.Count = It.Nodes'Length;
   end Is_Full;
end G1;

Tested on x86_64-pc-linux-gnu, committed on trunk

2010-06-23  Ed Schonberg  <schonberg@adacore.com>

	* sem_attr.adb (Eval_Attribute): If the prefix is an array, the
	attribute cannot be constant-folded if an index type is a formal type,
	or is derived from one.
	* checks.adb (Determine_Range): ditto.

Patch

Index: checks.adb
===================================================================
--- checks.adb	(revision 161078)
+++ checks.adb	(working copy)
@@ -3351,6 +3351,14 @@  package body Checks is
                         Indx := Next_Index (Indx);
                      end loop;
 
+                     --  if The index type is a formal type, or derived from
+                     --  one, the bounds are not static.
+
+                     if Is_Generic_Type (Root_Type (Etype (Indx))) then
+                        OK := False;
+                        return;
+                     end if;
+
                      Determine_Range
                        (Type_Low_Bound (Etype (Indx)), OK1, LL, LU,
                         Assume_Valid);
Index: sem_attr.adb
===================================================================
--- sem_attr.adb	(revision 161200)
+++ sem_attr.adb	(working copy)
@@ -5633,10 +5633,10 @@  package body Sem_Attr is
             while Present (N) loop
                Static := Static and then Is_Static_Subtype (Etype (N));
 
-               --  If however the index type is generic, attributes cannot
-               --  be folded.
+               --  If however the index type is generic, or derived from
+               --  one, attributes cannot be folded.
 
-               if Is_Generic_Type (Etype (N))
+               if Is_Generic_Type (Root_Type (Etype (N)))
                  and then Id /= Attribute_Component_Size
                then
                   return;
@@ -6205,13 +6205,13 @@  package body Sem_Attr is
          Ind : Node_Id;
 
       begin
-         --  In the case of a generic index type, the bounds may appear static
-         --  but the computation is not meaningful in this case, and may
-         --  generate a spurious warning.
+         --  If any index type is a formal type, or derived from one, the
+         --  bounds are not static. Treating them as static can produce
+         --  spurious warnings or improper constant folding.
 
          Ind := First_Index (P_Type);
          while Present (Ind) loop
-            if Is_Generic_Type (Etype (Ind)) then
+            if Is_Generic_Type (Root_Type (Etype (Ind))) then
                return;
             end if;