diff mbox

[Ada] Illegal use of current instance in attribute reference

Message ID 20160420105109.GA3711@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet April 20, 2016, 10:51 a.m. UTC
The current instance of a type in an aspect specification is an object of
the type. If the type is scalar, it cannot be the prefix of an attribute
reference such as 'First,  whose prefix must an array object (even though it
can be a scalar type in other contexts).

Compiling foo.adb must yield:
foo.adb:3:29:
  prefix of "First" attribute cannot be the current instance of a scalar type
foo.adb:6:29:
  prefix of "First" attribute cannot be the current instance of a scalar type

---
procedure Foo is
    type T_Data_Sending_Frequency is new Natural
      with Default_Value => T_Data_Sending_Frequency'First;

    type Infrequent is new Natural
      with Default_Value => Infrequent'First + 3;

begin
    null;
end;

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

2016-04-20  Ed Schonberg  <schonberg@adacore.com>

	* sem_attr.adb (Check_Type): Reject an attribute reference in
	an aspect expression, when the prefix of the reference is the
	current instance of the type to which the aspect applies.
diff mbox

Patch

Index: sem_attr.adb
===================================================================
--- sem_attr.adb	(revision 235243)
+++ sem_attr.adb	(working copy)
@@ -1408,10 +1408,41 @@ 
       --------------------------------
 
       procedure Check_Array_Or_Scalar_Type is
+         function In_Aspect_Specification return Boolean;
+         --  A current instance of a type in an aspect specification is an
+         --  object and not a type, and therefore cannot be of a scalar type
+         --  in the prefix of one of the array attributes if the attribute
+         --  reference is part of an aspect expression.
+
+         -----------------------------
+         -- In_Aspect_Specification --
+         -----------------------------
+
+         function In_Aspect_Specification return Boolean is
+            P : Node_Id;
+
+         begin
+            P := Parent (N);
+            while Present (P) loop
+               if Nkind (P) = N_Aspect_Specification then
+                  return P_Type = Entity (P);
+
+               elsif Nkind (P) in N_Declaration then
+                  return False;
+               end if;
+
+               P := Parent (P);
+            end loop;
+
+            return False;
+         end In_Aspect_Specification;
+
+         --  Local variables
+
+         Dims  : Int;
          Index : Entity_Id;
 
-         D : Int;
-         --  Dimension number for array attributes
+      --  Start of processing for Check_Array_Or_Scalar_Type
 
       begin
          --  Case of string literal or string literal subtype. These cases
@@ -1431,6 +1462,12 @@ 
 
             if Present (E1) then
                Error_Attr ("invalid argument in % attribute", E1);
+
+            elsif In_Aspect_Specification then
+               Error_Attr
+                 ("prefix of % attribute cannot be the current instance of a "
+                  & "scalar type", P);
+
             else
                Set_Etype (N, P_Base_Type);
                return;
@@ -1466,9 +1503,9 @@ 
                Set_Etype (N, Base_Type (Etype (Index)));
 
             else
-               D := UI_To_Int (Intval (E1));
+               Dims := UI_To_Int (Intval (E1));
 
-               for J in 1 .. D - 1 loop
+               for J in 1 .. Dims - 1 loop
                   Next_Index (Index);
                end loop;