-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
with Exp_Util; use Exp_Util;
with Expander; use Expander;
with Freeze; use Freeze;
+with Gnatvsn; use Gnatvsn;
with Itypes; use Itypes;
with Lib; use Lib;
with Lib.Xref; use Lib.Xref;
with Rtsfind; use Rtsfind;
with Sdefault; use Sdefault;
with Sem; use Sem;
+with Sem_Aux; use Sem_Aux;
with Sem_Cat; use Sem_Cat;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
+with Sem_Ch10; use Sem_Ch10;
with Sem_Dist; use Sem_Dist;
+with Sem_Elim; use Sem_Elim;
with Sem_Eval; use Sem_Eval;
with Sem_Res; use Sem_Res;
with Sem_Type; use Sem_Type;
Attribute_05 : constant Attribute_Class_Array := Attribute_Class_Array'(
Attribute_Machine_Rounding |
+ Attribute_Mod |
Attribute_Priority |
Attribute_Stream_Size |
Attribute_Wide_Wide_Width => True,
procedure Check_Dereference;
-- If the prefix of attribute is an object of an access type, then
- -- introduce an explicit deference, and adjust P_Type accordingly.
+ -- introduce an explicit dereference, and adjust P_Type accordingly.
procedure Check_Discrete_Type;
-- Verify that prefix of attribute N is a discrete type
-- an access, we set a flag to kill all tracked values on any call
-- because this access value may be passed around, and any called
-- code might use it to access a local procedure which clobbers a
- -- tracked value.
+ -- tracked value. If the scope is a loop or block, indicate that
+ -- value tracking is disabled for the enclosing subprogram.
function Get_Kind (E : Entity_Id) return Entity_Kind;
-- Distinguish between access to regular/protected subprograms
begin
if not Is_Library_Level_Entity (E) then
Set_Suppress_Value_Tracking_On_Call (Current_Scope);
+ Set_Suppress_Value_Tracking_On_Call
+ (Nearest_Dynamic_Scope (Current_Scope));
end if;
end Check_Local_Access;
Error_Attr ("attribute% cannot be applied to a subprogram", P);
end if;
+ -- Issue an error if the prefix denotes an eliminated subprogram
+
+ Check_For_Eliminated_Subprogram (P, Entity (P));
+
+ -- Check for obsolescent subprogram reference
+
+ Check_Obsolescent_2005_Entity (Entity (P), P);
+
-- Build the appropriate subprogram type
Build_Access_Subprogram_Type (P);
end loop;
if Present (Q) then
- Set_Has_Per_Object_Constraint (
- Defining_Identifier (Q), True);
+ Set_Has_Per_Object_Constraint
+ (Defining_Identifier (Q), True);
end if;
end;
("current instance attribute must appear alone", N);
end if;
+ if Is_CPP_Class (Root_Type (Typ)) then
+ Error_Msg_N
+ ("?current instance unsupported for derivations of "
+ & "'C'P'P types", N);
+ end if;
+
-- OK if we are in initialization procedure for the type
-- in question, in which case the reference to the type
-- is rewritten as a reference to the current object.
-- expression comes from source, e.g. when a single component
-- association in an aggregate has a box association.
- elsif Ada_Version >= Ada_05
+ elsif Ada_Version >= Ada_2005
and then OK_Self_Reference
then
null;
-- the designated type of the access type, since the type of
-- the referenced array is this type (see AI95-00106).
- Freeze_Before (N, Designated_Type (P_Type));
+ -- As done elsewhere, freezing must not happen when pre-analyzing
+ -- a pre- or postcondition or a default value for an object or
+ -- for a formal parameter.
+
+ if not In_Spec_Expression then
+ Freeze_Before (N, Designated_Type (P_Type));
+ end if;
Rewrite (P,
Make_Explicit_Dereference (Sloc (P),
-- S : constant Integer := X.all'Size; -- ERROR
-- procedure Q (Obj : Integer := X.all'Alignment); -- ERROR
- if Ada_Version >= Ada_05
+ if Ada_Version >= Ada_2005
and then Nkind (P) = N_Explicit_Dereference
then
E := P;
E := Prefix (E);
end loop;
- if From_With_Type (Etype (E)) then
+ Typ := Etype (E);
+
+ if From_With_Type (Typ) then
Error_Attr_P
("prefix of % attribute cannot be an incomplete type");
else
- if Is_Access_Type (Etype (E)) then
- Typ := Directly_Designated_Type (Etype (E));
- else
- Typ := Etype (E);
+ if Is_Access_Type (Typ) then
+ Typ := Directly_Designated_Type (Typ);
+ end if;
+
+ if Is_Class_Wide_Type (Typ) then
+ Typ := Root_Type (Typ);
+ end if;
+
+ -- A legal use of a shadow entity occurs only when the unit
+ -- where the non-limited view resides is imported via a regular
+ -- with clause in the current body. Such references to shadow
+ -- entities may occur in subprogram formals.
+
+ if Is_Incomplete_Type (Typ)
+ and then From_With_Type (Typ)
+ and then Present (Non_Limited_View (Typ))
+ and then Is_Legal_Shadow_Entity_In_Body (Typ)
+ then
+ Typ := Non_Limited_View (Typ);
end if;
if Ekind (Typ) = E_Incomplete_Type
-- Check restriction violations
- Check_Restriction (No_Streams, P);
+ -- First check the No_Streams restriction, which prohibits the use
+ -- of explicit stream attributes in the source program. We do not
+ -- prevent the occurrence of stream attributes in generated code,
+ -- for instance those generated implicitly for dispatching purposes.
+
+ if Comes_From_Source (N) then
+ Check_Restriction (No_Streams, P);
+ end if;
+
+ -- Check special case of Exception_Id and Exception_Occurrence which
+ -- are not allowed for restriction No_Exception_Regstriation.
if Is_RTE (P_Type, RE_Exception_Id)
or else
if Is_Task_Type (Etype (P))
or else (Is_Access_Type (Etype (P))
and then Is_Task_Type (Designated_Type (Etype (P))))
- or else (Ada_Version >= Ada_05
+ or else (Ada_Version >= Ada_2005
and then Ekind (Etype (P)) = E_Class_Wide_Type
and then Is_Interface (Etype (P))
and then Is_Task_Interface (Etype (P)))
Resolve (P);
else
- if Ada_Version >= Ada_05 then
+ if Ada_Version >= Ada_2005 then
Error_Attr_P
("prefix of % attribute must be a task or a task " &
"interface class-wide object");
-- Ada 2005 (AI-345): Ensure that the compiler gives exactly the current
-- output compiling in Ada 95 mode for the case of ambiguous prefixes.
- if Ada_Version < Ada_05
+ if Ada_Version < Ada_2005
and then Is_Overloaded (P)
and then Aname /= Name_Access
and then Aname /= Name_Address
then
Error_Attr ("ambiguous prefix for % attribute", P);
- elsif Ada_Version >= Ada_05
+ elsif Ada_Version >= Ada_2005
and then Is_Overloaded (P)
and then Aname /= Name_Access
and then Aname /= Name_Address
-- entry wrappers, the attributes Count, Caller and AST_Entry require
-- a context check
- if Aname = Name_Count
- or else Aname = Name_Caller
- or else Aname = Name_AST_Entry
+ if Ada_Version >= Ada_2005
+ and then (Aname = Name_Count
+ or else Aname = Name_Caller
+ or else Aname = Name_AST_Entry)
then
declare
Count : Natural := 0;
Error_Attr_P
("prefix of % attribute cannot be Inline_Always" &
" subprogram");
+
+ -- It is illegal to apply 'Address to an intrinsic
+ -- subprogram. This is now formalized in AI05-0095.
+ -- In an instance, an attempt to obtain 'Address of an
+ -- intrinsic subprogram (e.g the renaming of a predefined
+ -- operator that is an actual) raises Program_Error.
+
+ elsif Convention (Ent) = Convention_Intrinsic then
+ if In_Instance then
+ Rewrite (N,
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Address_Of_Intrinsic));
+
+ else
+ Error_Msg_N
+ ("cannot take Address of intrinsic subprogram", N);
+ end if;
+
+ -- Issue an error if prefix denotes an eliminated subprogram
+
+ else
+ Check_For_Eliminated_Subprogram (P, Ent);
end if;
elsif Is_Object (Ent)
and then Base_Type (Typ) = Typ
and then Warn_On_Redundant_Constructs
then
- Error_Msg_NE
- ("?redundant attribute, & is its own base type", N, Typ);
+ Error_Msg_NE -- CODEFIX
+ ("?redundant attribute, & is its own base type", N, Typ);
end if;
Set_Etype (N, Base_Type (Entity (P)));
Check_E0;
Find_Type (N);
+ -- Applying Class to untagged incomplete type is obsolescent in Ada
+ -- 2005. Note that we can't test Is_Tagged_Type here on P_Type, since
+ -- this flag gets set by Find_Type in this situation.
+
+ if Restriction_Check_Required (No_Obsolescent_Features)
+ and then Ada_Version >= Ada_2005
+ and then Ekind (P_Type) = E_Incomplete_Type
+ then
+ declare
+ DN : constant Node_Id := Declaration_Node (P_Type);
+ begin
+ if Nkind (DN) = N_Incomplete_Type_Declaration
+ and then not Tagged_Present (DN)
+ then
+ Check_Restriction (No_Obsolescent_Features, P);
+ end if;
+ end;
+ end if;
+
------------------
-- Code_Address --
------------------
then
Error_Attr ("invalid prefix for % attribute", P);
Set_Address_Taken (Entity (P));
+
+ -- Issue an error if the prefix denotes an eliminated subprogram
+
+ else
+ Check_For_Eliminated_Subprogram (P, Entity (P));
end if;
Set_Etype (N, RTE (RE_Address));
+ ----------------------
+ -- Compiler_Version --
+ ----------------------
+
+ when Attribute_Compiler_Version =>
+ Check_E0;
+ Check_Standard_Prefix;
+ Rewrite (N, Make_String_Literal (Loc, "GNAT " & Gnat_Version_String));
+ Analyze_And_Resolve (N, Standard_String);
+
--------------------
-- Component_Size --
--------------------
-- Case from RM J.4(2) of constrained applied to private type
if Is_Entity_Name (P) and then Is_Type (Entity (P)) then
- Check_Restriction (No_Obsolescent_Features, N);
+ Check_Restriction (No_Obsolescent_Features, P);
if Warn_On_Obsolescent_Feature then
Error_Msg_N
exit;
elsif Ekind (Scope (Ent)) in Task_Kind
- and then Ekind (S) /= E_Loop
- and then Ekind (S) /= E_Block
- and then Ekind (S) /= E_Entry
- and then Ekind (S) /= E_Entry_Family
+ and then
+ not Ekind_In (S, E_Loop, E_Block, E_Entry, E_Entry_Family)
then
Error_Attr ("Attribute % cannot appear in inner unit", N);
-- Ada 2005 (AI-345): Do not consider primitive entry
-- wrappers generated for task or protected types.
- elsif Ada_Version >= Ada_05
+ elsif Ada_Version >= Ada_2005
and then not Comes_From_Source (It.Nam)
then
null;
elsif Is_Task_Type (Etype (P))
or else (Is_Access_Type (Etype (P))
and then Is_Task_Type (Designated_Type (Etype (P))))
- or else (Ada_Version >= Ada_05
+ or else (Ada_Version >= Ada_2005
and then Ekind (Etype (P)) = E_Class_Wide_Type
and then Is_Interface (Etype (P))
and then Is_Task_Interface (Etype (P)))
Set_Etype (N, RTE (RO_AT_Task_Id));
else
- if Ada_Version >= Ada_05 then
+ if Ada_Version >= Ada_2005 then
Error_Attr_P
("prefix of % attribute must be an exception, a " &
"task or a task interface class-wide object");
----------------------
procedure Must_Be_Imported (Proc_Ent : Entity_Id) is
- Pent : Entity_Id := Proc_Ent;
+ Pent : constant Entity_Id := Ultimate_Alias (Proc_Ent);
begin
- while Present (Alias (Pent)) loop
- Pent := Alias (Pent);
- end loop;
-
-- Ignore check if procedure not frozen yet (we will get
-- another chance when the default parameter is reanalyzed)
function Process (N : Node_Id) return Traverse_Result is
begin
if Is_Entity_Name (N)
+ and then Present (Entity (N))
and then not Is_Formal (Entity (N))
and then Enclosing_Subprogram (Entity (N)) = Subp
then
-- Ada 2005 (AI-327): Dynamic ceiling priorities
when Attribute_Priority =>
- if Ada_Version < Ada_05 then
+ if Ada_Version < Ada_2005 then
Error_Attr ("% attribute is allowed only in Ada 2005 mode", P);
end if;
end if;
-- Body case, where we must be inside a generated _Postcondition
- -- procedure, and the prefix must be on the scope stack, or else
+ -- procedure, and the prefix must be on the scope stack, or else
-- the attribute use is definitely misplaced. The condition itself
-- may have generated transient scopes, and is not necessarily the
-- current one.
if Is_Task_Type (P_Type) then
Set_Etype (N, Universal_Integer);
+ -- Use with tasks is an obsolescent feature
+
+ Check_Restriction (No_Obsolescent_Features, P);
+
elsif Is_Access_Type (P_Type) then
if Ekind (P_Type) = E_Access_Subprogram_Type then
Error_Attr_P
Check_Not_Incomplete_Type;
Set_Etype (N, RTE (RE_Type_Class));
- ------------
- -- To_Any --
- ------------
+ --------------
+ -- TypeCode --
+ --------------
when Attribute_TypeCode =>
Check_E0;
Check_PolyORB_Attribute;
Set_Etype (N, RTE (RE_TypeCode));
+ --------------
+ -- Type_Key --
+ --------------
+
+ when Attribute_Type_Key =>
+ Check_E0;
+ Check_Type;
+ declare
+ function Type_Key return String;
+ -- A very preliminary implementation.
+ -- For now, a signature consists of only the type name.
+ -- This is clearly incomplete (e.g., adding a new field to
+ -- a record type should change the type's Type_Key attribute).
+
+ --------------
+ -- Type_Key --
+ --------------
+
+ function Type_Key return String is
+
+ Full_Name : constant String_Id :=
+ Fully_Qualified_Name_String (Entity (P));
+
+ Signature : String
+ (1 .. Integer (String_Length (Full_Name)) - 1);
+ -- Decrement length to omit trailing NUL
+
+ begin
+ for J in Signature'Range loop
+ Signature (J) :=
+ Get_Character (Get_String_Char (Full_Name, Int (J)));
+ end loop;
+
+ return Signature & "'Type_Key";
+ end Type_Key;
+
+ begin
+ Rewrite (N, Make_String_Literal (Loc, Type_Key));
+ end;
+
+ Analyze_And_Resolve (N, Standard_String);
+
-----------------
-- UET_Address --
-----------------
-- processing, since otherwise gigi might see an attribute which it is
-- unprepared to deal with.
- function Aft_Value return Nat;
- -- Computes Aft value for current attribute prefix (used by Aft itself
- -- and also by Width for computing the Width of a fixed point type).
+ procedure Check_Concurrent_Discriminant (Bound : Node_Id);
+ -- If Bound is a reference to a discriminant of a task or protected type
+ -- occurring within the object's body, rewrite attribute reference into
+ -- a reference to the corresponding discriminal. Use for the expansion
+ -- of checks against bounds of entry family index subtypes.
procedure Check_Expressions;
-- In case where the attribute is not foldable, the expressions, if
-- Verify that the prefix of a potentially static array attribute
-- satisfies the conditions of 4.9 (14).
- ---------------
- -- Aft_Value --
- ---------------
+ -----------------------------------
+ -- Check_Concurrent_Discriminant --
+ -----------------------------------
- function Aft_Value return Nat is
- Result : Nat;
- Delta_Val : Ureal;
+ procedure Check_Concurrent_Discriminant (Bound : Node_Id) is
+ Tsk : Entity_Id;
+ -- The concurrent (task or protected) type
begin
- Result := 1;
- Delta_Val := Delta_Value (P_Type);
- while Delta_Val < Ureal_Tenth loop
- Delta_Val := Delta_Val * Ureal_10;
- Result := Result + 1;
- end loop;
+ if Nkind (Bound) = N_Identifier
+ and then Ekind (Entity (Bound)) = E_Discriminant
+ and then Is_Concurrent_Record_Type (Scope (Entity (Bound)))
+ then
+ Tsk := Corresponding_Concurrent_Type (Scope (Entity (Bound)));
+
+ if In_Open_Scopes (Tsk) and then Has_Completion (Tsk) then
- return Result;
- end Aft_Value;
+ -- Find discriminant of original concurrent type, and use
+ -- its current discriminal, which is the renaming within
+ -- the task/protected body.
+
+ Rewrite (N,
+ New_Occurrence_Of
+ (Find_Body_Discriminal (Entity (Bound)), Loc));
+ end if;
+ end if;
+ end Check_Concurrent_Discriminant;
-----------------------
-- Check_Expressions --
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;
---------
when Attribute_Aft =>
- Fold_Uint (N, UI_From_Int (Aft_Value), True);
+ Fold_Uint (N, Aft_Value (P_Type), True);
---------------
-- Alignment --
else
Fold_Uint (N, Expr_Value (Lo_Bound), Static);
end if;
+
+ else
+ Check_Concurrent_Discriminant (Lo_Bound);
end if;
end First_Attr;
else
Fold_Uint (N, Expr_Value (Hi_Bound), Static);
end if;
+
+ else
+ Check_Concurrent_Discriminant (Hi_Bound);
end if;
end Last;
Ind : Node_Id;
begin
- -- In the case of a generic index type, the bounds may
- -- appear static but the computation is not meaningful,
- -- 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;
Set_Bounds;
+ -- For two compile time values, we can compute length
+
if Compile_Time_Known_Value (Lo_Bound)
and then Compile_Time_Known_Value (Hi_Bound)
then
UI_Max (0, 1 + (Expr_Value (Hi_Bound) - Expr_Value (Lo_Bound))),
True);
end if;
+
+ -- One more case is where Hi_Bound and Lo_Bound are compile-time
+ -- comparable, and we can figure out the difference between them.
+
+ declare
+ Diff : aliased Uint;
+
+ begin
+ case
+ Compile_Time_Compare
+ (Lo_Bound, Hi_Bound, Diff'Access, Assume_Valid => False)
+ is
+ when EQ =>
+ Fold_Uint (N, Uint_1, False);
+
+ when GT =>
+ Fold_Uint (N, Uint_0, False);
+
+ when LT =>
+ if Diff /= No_Uint then
+ Fold_Uint (N, Diff + 1, False);
+ end if;
+
+ when others =>
+ null;
+ end case;
+ end;
end Length;
-------------
-- Note: for the folding case, it is fine to treat Machine_Rounding
-- exactly the same way as Rounding, since this is one of the allowed
-- behaviors, and performance is not an issue here. It might be a bit
- -- better to give the same result as it would give at run-time, even
+ -- better to give the same result as it would give at run time, even
-- though the non-determinism is certainly permitted.
when Attribute_Machine_Rounding =>
when Attribute_Range_Length =>
Set_Bounds;
+ -- Can fold if both bounds are compile time known
+
if Compile_Time_Known_Value (Hi_Bound)
and then Compile_Time_Known_Value (Lo_Bound)
then
Static);
end if;
+ -- One more case is where Hi_Bound and Lo_Bound are compile-time
+ -- comparable, and we can figure out the difference between them.
+
+ declare
+ Diff : aliased Uint;
+
+ begin
+ case
+ Compile_Time_Compare
+ (Lo_Bound, Hi_Bound, Diff'Access, Assume_Valid => False)
+ is
+ when EQ =>
+ Fold_Uint (N, Uint_1, False);
+
+ when GT =>
+ Fold_Uint (N, Uint_0, False);
+
+ when LT =>
+ if Diff /= No_Uint then
+ Fold_Uint (N, Diff + 1, False);
+ end if;
+
+ when others =>
+ null;
+ end case;
+ end;
+
---------------
-- Remainder --
---------------
-- For fixed-point type width is Fore + 1 + Aft (RM 3.5(34))
Fold_Uint
- (N, UI_From_Int (Fore_Value + 1 + Aft_Value), True);
+ (N, UI_From_Int (Fore_Value + 1) + Aft_Value (P_Type),
+ True);
end if;
-- Discrete types
-- All wide characters look like Hex_hhhhhhhh
if J > 255 then
- W := 12;
+
+ -- No need to compute this more than once!
+
+ exit;
else
C := Character'Val (J);
case C is
when Reserved_128 | Reserved_129 |
Reserved_132 | Reserved_153
-
=> Wt := 12;
when BS | HT | LF | VT | FF | CR |
SO | SI | EM | FS | GS | RS |
US | RI | MW | ST | PM
-
=> Wt := 2;
when NUL | SOH | STX | ETX | EOT |
SS2 | SS3 | DCS | PU1 | PU2 |
STS | CCH | SPA | EPA | SOS |
SCI | CSI | OSC | APC
-
=> Wt := 3;
when Space .. Tilde |
No_Break_Space .. LC_Y_Diaeresis
-
- => Wt := 3;
+ =>
+ -- Special case of soft hyphen in Ada 2005
+
+ if C = Character'Val (16#AD#)
+ and then Ada_Version >= Ada_2005
+ then
+ Wt := 11;
+ else
+ Wt := 3;
+ end if;
end case;
W := Int'Max (W, Wt);
Attribute_Caller |
Attribute_Class |
Attribute_Code_Address |
+ Attribute_Compiler_Version |
Attribute_Count |
Attribute_Default_Bit_Order |
Attribute_Elaborated |
Attribute_Target_Name |
Attribute_Terminated |
Attribute_To_Address |
+ Attribute_Type_Key |
Attribute_UET_Address |
Attribute_Unchecked_Access |
Attribute_Universal_Literal_String |
-- know will fail, so generate an appropriate warning.
if In_Instance_Body then
- Error_Msg_F
- ("?non-local pointer cannot point to local object", P);
+ Error_Msg_F ("?non-local pointer cannot point to local object", P);
Error_Msg_F
("\?Program_Error will be raised at run time", P);
Rewrite (N,
return;
else
- Error_Msg_F
- ("non-local pointer cannot point to local object", P);
+ Error_Msg_F ("non-local pointer cannot point to local object", P);
-- Check for case where we have a missing access definition
-- also be accessibility checks on those, this is where the
-- checks can eventually be centralized ???
- if Ekind (Btyp) = E_Access_Subprogram_Type
- or else
- Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type
- or else
- Ekind (Btyp) = E_Anonymous_Access_Protected_Subprogram_Type
+ if Ekind_In (Btyp, E_Access_Subprogram_Type,
+ E_Anonymous_Access_Subprogram_Type,
+ E_Anonymous_Access_Protected_Subprogram_Type)
then
-- Deal with convention mismatch
-- Check the static accessibility rule of 3.10.2(32).
-- This rule also applies within the private part of an
-- instantiation. This rule does not apply to anonymous
- -- access-to-subprogram types (Ada 2005).
+ -- access-to-subprogram types in access parameters.
elsif Attr_Id = Attribute_Access
and then not In_Instance_Body
+ and then
+ (Ekind (Btyp) = E_Access_Subprogram_Type
+ or else Is_Local_Anonymous_Access (Btyp))
+
and then Subprogram_Access_Level (Entity (P)) >
Type_Access_Level (Btyp)
- and then Ekind (Btyp) /=
- E_Anonymous_Access_Subprogram_Type
- and then Ekind (Btyp) /=
- E_Anonymous_Access_Protected_Subprogram_Type
then
Error_Msg_F
("subprogram must not be deeper than access type", P);
-- that generic unit. This includes any such attribute that
-- occurs within the body of a generic unit that is a child
-- of the generic unit where the subprogram is declared.
+
-- The rule also prohibits applying the attribute when the
-- access type is a generic formal access type (since the
-- level of the actual type is not known). This restriction
-- when within an instance, because any violations will have
-- been caught by the compilation of the generic unit.
+ -- Note that we relax this check in CodePeer mode for
+ -- compatibility with legacy code, since CodePeer is an
+ -- Ada source code analyzer, not a strict compiler.
+ -- ??? Note that a better approach would be to have a
+ -- separate switch to relax this rule, and enable this
+ -- switch in CodePeer mode.
+
elsif Attr_Id = Attribute_Access
+ and then not CodePeer_Mode
and then not In_Instance
and then Present (Enclosing_Generic_Unit (Entity (P)))
and then Present (Enclosing_Generic_Body (N))
-- The attribute type's ultimate ancestor must be
-- declared within the same generic unit as the
-- subprogram is declared. The error message is
- -- specialized to say "ancestor" for the case where
- -- the access type is not its own ancestor, since
- -- saying simply "access type" would be very confusing.
+ -- specialized to say "ancestor" for the case where the
+ -- access type is not its own ancestor, since saying
+ -- simply "access type" would be very confusing.
if Enclosing_Generic_Unit (Entity (P)) /=
Enclosing_Generic_Unit (Root_Type (Btyp))
Des_Btyp := Designated_Type (Btyp);
- if Ada_Version >= Ada_05
+ if Ada_Version >= Ada_2005
and then Is_Incomplete_Type (Des_Btyp)
then
-- Ada 2005 (AI-412): If the (sub)type is a limited view of an
-- components, and return objects. For a component definition
-- the level is the same of the enclosing composite type.
- if Ada_Version >= Ada_05
+ if Ada_Version >= Ada_2005
and then Is_Local_Anonymous_Access (Btyp)
and then Object_Access_Level (P) > Type_Access_Level (Btyp)
and then Attr_Id = Attribute_Access
elsif Has_Discriminants (Designated_Type (Typ))
and then not Is_Constrained (Des_Btyp)
and then
- (Ada_Version < Ada_05
+ (Ada_Version < Ada_2005
or else
not Has_Constrained_Partial_View
(Designated_Type (Base_Type (Typ))))
end if;
end if;
- if Ekind (Btyp) = E_Access_Protected_Subprogram_Type
- or else
- Ekind (Btyp) = E_Anonymous_Access_Protected_Subprogram_Type
+ if Ekind_In (Btyp, E_Access_Protected_Subprogram_Type,
+ E_Anonymous_Access_Protected_Subprogram_Type)
then
if Is_Entity_Name (P)
and then not Is_Protected_Type (Scope (Entity (P)))
return;
end if;
- elsif (Ekind (Btyp) = E_Access_Subprogram_Type
- or else
- Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type)
+ elsif Ekind_In (Btyp, E_Access_Subprogram_Type,
+ E_Anonymous_Access_Subprogram_Type)
and then Ekind (Etype (N)) = E_Access_Protected_Subprogram_Type
then
Error_Msg_F ("context requires a non-protected subprogram", P);
-- In Ada 2005, Input can invoke Read, and Output can invoke Write
if Nam = TSS_Stream_Input
- and then Ada_Version >= Ada_05
+ and then Ada_Version >= Ada_2005
and then Stream_Attribute_Available (Etyp, TSS_Stream_Read)
then
return True;
elsif Nam = TSS_Stream_Output
- and then Ada_Version >= Ada_05
+ and then Ada_Version >= Ada_2005
and then Stream_Attribute_Available (Etyp, TSS_Stream_Write)
then
return True;
end if;
end loop;
- if Ada_Version < Ada_05 then
+ if Ada_Version < Ada_2005 then
-- In Ada 95 mode, also consider a non-visible definition