Commit 822033eb by Hristian Kirtchev Committed by Arnaud Charlet

exp_ch2.adb: Remove "with" and "use" clauses for Namet and Snames.

2007-04-20  Hristian Kirtchev  <kirtchev@adacore.com>
	    Robert Dewar  <dewar@adacore.com>
	    Ed Schonberg  <schonberg@adacore.com>
	    Gary Dismukes  <dismukes@adacore.com>

	* exp_ch2.adb: Remove "with" and "use" clauses for Namet and Snames.
	Add "with" and "use" clauses for Sem_Attr.
	(Expand_Current_Value): Do not replace occurences of attribute
	references where the prefix must be a simple name.

	* sem_attr.ads, sem_attr.adb: Remove "with" and "use" clauses for
	Namet. Add new arrays Attribute_Name_Modifies_Prefix and
	Attribute_Requires_Simple_Name_Prefix.
	(Name_Modifies_Prefix): Body of new function.
	(Requires_Simple_Name_Prefix): Body of new function.
	(Resolve_Attribute, case Access): Improve error message for case of
	mismatched conventions.
	(Analyze_Attribute, case 'Tag): The prefix the attribute cannot be of an
	incomplete type.
	(Analyze_Attribute, case 'Access): If the type of the prefix is a
	constrained subtype for a nominal unconstrained type, use its base type
	to check for conformance with the context.
	(Resolve_Attribute): Remove test of the access type being associated
	with a return statement from condition for performing accessibility
	checks on access attributes, since this case is now captured by
	Is_Local_Anonymous_Access.
	(Analyze_Access_Attribute): Set Address_Taken on entity
	(Analyze_Attribute, case Address): Set Address_Taken on entity
	(OK_Self_Reference): Traverse tree to locate enclosing aggregate when
	validating an access attribute whose prefix is a current instance.
	(Resolve_Attribute): In case of attributes 'Code_Address and 'Address
	applied to dispatching operations, if freezing is required then we set
	the attribute Has_Delayed_Freeze in the prefix's entity.
	(Check_Local_Access): Set flag Suppress_Value_Tracking_On_Call in
	current scope if access of local subprogram taken
	(Analyze_Access_Attribute): Check legality of self-reference even if the
	expression comes from source, as when a single component association in
	an aggregate has a box association.
	(Resolve_Attribute, case 'Access): Do not apply accessibility checks to
	the prefix if it is a protected operation and the attribute is
	Unrestricted_Access.
	(Resolve_Attribute, case 'Access): Set the Etype of the attribute
	reference to the base type of the context, to force a constraint check
	when the context is an access subtype with an explicit constraint.
	(Analyze_Attribute, case 'Class): If the prefix is an interface and the
	node is rewritten as an interface conversion. leave unanalyzed after
	resolution, to ensure that type checking against the context will take
	place.

From-SVN: r125395
parent 33160237
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 1992-2006, Free Software Foundation, Inc. -- -- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -35,12 +35,12 @@ with Exp_VFpt; use Exp_VFpt; ...@@ -35,12 +35,12 @@ with Exp_VFpt; use Exp_VFpt;
with Nmake; use Nmake; with Nmake; use Nmake;
with Opt; use Opt; with Opt; use Opt;
with Sem; use Sem; with Sem; use Sem;
with Sem_Attr; use Sem_Attr;
with Sem_Eval; use Sem_Eval; with Sem_Eval; use Sem_Eval;
with Sem_Res; use Sem_Res; with Sem_Res; use Sem_Res;
with Sem_Util; use Sem_Util; with Sem_Util; use Sem_Util;
with Sem_Warn; use Sem_Warn; with Sem_Warn; use Sem_Warn;
with Sinfo; use Sinfo; with Sinfo; use Sinfo;
with Snames; use Snames;
with Tbuild; use Tbuild; with Tbuild; use Tbuild;
with Uintp; use Uintp; with Uintp; use Uintp;
...@@ -156,13 +156,12 @@ package body Exp_Ch2 is ...@@ -156,13 +156,12 @@ package body Exp_Ch2 is
and then Nkind (Parent (N)) /= N_Pragma_Argument_Association and then Nkind (Parent (N)) /= N_Pragma_Argument_Association
-- Same for Asm_Input and Asm_Output attribute references -- Same for attribute references that require a simple name prefix
and then not (Nkind (Parent (N)) = N_Attribute_Reference and then not (Nkind (Parent (N)) = N_Attribute_Reference
and then and then Requires_Simple_Name_Prefix (
(Attribute_Name (Parent (N)) = Name_Asm_Input Attribute_Name (Parent (N))))
or else
Attribute_Name (Parent (N)) = Name_Asm_Output))
then then
-- Case of Current_Value is a compile time known value -- Case of Current_Value is a compile time known value
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 1992-2006, Free Software Foundation, Inc. -- -- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -37,7 +37,6 @@ with Expander; use Expander; ...@@ -37,7 +37,6 @@ with Expander; use Expander;
with Freeze; use Freeze; with Freeze; use Freeze;
with Lib; use Lib; with Lib; use Lib;
with Lib.Xref; use Lib.Xref; with Lib.Xref; use Lib.Xref;
with Namet; use Namet;
with Nlists; use Nlists; with Nlists; use Nlists;
with Nmake; use Nmake; with Nmake; use Nmake;
with Opt; use Opt; with Opt; use Opt;
...@@ -79,6 +78,7 @@ package body Sem_Attr is ...@@ -79,6 +78,7 @@ package body Sem_Attr is
-- trouble with cascaded errors. -- trouble with cascaded errors.
-- The following array is the list of attributes defined in the Ada 83 RM -- The following array is the list of attributes defined in the Ada 83 RM
-- that are not included in Ada 95, but still get recognized in GNAT.
Attribute_83 : constant Attribute_Class_Array := Attribute_Class_Array'( Attribute_83 : constant Attribute_Class_Array := Attribute_Class_Array'(
Attribute_Address | Attribute_Address |
...@@ -125,6 +125,40 @@ package body Sem_Attr is ...@@ -125,6 +125,40 @@ package body Sem_Attr is
Attribute_Width => True, Attribute_Width => True,
others => False); others => False);
-- The following array is the list of attributes defined in the Ada 2005
-- RM which are not defined in Ada 95. These are recognized in Ada 95 mode,
-- but in Ada 95 they are considered to be implementation defined.
Attribute_05 : constant Attribute_Class_Array := Attribute_Class_Array'(
Attribute_Machine_Rounding |
Attribute_Priority |
Attribute_Stream_Size |
Attribute_Wide_Wide_Width => True,
others => False);
-- The following array contains all attributes that cause a modification
-- of their prefixes. In a certain sense, the prefix may be considered as
-- an lvalue.
Attribute_Name_Modifies_Prefix : constant Attribute_Class_Array :=
Attribute_Class_Array'(
Attribute_Access |
Attribute_Address |
Attribute_Input |
Attribute_Read |
Attribute_Unchecked_Access => True,
others => False);
-- The following list contains all attributes that require simple names
-- rather than values as their prefixes.
Attribute_Requires_Simple_Name_Prefix : constant Attribute_Class_Array :=
Attribute_Class_Array'(
Attribute_Asm_Input |
Attribute_Asm_Output |
Attribute_Size => True,
others => False);
----------------------- -----------------------
-- Local_Subprograms -- -- Local_Subprograms --
----------------------- -----------------------
...@@ -311,6 +345,10 @@ package body Sem_Attr is ...@@ -311,6 +345,10 @@ package body Sem_Attr is
-- no arguments is used when the caller has already generated the -- no arguments is used when the caller has already generated the
-- required error messages. -- required error messages.
procedure Error_Attr_P (Msg : String);
pragma No_Return (Error_Attr);
-- Like Error_Attr, but error is posted at the start of the prefix
procedure Standard_Attribute (Val : Int); procedure Standard_Attribute (Val : Int);
-- Used to process attributes whose prefix is package Standard which -- Used to process attributes whose prefix is package Standard which
-- yield values of type Universal_Integer. The attribute reference -- yield values of type Universal_Integer. The attribute reference
...@@ -348,7 +386,9 @@ package body Sem_Attr is ...@@ -348,7 +386,9 @@ package body Sem_Attr is
function OK_Self_Reference return Boolean; function OK_Self_Reference return Boolean;
-- An access reference whose prefix is a type can legally appear -- An access reference whose prefix is a type can legally appear
-- within an aggregate, where it is obtained by expansion of -- within an aggregate, where it is obtained by expansion of
-- a defaulted aggregate; -- a defaulted aggregate. The enclosing aggregate that contains
-- the self-referenced is flagged so that the self-reference can
-- be expanded into a reference to the target object (see exp_aggr).
------------------------------ ------------------------------
-- Build_Access_Object_Type -- -- Build_Access_Object_Type --
...@@ -375,9 +415,27 @@ package body Sem_Attr is ...@@ -375,9 +415,27 @@ package body Sem_Attr is
Index : Interp_Index; Index : Interp_Index;
It : Interp; It : Interp;
procedure Check_Local_Access (E : Entity_Id);
-- Deal with possible access to local subprogram. If we have such
-- 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.
function Get_Kind (E : Entity_Id) return Entity_Kind; function Get_Kind (E : Entity_Id) return Entity_Kind;
-- Distinguish between access to regular/protected subprograms -- Distinguish between access to regular/protected subprograms
------------------------
-- Check_Local_Access --
------------------------
procedure Check_Local_Access (E : Entity_Id) is
begin
if not Is_Library_Level_Entity (E) then
Set_Suppress_Value_Tracking_On_Call (Current_Scope);
end if;
end Check_Local_Access;
-------------- --------------
-- Get_Kind -- -- Get_Kind --
-------------- --------------
...@@ -401,6 +459,8 @@ package body Sem_Attr is ...@@ -401,6 +459,8 @@ package body Sem_Attr is
Set_Etype (N, Any_Type); Set_Etype (N, Any_Type);
if not Is_Overloaded (P) then if not Is_Overloaded (P) then
Check_Local_Access (Entity (P));
if not Is_Intrinsic_Subprogram (Entity (P)) then if not Is_Intrinsic_Subprogram (Entity (P)) then
Acc_Type := Acc_Type :=
New_Internal_Entity New_Internal_Entity
...@@ -413,6 +473,8 @@ package body Sem_Attr is ...@@ -413,6 +473,8 @@ package body Sem_Attr is
else else
Get_First_Interp (P, Index, It); Get_First_Interp (P, Index, It);
while Present (It.Nam) loop while Present (It.Nam) loop
Check_Local_Access (It.Nam);
if not Is_Intrinsic_Subprogram (It.Nam) then if not Is_Intrinsic_Subprogram (It.Nam) then
Acc_Type := Acc_Type :=
New_Internal_Entity New_Internal_Entity
...@@ -426,8 +488,12 @@ package body Sem_Attr is ...@@ -426,8 +488,12 @@ package body Sem_Attr is
end loop; end loop;
end if; end if;
-- Cannot be applied to intrinsic. Looking at the tests above,
-- the only way Etype (N) can still be set to Any_Type is if
-- Is_Intrinsic_Subprogram was True for some referenced entity.
if Etype (N) = Any_Type then if Etype (N) = Any_Type then
Error_Attr ("prefix of % attribute cannot be intrinsic", P); Error_Attr_P ("prefix of % attribute cannot be intrinsic");
end if; end if;
end Build_Access_Subprogram_Type; end Build_Access_Subprogram_Type;
...@@ -441,24 +507,25 @@ package body Sem_Attr is ...@@ -441,24 +507,25 @@ package body Sem_Attr is
begin begin
Par := Parent (N); Par := Parent (N);
while Present (Par) while Present (Par)
and then Nkind (Par) in N_Subexpr and then
(Nkind (Par) = N_Component_Association
or else Nkind (Par) in N_Subexpr)
loop loop
exit when Nkind (Par) = N_Aggregate if Nkind (Par) = N_Aggregate
or else Nkind (Par) = N_Extension_Aggregate; or else Nkind (Par) = N_Extension_Aggregate
then
if Etype (Par) = Typ then
Set_Has_Self_Reference (Par);
return True;
end if;
end if;
Par := Parent (Par); Par := Parent (Par);
end loop; end loop;
if Present (Par) -- No enclosing aggregate, or not a self-reference
and then
(Nkind (Par) = N_Aggregate return False;
or else Nkind (Par) = N_Extension_Aggregate)
and then Etype (Par) = Typ
then
Set_Has_Self_Reference (Par);
return True;
else
return False;
end if;
end OK_Self_Reference; end OK_Self_Reference;
-- Start of processing for Analyze_Access_Attribute -- Start of processing for Analyze_Access_Attribute
...@@ -467,8 +534,8 @@ package body Sem_Attr is ...@@ -467,8 +534,8 @@ package body Sem_Attr is
Check_E0; Check_E0;
if Nkind (P) = N_Character_Literal then if Nkind (P) = N_Character_Literal then
Error_Attr Error_Attr_P
("prefix of % attribute cannot be enumeration literal", P); ("prefix of % attribute cannot be enumeration literal");
end if; end if;
-- Case of access to subprogram -- Case of access to subprogram
...@@ -484,9 +551,8 @@ package body Sem_Attr is ...@@ -484,9 +551,8 @@ package body Sem_Attr is
end if; end if;
if Is_Always_Inlined (Entity (P)) then if Is_Always_Inlined (Entity (P)) then
Error_Attr Error_Attr_P
("prefix of % attribute cannot be Inline_Always subprogram", ("prefix of % attribute cannot be Inline_Always subprogram");
P);
end if; end if;
if Aname = Name_Unchecked_Access then if Aname = Name_Unchecked_Access then
...@@ -513,7 +579,7 @@ package body Sem_Attr is ...@@ -513,7 +579,7 @@ package body Sem_Attr is
and then Is_Overloadable (Entity (Selector_Name (P))) and then Is_Overloadable (Entity (Selector_Name (P)))
then then
if Ekind (Entity (Selector_Name (P))) = E_Entry then if Ekind (Entity (Selector_Name (P))) = E_Entry then
Error_Attr ("prefix of % attribute must be subprogram", P); Error_Attr_P ("prefix of % attribute must be subprogram");
end if; end if;
Build_Access_Subprogram_Type (Selector_Name (P)); Build_Access_Subprogram_Type (Selector_Name (P));
...@@ -565,7 +631,7 @@ package body Sem_Attr is ...@@ -565,7 +631,7 @@ package body Sem_Attr is
end; end;
if Nkind (P) = N_Expanded_Name then if Nkind (P) = N_Expanded_Name then
Error_Msg_N Error_Msg_F
("current instance prefix must be a direct name", P); ("current instance prefix must be a direct name", P);
end if; end if;
...@@ -608,8 +674,11 @@ package body Sem_Attr is ...@@ -608,8 +674,11 @@ package body Sem_Attr is
-- OK if self-reference in an aggregate in Ada 2005, and -- OK if self-reference in an aggregate in Ada 2005, and
-- the reference comes from a copied default expression. -- the reference comes from a copied default expression.
-- Note that we check legality of self-reference even if the
-- 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_05
and then not Comes_From_Source (N)
and then OK_Self_Reference and then OK_Self_Reference
then then
null; null;
...@@ -647,31 +716,38 @@ package body Sem_Attr is ...@@ -647,31 +716,38 @@ package body Sem_Attr is
end; end;
end if; end if;
-- If we have an access to an object, and the attribute comes -- Special cases when prefix is entity name
-- from source, then set the object as potentially source modified.
-- We do this because the resulting access pointer can be used to
-- modify the variable, and we might not detect this, leading to
-- some junk warnings.
if Is_Entity_Name (P) then if Is_Entity_Name (P) then
-- If we have an access to an object, and the attribute comes from
-- source, then set the object as potentially source modified. We
-- do this because the resulting access pointer can be used to
-- modify the variable, and we might not detect this, leading to
-- some junk warnings.
Set_Never_Set_In_Source (Entity (P), False); Set_Never_Set_In_Source (Entity (P), False);
-- Mark entity as address taken, and kill current values
Set_Address_Taken (Entity (P));
Kill_Current_Values (Entity (P));
end if; end if;
-- Check for aliased view unless unrestricted case. We allow -- Check for aliased view unless unrestricted case. We allow a
-- a nonaliased prefix when within an instance because the -- nonaliased prefix when within an instance because the prefix may
-- prefix may have been a tagged formal object, which is -- have been a tagged formal object, which is defined to be aliased
-- defined to be aliased even when the actual might not be -- even when the actual might not be (other instance cases will have
-- (other instance cases will have been caught in the generic). -- been caught in the generic). Similarly, within an inlined body we
-- Similarly, within an inlined body we know that the attribute -- know that the attribute is legal in the original subprogram, and
-- is legal in the original subprogram, and therefore legal in -- therefore legal in the expansion.
-- the expansion.
if Aname /= Name_Unrestricted_Access if Aname /= Name_Unrestricted_Access
and then not Is_Aliased_View (P) and then not Is_Aliased_View (P)
and then not In_Instance and then not In_Instance
and then not In_Inlined_Body and then not In_Inlined_Body
then then
Error_Attr ("prefix of % attribute must be aliased", P); Error_Attr_P ("prefix of % attribute must be aliased");
end if; end if;
end Analyze_Access_Attribute; end Analyze_Access_Attribute;
...@@ -788,7 +864,7 @@ package body Sem_Attr is ...@@ -788,7 +864,7 @@ package body Sem_Attr is
-- recovery behavior. -- recovery behavior.
Error_Msg_Name_1 := Aname; Error_Msg_Name_1 := Aname;
Error_Msg_N Error_Msg_F
("prefix for % attribute must be constrained array", P); ("prefix for % attribute must be constrained array", P);
end if; end if;
...@@ -796,15 +872,14 @@ package body Sem_Attr is ...@@ -796,15 +872,14 @@ package body Sem_Attr is
else else
if Is_Private_Type (P_Type) then if Is_Private_Type (P_Type) then
Error_Attr Error_Attr_P ("prefix for % attribute may not be private type");
("prefix for % attribute may not be private type", P);
elsif Is_Access_Type (P_Type) elsif Is_Access_Type (P_Type)
and then Is_Array_Type (Designated_Type (P_Type)) and then Is_Array_Type (Designated_Type (P_Type))
and then Is_Entity_Name (P) and then Is_Entity_Name (P)
and then Is_Type (Entity (P)) and then Is_Type (Entity (P))
then then
Error_Attr ("prefix of % attribute cannot be access type", P); Error_Attr_P ("prefix of % attribute cannot be access type");
elsif Attr_Id = Attribute_First elsif Attr_Id = Attribute_First
or else or else
...@@ -813,7 +888,7 @@ package body Sem_Attr is ...@@ -813,7 +888,7 @@ package body Sem_Attr is
Error_Attr ("invalid prefix for % attribute", P); Error_Attr ("invalid prefix for % attribute", P);
else else
Error_Attr ("prefix for % attribute must be array", P); Error_Attr_P ("prefix for % attribute must be array");
end if; end if;
end if; end if;
...@@ -888,8 +963,7 @@ package body Sem_Attr is ...@@ -888,8 +963,7 @@ package body Sem_Attr is
and then and then
Ekind (Entity (Selector_Name (P))) /= E_Discriminant) Ekind (Entity (Selector_Name (P))) /= E_Discriminant)
then then
Error_Attr Error_Attr_P ("prefix for % attribute must be selected component");
("prefix for % attribute must be selected component", P);
end if; end if;
end Check_Component; end Check_Component;
...@@ -902,8 +976,7 @@ package body Sem_Attr is ...@@ -902,8 +976,7 @@ package body Sem_Attr is
Check_Type; Check_Type;
if not Is_Decimal_Fixed_Point_Type (P_Type) then if not Is_Decimal_Fixed_Point_Type (P_Type) then
Error_Attr Error_Attr_P ("prefix of % attribute must be decimal type");
("prefix of % attribute must be decimal type", P);
end if; end if;
end Check_Decimal_Fixed_Point_Type; end Check_Decimal_Fixed_Point_Type;
...@@ -958,7 +1031,7 @@ package body Sem_Attr is ...@@ -958,7 +1031,7 @@ package body Sem_Attr is
Check_Type; Check_Type;
if not Is_Discrete_Type (P_Type) then if not Is_Discrete_Type (P_Type) then
Error_Attr ("prefix of % attribute must be discrete type", P); Error_Attr_P ("prefix of % attribute must be discrete type");
end if; end if;
end Check_Discrete_Type; end Check_Discrete_Type;
...@@ -1054,7 +1127,7 @@ package body Sem_Attr is ...@@ -1054,7 +1127,7 @@ package body Sem_Attr is
Check_Type; Check_Type;
if not Is_Fixed_Point_Type (P_Type) then if not Is_Fixed_Point_Type (P_Type) then
Error_Attr ("prefix of % attribute must be fixed point type", P); Error_Attr_P ("prefix of % attribute must be fixed point type");
end if; end if;
end Check_Fixed_Point_Type; end Check_Fixed_Point_Type;
...@@ -1077,7 +1150,7 @@ package body Sem_Attr is ...@@ -1077,7 +1150,7 @@ package body Sem_Attr is
Check_Type; Check_Type;
if not Is_Floating_Point_Type (P_Type) then if not Is_Floating_Point_Type (P_Type) then
Error_Attr ("prefix of % attribute must be float type", P); Error_Attr_P ("prefix of % attribute must be float type");
end if; end if;
end Check_Floating_Point_Type; end Check_Floating_Point_Type;
...@@ -1120,7 +1193,7 @@ package body Sem_Attr is ...@@ -1120,7 +1193,7 @@ package body Sem_Attr is
Check_Type; Check_Type;
if not Is_Integer_Type (P_Type) then if not Is_Integer_Type (P_Type) then
Error_Attr ("prefix of % attribute must be integer type", P); Error_Attr_P ("prefix of % attribute must be integer type");
end if; end if;
end Check_Integer_Type; end Check_Integer_Type;
...@@ -1131,7 +1204,7 @@ package body Sem_Attr is ...@@ -1131,7 +1204,7 @@ package body Sem_Attr is
procedure Check_Library_Unit is procedure Check_Library_Unit is
begin begin
if not Is_Compilation_Unit (Entity (P)) then if not Is_Compilation_Unit (Entity (P)) then
Error_Attr ("prefix of % attribute must be library unit", P); Error_Attr_P ("prefix of % attribute must be library unit");
end if; end if;
end Check_Library_Unit; end Check_Library_Unit;
...@@ -1144,8 +1217,8 @@ package body Sem_Attr is ...@@ -1144,8 +1217,8 @@ package body Sem_Attr is
Check_Type; Check_Type;
if not Is_Modular_Integer_Type (P_Type) then if not Is_Modular_Integer_Type (P_Type) then
Error_Attr Error_Attr_P
("prefix of % attribute must be modular integer type", P); ("prefix of % attribute must be modular integer type");
end if; end if;
end Check_Modular_Integer_Type; end Check_Modular_Integer_Type;
...@@ -1188,8 +1261,8 @@ package body Sem_Attr is ...@@ -1188,8 +1261,8 @@ package body Sem_Attr is
end loop; end loop;
if From_With_Type (Etype (E)) then if From_With_Type (Etype (E)) then
Error_Attr Error_Attr_P
("prefix of % attribute cannot be an incomplete type", P); ("prefix of % attribute cannot be an incomplete type");
else else
if Is_Access_Type (Etype (E)) then if Is_Access_Type (Etype (E)) then
...@@ -1201,8 +1274,8 @@ package body Sem_Attr is ...@@ -1201,8 +1274,8 @@ package body Sem_Attr is
if Ekind (Typ) = E_Incomplete_Type if Ekind (Typ) = E_Incomplete_Type
and then No (Full_View (Typ)) and then No (Full_View (Typ))
then then
Error_Attr Error_Attr_P
("prefix of % attribute cannot be an incomplete type", P); ("prefix of % attribute cannot be an incomplete type");
end if; end if;
end if; end if;
end if; end if;
...@@ -1242,7 +1315,7 @@ package body Sem_Attr is ...@@ -1242,7 +1315,7 @@ package body Sem_Attr is
-- Otherwise we must have an object reference -- Otherwise we must have an object reference
elsif not Is_Object_Reference (P) then elsif not Is_Object_Reference (P) then
Error_Attr ("prefix of % attribute must be object", P); Error_Attr_P ("prefix of % attribute must be object");
end if; end if;
end Check_Object_Reference; end Check_Object_Reference;
...@@ -1274,7 +1347,7 @@ package body Sem_Attr is ...@@ -1274,7 +1347,7 @@ package body Sem_Attr is
end; end;
end if; end if;
Error_Attr ("prefix of % attribute must be program unit", P); Error_Attr_P ("prefix of % attribute must be program unit");
end Check_Program_Unit; end Check_Program_Unit;
--------------------- ---------------------
...@@ -1286,7 +1359,7 @@ package body Sem_Attr is ...@@ -1286,7 +1359,7 @@ package body Sem_Attr is
Check_Type; Check_Type;
if not Is_Real_Type (P_Type) then if not Is_Real_Type (P_Type) then
Error_Attr ("prefix of % attribute must be real type", P); Error_Attr_P ("prefix of % attribute must be real type");
end if; end if;
end Check_Real_Type; end Check_Real_Type;
...@@ -1299,7 +1372,7 @@ package body Sem_Attr is ...@@ -1299,7 +1372,7 @@ package body Sem_Attr is
Check_Type; Check_Type;
if not Is_Scalar_Type (P_Type) then if not Is_Scalar_Type (P_Type) then
Error_Attr ("prefix of % attribute must be scalar type", P); Error_Attr_P ("prefix of % attribute must be scalar type");
end if; end if;
end Check_Scalar_Type; end Check_Scalar_Type;
...@@ -1443,11 +1516,12 @@ package body Sem_Attr is ...@@ -1443,11 +1516,12 @@ package body Sem_Attr is
else else
if Ada_Version >= Ada_05 then if Ada_Version >= Ada_05 then
Error_Attr ("prefix of % attribute must be a task or a task " Error_Attr_P
& "interface class-wide object", P); ("prefix of % attribute must be a task or a task " &
"interface class-wide object");
else else
Error_Attr ("prefix of % attribute must be a task", P); Error_Attr_P ("prefix of % attribute must be a task");
end if; end if;
end if; end if;
end Check_Task_Prefix; end Check_Task_Prefix;
...@@ -1465,7 +1539,7 @@ package body Sem_Attr is ...@@ -1465,7 +1539,7 @@ package body Sem_Attr is
if not Is_Entity_Name (P) if not Is_Entity_Name (P)
or else not Is_Type (Entity (P)) or else not Is_Type (Entity (P))
then then
Error_Attr ("prefix of % attribute must be a type", P); Error_Attr_P ("prefix of % attribute must be a type");
elsif Ekind (Entity (P)) = E_Incomplete_Type elsif Ekind (Entity (P)) = E_Incomplete_Type
and then Present (Full_View (Entity (P))) and then Present (Full_View (Entity (P)))
...@@ -1513,6 +1587,17 @@ package body Sem_Attr is ...@@ -1513,6 +1587,17 @@ package body Sem_Attr is
Error_Attr; Error_Attr;
end Error_Attr; end Error_Attr;
------------------
-- Error_Attr_P --
------------------
procedure Error_Attr_P (Msg : String) is
begin
Error_Msg_Name_1 := Aname;
Error_Msg_F (Msg, P);
Error_Attr;
end Error_Attr_P;
---------------------------- ----------------------------
-- Legal_Formal_Attribute -- -- Legal_Formal_Attribute --
---------------------------- ----------------------------
...@@ -1524,7 +1609,7 @@ package body Sem_Attr is ...@@ -1524,7 +1609,7 @@ package body Sem_Attr is
if not Is_Entity_Name (P) if not Is_Entity_Name (P)
or else not Is_Type (Entity (P)) or else not Is_Type (Entity (P))
then then
Error_Attr ("prefix of % attribute must be generic type", N); Error_Attr_P ("prefix of % attribute must be generic type");
elsif Is_Generic_Actual_Type (Entity (P)) elsif Is_Generic_Actual_Type (Entity (P))
or else In_Instance or else In_Instance
...@@ -1534,13 +1619,13 @@ package body Sem_Attr is ...@@ -1534,13 +1619,13 @@ package body Sem_Attr is
elsif Is_Generic_Type (Entity (P)) then elsif Is_Generic_Type (Entity (P)) then
if not Is_Indefinite_Subtype (Entity (P)) then if not Is_Indefinite_Subtype (Entity (P)) then
Error_Attr Error_Attr_P
("prefix of % attribute must be indefinite generic type", N); ("prefix of % attribute must be indefinite generic type");
end if; end if;
else else
Error_Attr Error_Attr_P
("prefix of % attribute must be indefinite generic type", N); ("prefix of % attribute must be indefinite generic type");
end if; end if;
Set_Etype (N, Standard_Boolean); Set_Etype (N, Standard_Boolean);
...@@ -1674,7 +1759,7 @@ package body Sem_Attr is ...@@ -1674,7 +1759,7 @@ package body Sem_Attr is
raise Bad_Attribute; raise Bad_Attribute;
end if; end if;
-- Deal with Ada 83 and Features issues -- Deal with Ada 83 issues
if Comes_From_Source (N) then if Comes_From_Source (N) then
if not Attribute_83 (Attr_Id) then if not Attribute_83 (Attr_Id) then
...@@ -1689,6 +1774,12 @@ package body Sem_Attr is ...@@ -1689,6 +1774,12 @@ package body Sem_Attr is
end if; end if;
end if; end if;
-- Deal with Ada 2005 issues
if Attribute_05 (Attr_Id) and then Ada_Version <= Ada_95 then
Check_Restriction (No_Implementation_Attributes, N);
end if;
-- Remote access to subprogram type access attribute reference needs -- Remote access to subprogram type access attribute reference needs
-- unanalyzed copy for tree transformation. The analyzed copy is used -- unanalyzed copy for tree transformation. The analyzed copy is used
-- for its semantic information (whether prefix is a remote subprogram -- for its semantic information (whether prefix is a remote subprogram
...@@ -1899,45 +1990,25 @@ package body Sem_Attr is ...@@ -1899,45 +1990,25 @@ package body Sem_Attr is
begin begin
if Is_Subprogram (Ent) then if Is_Subprogram (Ent) then
if not Is_Library_Level_Entity (Ent) if not Is_Library_Level_Entity (Ent) then
-- Do not take into account nodes generated by the
-- expander for the elaboration of the dispatch tables;
-- otherwise we erroneously generate warnings indicating
-- violation of restriction No_Implicit_Dynamic_Code
-- with those nodes.
and then not (Is_Dispatching_Operation (Ent)
and then Nkind (Parent (N)) = N_Assignment_Statement
and then Nkind (Name (Parent (N))) = N_Indexed_Component
and then Nkind (Prefix (Name (Parent (N)))) =
N_Selected_Component
and then Nkind (Selector_Name
(Prefix (Name (Parent (N))))) =
N_Identifier
and then Present (Entity (Selector_Name
(Prefix (Name (Parent (N))))))
and then Entity (Selector_Name
(Prefix (Name (Parent (N))))) =
RTE_Record_Component (RE_Prims_Ptr))
then
Check_Restriction (No_Implicit_Dynamic_Code, P); Check_Restriction (No_Implicit_Dynamic_Code, P);
end if; end if;
Set_Address_Taken (Ent); Set_Address_Taken (Ent);
Kill_Current_Values (Ent);
-- An Address attribute is accepted when generated by -- An Address attribute is accepted when generated by the
-- the compiler for dispatching operation, and an error -- compiler for dispatching operation, and an error is
-- is issued once the subprogram is frozen (to avoid -- issued once the subprogram is frozen (to avoid confusing
-- confusing errors about implicit uses of Address in -- errors about implicit uses of Address in the dispatch
-- the dispatch table initialization). -- table initialization).
if Is_Always_Inlined (Entity (P)) if Is_Always_Inlined (Entity (P))
and then Comes_From_Source (P) and then Comes_From_Source (P)
then then
Error_Attr Error_Attr_P
("prefix of % attribute cannot be Inline_Always" & ("prefix of % attribute cannot be Inline_Always" &
" subprogram", P); " subprogram");
end if; end if;
elsif Is_Object (Ent) elsif Is_Object (Ent)
...@@ -2083,7 +2154,7 @@ package body Sem_Attr is ...@@ -2083,7 +2154,7 @@ package body Sem_Attr is
procedure Bad_AST_Entry is procedure Bad_AST_Entry is
begin begin
Error_Attr ("prefix for % attribute must be task entry", P); Error_Attr_P ("prefix for % attribute must be task entry");
end Bad_AST_Entry; end Bad_AST_Entry;
function OK_Entry (E : Entity_Id) return Boolean is function OK_Entry (E : Entity_Id) return Boolean is
...@@ -2099,8 +2170,7 @@ package body Sem_Attr is ...@@ -2099,8 +2170,7 @@ package body Sem_Attr is
if Result then if Result then
if not Is_AST_Entry (E) then if not Is_AST_Entry (E) then
Error_Msg_Name_2 := Aname; Error_Msg_Name_2 := Aname;
Error_Attr Error_Attr ("% attribute requires previous % pragma", P);
("% attribute requires previous % pragma", P);
end if; end if;
end if; end if;
...@@ -2195,14 +2265,14 @@ package body Sem_Attr is ...@@ -2195,14 +2265,14 @@ package body Sem_Attr is
and then not Is_Scalar_Type (Typ) and then not Is_Scalar_Type (Typ)
and then not Is_Generic_Type (Typ) and then not Is_Generic_Type (Typ)
then then
Error_Msg_N ("prefix of Base attribute must be scalar type", N); Error_Attr_P ("prefix of Base attribute must be scalar type");
elsif Sloc (Typ) = Standard_Location elsif Sloc (Typ) = Standard_Location
and then Base_Type (Typ) = Typ and then Base_Type (Typ) = Typ
and then Warn_On_Redundant_Constructs and then Warn_On_Redundant_Constructs
then then
Error_Msg_NE Error_Msg_NE
("?redudant attribute, & is its own base type", N, Typ); ("?redudant attribute, & is its own base type", N, Typ);
end if; end if;
Set_Etype (N, Base_Type (Entity (P))); Set_Etype (N, Base_Type (Entity (P)));
...@@ -2248,7 +2318,7 @@ package body Sem_Attr is ...@@ -2248,7 +2318,7 @@ package body Sem_Attr is
Check_E0; Check_E0;
if not Is_Object_Reference (P) then if not Is_Object_Reference (P) then
Error_Attr ("prefix for % attribute must be object", P); Error_Attr_P ("prefix for % attribute must be object");
-- What about the access object cases ??? -- What about the access object cases ???
...@@ -2269,7 +2339,7 @@ package body Sem_Attr is ...@@ -2269,7 +2339,7 @@ package body Sem_Attr is
Check_Type; Check_Type;
if not Is_Record_Type (P_Type) then if not Is_Record_Type (P_Type) then
Error_Attr ("prefix of % attribute must be record type", P); Error_Attr_P ("prefix of % attribute must be record type");
end if; end if;
if Bytes_Big_Endian xor Reverse_Bit_Order (P_Type) then if Bytes_Big_Endian xor Reverse_Bit_Order (P_Type) then
...@@ -2408,6 +2478,14 @@ package body Sem_Attr is ...@@ -2408,6 +2478,14 @@ package body Sem_Attr is
or else Is_Interface (Etype (E1)) or else Is_Interface (Etype (E1))
then then
Analyze_And_Resolve (N, Etype (P)); Analyze_And_Resolve (N, Etype (P));
-- However, the attribute is a name that occurs in a context
-- that imposes its own type. Leave the result unanalyzed,
-- so that type checking with the context type take place.
-- on the new conversion node, otherwise Resolve is a noop.
Set_Analyzed (N, False);
else else
Analyze (N); Analyze (N);
end if; end if;
...@@ -2417,7 +2495,6 @@ package body Sem_Attr is ...@@ -2417,7 +2495,6 @@ package body Sem_Attr is
else else
Find_Type (N); Find_Type (N);
end if; end if;
end Class; end Class;
------------------ ------------------
...@@ -2552,8 +2629,8 @@ package body Sem_Attr is ...@@ -2552,8 +2629,8 @@ package body Sem_Attr is
-- Fall through if bad prefix -- Fall through if bad prefix
Error_Attr Error_Attr_P
("prefix of % attribute must be object of discriminated type", P); ("prefix of % attribute must be object of discriminated type");
--------------- ---------------
-- Copy_Sign -- -- Copy_Sign --
...@@ -2749,8 +2826,8 @@ package body Sem_Attr is ...@@ -2749,8 +2826,8 @@ package body Sem_Attr is
if not Is_Floating_Point_Type (P_Type) if not Is_Floating_Point_Type (P_Type)
and then not Is_Decimal_Fixed_Point_Type (P_Type) and then not Is_Decimal_Fixed_Point_Type (P_Type)
then then
Error_Attr Error_Attr_P
("prefix of % attribute must be float or decimal type", P); ("prefix of % attribute must be float or decimal type");
end if; end if;
Set_Etype (N, Universal_Integer); Set_Etype (N, Universal_Integer);
...@@ -2812,9 +2889,9 @@ package body Sem_Attr is ...@@ -2812,9 +2889,9 @@ package body Sem_Attr is
and then and then
Ekind (Entity (P)) /= E_Enumeration_Literal) Ekind (Entity (P)) /= E_Enumeration_Literal)
then then
Error_Attr Error_Attr_P
("prefix of %attribute must be " & ("prefix of %attribute must be " &
"discrete type/object or enum literal", P); "discrete type/object or enum literal");
end if; end if;
end if; end if;
...@@ -2849,7 +2926,7 @@ package body Sem_Attr is ...@@ -2849,7 +2926,7 @@ package body Sem_Attr is
Set_Etype (N, Standard_String); Set_Etype (N, Standard_String);
if not Is_Tagged_Type (P_Type) then if not Is_Tagged_Type (P_Type) then
Error_Attr ("prefix of % attribute must be tagged", P); Error_Attr_P ("prefix of % attribute must be tagged");
end if; end if;
----------- -----------
...@@ -2946,11 +3023,12 @@ package body Sem_Attr is ...@@ -2946,11 +3023,12 @@ package body Sem_Attr is
else else
if Ada_Version >= Ada_05 then if Ada_Version >= Ada_05 then
Error_Attr ("prefix of % attribute must be an exception, a " Error_Attr_P
& "task or a task interface class-wide object", P); ("prefix of % attribute must be an exception, a " &
"task or a task interface class-wide object");
else else
Error_Attr ("prefix of % attribute must be a task or an " Error_Attr_P
& "exception", P); ("prefix of % attribute must be a task or an exception");
end if; end if;
end if; end if;
...@@ -2992,8 +3070,8 @@ package body Sem_Attr is ...@@ -2992,8 +3070,8 @@ package body Sem_Attr is
if not Is_Scalar_Type (P_Type) if not Is_Scalar_Type (P_Type)
or else (Is_Entity_Name (P) and then Is_Type (Entity (P))) or else (Is_Entity_Name (P) and then Is_Type (Entity (P)))
then then
Error_Attr Error_Attr_P
("prefix of % attribute must be scalar object name", N); ("prefix of % attribute must be scalar object name");
end if; end if;
Check_Enum_Image; Check_Enum_Image;
...@@ -3184,7 +3262,7 @@ package body Sem_Attr is ...@@ -3184,7 +3262,7 @@ package body Sem_Attr is
if not Is_Entity_Name (P) if not Is_Entity_Name (P)
or else not Is_Subprogram (Entity (P)) or else not Is_Subprogram (Entity (P))
then then
Error_Attr ("prefix of % attribute must be subprogram", P); Error_Attr_P ("prefix of % attribute must be subprogram");
end if; end if;
Check_Either_E0_Or_E1; Check_Either_E0_Or_E1;
...@@ -3405,8 +3483,8 @@ package body Sem_Attr is ...@@ -3405,8 +3483,8 @@ package body Sem_Attr is
if P_Type /= Any_Type then if P_Type /= Any_Type then
if not Is_Library_Level_Entity (Entity (P)) then if not Is_Library_Level_Entity (Entity (P)) then
Error_Attr Error_Attr_P
("prefix of % attribute must be library-level entity", P); ("prefix of % attribute must be library-level entity");
-- The defining entity of prefix should not be declared inside -- The defining entity of prefix should not be declared inside
-- a Pure unit. RM E.1(8). -- a Pure unit. RM E.1(8).
...@@ -3415,8 +3493,8 @@ package body Sem_Attr is ...@@ -3415,8 +3493,8 @@ package body Sem_Attr is
elsif Is_Entity_Name (P) elsif Is_Entity_Name (P)
and then Is_Pure (Entity (P)) and then Is_Pure (Entity (P))
then then
Error_Attr Error_Attr_P
("prefix of % attribute must not be declared pure", P); ("prefix of % attribute must not be declared pure");
end if; end if;
end if; end if;
...@@ -3505,7 +3583,7 @@ package body Sem_Attr is ...@@ -3505,7 +3583,7 @@ package body Sem_Attr is
then then
Resolve (P, Etype (P)); Resolve (P, Etype (P));
else else
Error_Attr ("prefix of % attribute must be a protected object", P); Error_Attr_P ("prefix of % attribute must be a protected object");
end if; end if;
Set_Etype (N, Standard_Integer); Set_Etype (N, Standard_Integer);
...@@ -3718,7 +3796,7 @@ package body Sem_Attr is ...@@ -3718,7 +3796,7 @@ package body Sem_Attr is
null; null;
else else
Error_Attr ("invalid prefix for % attribute", P); Error_Attr_P ("invalid prefix for % attribute");
end if; end if;
Check_Not_Incomplete_Type; Check_Not_Incomplete_Type;
...@@ -3742,8 +3820,8 @@ package body Sem_Attr is ...@@ -3742,8 +3820,8 @@ package body Sem_Attr is
Check_E0; Check_E0;
if Ekind (P_Type) = E_Access_Subprogram_Type then if Ekind (P_Type) = E_Access_Subprogram_Type then
Error_Attr Error_Attr_P
("cannot use % attribute for access-to-subprogram type", P); ("cannot use % attribute for access-to-subprogram type");
end if; end if;
-- Set appropriate entity -- Set appropriate entity
...@@ -3763,7 +3841,7 @@ package body Sem_Attr is ...@@ -3763,7 +3841,7 @@ package body Sem_Attr is
Validate_Remote_Access_To_Class_Wide_Type (N); Validate_Remote_Access_To_Class_Wide_Type (N);
else else
Error_Attr ("prefix of % attribute must be access type", P); Error_Attr_P ("prefix of % attribute must be access type");
end if; end if;
------------------ ------------------
...@@ -3777,8 +3855,8 @@ package body Sem_Attr is ...@@ -3777,8 +3855,8 @@ package body Sem_Attr is
elsif Is_Access_Type (P_Type) then elsif Is_Access_Type (P_Type) then
if Ekind (P_Type) = E_Access_Subprogram_Type then if Ekind (P_Type) = E_Access_Subprogram_Type then
Error_Attr Error_Attr_P
("cannot use % attribute for access-to-subprogram type", P); ("cannot use % attribute for access-to-subprogram type");
end if; end if;
if Is_Entity_Name (P) if Is_Entity_Name (P)
...@@ -3804,8 +3882,7 @@ package body Sem_Attr is ...@@ -3804,8 +3882,7 @@ package body Sem_Attr is
end if; end if;
else else
Error_Attr Error_Attr_P ("prefix of % attribute must be access or task type");
("prefix of % attribute must be access or task type", P);
end if; end if;
------------------ ------------------
...@@ -3828,7 +3905,7 @@ package body Sem_Attr is ...@@ -3828,7 +3905,7 @@ package body Sem_Attr is
then then
Set_Etype (N, Universal_Integer); Set_Etype (N, Universal_Integer);
else else
Error_Attr ("invalid prefix for % attribute", P); Error_Attr_P ("invalid prefix for % attribute");
end if; end if;
--------------- ---------------
...@@ -3843,8 +3920,8 @@ package body Sem_Attr is ...@@ -3843,8 +3920,8 @@ package body Sem_Attr is
Rewrite (N, Rewrite (N,
New_Occurrence_Of (Corresponding_Stub_Type (P_Type), Loc)); New_Occurrence_Of (Corresponding_Stub_Type (P_Type), Loc));
else else
Error_Attr Error_Attr_P
("prefix of% attribute must be remote access to classwide", P); ("prefix of% attribute must be remote access to classwide");
end if; end if;
---------- ----------
...@@ -3881,7 +3958,7 @@ package body Sem_Attr is ...@@ -3881,7 +3958,7 @@ package body Sem_Attr is
Check_Dereference; Check_Dereference;
if not Is_Tagged_Type (P_Type) then if not Is_Tagged_Type (P_Type) then
Error_Attr ("prefix of % attribute must be tagged", P); Error_Attr_P ("prefix of % attribute must be tagged");
-- Next test does not apply to generated code -- Next test does not apply to generated code
-- why not, and what does the illegal reference mean??? -- why not, and what does the illegal reference mean???
...@@ -3890,11 +3967,18 @@ package body Sem_Attr is ...@@ -3890,11 +3967,18 @@ package body Sem_Attr is
and then not Is_Class_Wide_Type (P_Type) and then not Is_Class_Wide_Type (P_Type)
and then Comes_From_Source (N) and then Comes_From_Source (N)
then then
Error_Attr Error_Attr_P
("% attribute can only be applied to objects of class-wide type", ("% attribute can only be applied to objects " &
P); "of class - wide type");
end if; end if;
-- The prefix cannot be an incomplete type. However, references
-- to 'Tag can be generated when expanding interface conversions,
-- and this is legal.
if Comes_From_Source (N) then
Check_Not_Incomplete_Type;
end if;
Set_Etype (N, RTE (RE_Tag)); Set_Etype (N, RTE (RE_Tag));
----------------- -----------------
...@@ -3941,7 +4025,7 @@ package body Sem_Attr is ...@@ -3941,7 +4025,7 @@ package body Sem_Attr is
if Nkind (P) /= N_Identifier if Nkind (P) /= N_Identifier
or else Chars (P) /= Name_System or else Chars (P) /= Name_System
then then
Error_Attr ("prefix of %attribute must be System", P); Error_Attr_P ("prefix of %attribute must be System");
end if; end if;
Generate_Reference (RTE (RE_Address), P); Generate_Reference (RTE (RE_Address), P);
...@@ -4024,7 +4108,7 @@ package body Sem_Attr is ...@@ -4024,7 +4108,7 @@ package body Sem_Attr is
if not Is_Entity_Name (P) if not Is_Entity_Name (P)
or else Ekind (Entity (P)) not in Named_Kind or else Ekind (Entity (P)) not in Named_Kind
then then
Error_Attr ("prefix for % attribute must be named number", P); Error_Attr_P ("prefix for % attribute must be named number");
else else
declare declare
...@@ -4125,7 +4209,7 @@ package body Sem_Attr is ...@@ -4125,7 +4209,7 @@ package body Sem_Attr is
end if; end if;
if not Is_Scalar_Type (P_Type) then if not Is_Scalar_Type (P_Type) then
Error_Attr ("object for % attribute must be of scalar type", P); Error_Attr_P ("object for % attribute must be of scalar type");
end if; end if;
Set_Etype (N, Standard_Boolean); Set_Etype (N, Standard_Boolean);
...@@ -6946,6 +7030,26 @@ package body Sem_Attr is ...@@ -6946,6 +7030,26 @@ package body Sem_Attr is
and then Associated_Node_For_Itype (Anon) = Parent (Typ); and then Associated_Node_For_Itype (Anon) = Parent (Typ);
end Is_Anonymous_Tagged_Base; end Is_Anonymous_Tagged_Base;
--------------------------
-- Name_Modifies_Prefix --
--------------------------
function Name_Modifies_Prefix (Nam : Name_Id) return Boolean is
pragma Assert (Is_Attribute_Name (Nam));
begin
return Attribute_Name_Modifies_Prefix (Get_Attribute_Id (Nam));
end Name_Modifies_Prefix;
---------------------------------
-- Requires_Simple_Name_Prefix --
---------------------------------
function Requires_Simple_Name_Prefix (Nam : Name_Id) return Boolean is
pragma Assert (Is_Attribute_Name (Nam));
begin
return Attribute_Requires_Simple_Name_Prefix (Get_Attribute_Id (Nam));
end Requires_Simple_Name_Prefix;
----------------------- -----------------------
-- Resolve_Attribute -- -- Resolve_Attribute --
----------------------- -----------------------
...@@ -6977,9 +7081,9 @@ package body Sem_Attr is ...@@ -6977,9 +7081,9 @@ package body Sem_Attr is
-- know will fail, so generate an appropriate warning. -- know will fail, so generate an appropriate warning.
if In_Instance_Body then if In_Instance_Body then
Error_Msg_N Error_Msg_F
("?non-local pointer cannot point to local object", P); ("?non-local pointer cannot point to local object", P);
Error_Msg_N Error_Msg_F
("\?Program_Error will be raised at run time", P); ("\?Program_Error will be raised at run time", P);
Rewrite (N, Rewrite (N,
Make_Raise_Program_Error (Loc, Make_Raise_Program_Error (Loc,
...@@ -6988,7 +7092,7 @@ package body Sem_Attr is ...@@ -6988,7 +7092,7 @@ package body Sem_Attr is
return; return;
else else
Error_Msg_N Error_Msg_F
("non-local pointer cannot point to local object", P); ("non-local pointer cannot point to local object", P);
-- Check for case where we have a missing access definition -- Check for case where we have a missing access definition
...@@ -7009,8 +7113,8 @@ package body Sem_Attr is ...@@ -7009,8 +7113,8 @@ package body Sem_Attr is
if Present (Indic) then if Present (Indic) then
Error_Msg_NE Error_Msg_NE
("\use an access definition for" & ("\use an access definition for" &
" the access discriminant of&", N, " the access discriminant of&",
Entity (Subtype_Mark (Indic))); N, Entity (Subtype_Mark (Indic)));
end if; end if;
end if; end if;
end if; end if;
...@@ -7106,24 +7210,20 @@ package body Sem_Attr is ...@@ -7106,24 +7210,20 @@ package body Sem_Attr is
elsif Is_Overloadable (Entity (P)) elsif Is_Overloadable (Entity (P))
and then Is_Abstract_Subprogram (Entity (P)) and then Is_Abstract_Subprogram (Entity (P))
then then
Error_Msg_N ("prefix of % attribute cannot be abstract", P); Error_Msg_F ("prefix of % attribute cannot be abstract", P);
Set_Etype (N, Any_Type); Set_Etype (N, Any_Type);
elsif Convention (Entity (P)) = Convention_Intrinsic then elsif Convention (Entity (P)) = Convention_Intrinsic then
if Ekind (Entity (P)) = E_Enumeration_Literal then if Ekind (Entity (P)) = E_Enumeration_Literal then
Error_Msg_N Error_Msg_F
("prefix of % attribute cannot be enumeration literal", ("prefix of % attribute cannot be enumeration literal",
P); P);
else else
Error_Msg_N Error_Msg_F
("prefix of % attribute cannot be intrinsic", P); ("prefix of % attribute cannot be intrinsic", P);
end if; end if;
Set_Etype (N, Any_Type); Set_Etype (N, Any_Type);
elsif Is_Thread_Body (Entity (P)) then
Error_Msg_N
("prefix of % attribute cannot be a thread body", P);
end if; end if;
-- Assignments, return statements, components of aggregates, -- Assignments, return statements, components of aggregates,
...@@ -7138,9 +7238,21 @@ package body Sem_Attr is ...@@ -7138,9 +7238,21 @@ package body Sem_Attr is
or else or else
Ekind (Btyp) = E_Anonymous_Access_Protected_Subprogram_Type Ekind (Btyp) = E_Anonymous_Access_Protected_Subprogram_Type
then then
-- Deal with convention mismatch
if Convention (Btyp) /= Convention (Entity (P)) then if Convention (Btyp) /= Convention (Entity (P)) then
Error_Msg_N Error_Msg_FE
("subprogram has invalid convention for context", P); ("subprogram & has wrong convention", P, Entity (P));
Error_Msg_FE
("\does not match convention of access type &",
P, Btyp);
if not Has_Convention_Pragma (Btyp) then
Error_Msg_FE
("\probable missing pragma Convention for &",
P, Btyp);
end if;
else else
Check_Subtype_Conformant Check_Subtype_Conformant
...@@ -7151,7 +7263,7 @@ package body Sem_Attr is ...@@ -7151,7 +7263,7 @@ package body Sem_Attr is
if Attr_Id = Attribute_Unchecked_Access then if Attr_Id = Attribute_Unchecked_Access then
Error_Msg_Name_1 := Aname; Error_Msg_Name_1 := Aname;
Error_Msg_N Error_Msg_F
("attribute% cannot be applied to a subprogram", P); ("attribute% cannot be applied to a subprogram", P);
elsif Aname = Name_Unrestricted_Access then elsif Aname = Name_Unrestricted_Access then
...@@ -7171,7 +7283,7 @@ package body Sem_Attr is ...@@ -7171,7 +7283,7 @@ package body Sem_Attr is
and then Ekind (Btyp) /= and then Ekind (Btyp) /=
E_Anonymous_Access_Protected_Subprogram_Type E_Anonymous_Access_Protected_Subprogram_Type
then then
Error_Msg_N Error_Msg_F
("subprogram must not be deeper than access type", P); ("subprogram must not be deeper than access type", P);
-- Check the restriction of 3.10.2(32) that disallows the -- Check the restriction of 3.10.2(32) that disallows the
...@@ -7210,8 +7322,8 @@ package body Sem_Attr is ...@@ -7210,8 +7322,8 @@ package body Sem_Attr is
-- want the check to apply when the access attribute is in -- want the check to apply when the access attribute is in
-- the spec and there's some other generic body enclosing -- the spec and there's some other generic body enclosing
-- generic). Finally, there's no point applying the check -- generic). Finally, there's no point applying the check
-- when within an instance, because any violations will -- when within an instance, because any violations will have
-- have been caught by the compilation of the generic unit. -- been caught by the compilation of the generic unit.
elsif Attr_Id = Attribute_Access elsif Attr_Id = Attribute_Access
and then not In_Instance and then not In_Instance
...@@ -7306,7 +7418,7 @@ package body Sem_Attr is ...@@ -7306,7 +7418,7 @@ package body Sem_Attr is
if Attr_Id = Attribute_Unchecked_Access then if Attr_Id = Attribute_Unchecked_Access then
Error_Msg_Name_1 := Aname; Error_Msg_Name_1 := Aname;
Error_Msg_N Error_Msg_F
("attribute% cannot be applied to protected operation", P); ("attribute% cannot be applied to protected operation", P);
end if; end if;
...@@ -7340,16 +7452,17 @@ package body Sem_Attr is ...@@ -7340,16 +7452,17 @@ package body Sem_Attr is
Resolve (P); Resolve (P);
end if; end if;
-- X'Access is illegal if X denotes a constant and the access -- X'Access is illegal if X denotes a constant and the access type
-- type is access-to-variable. Same for 'Unchecked_Access. -- is access-to-variable. Same for 'Unchecked_Access. The rule
-- The rule does not apply to 'Unrestricted_Access. -- does not apply to 'Unrestricted_Access. If the reference is a
-- If the reference is a default-initialized aggregate component -- default-initialized aggregate component for a self-referential
-- for a self-referential type the reference is legal. -- type the reference is legal.
if not (Ekind (Btyp) = E_Access_Subprogram_Type if not (Ekind (Btyp) = E_Access_Subprogram_Type
or else Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type or else Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type
or else (Is_Record_Type (Btyp) and then or else (Is_Record_Type (Btyp)
Present (Corresponding_Remote_Type (Btyp))) and then
Present (Corresponding_Remote_Type (Btyp)))
or else Ekind (Btyp) = E_Access_Protected_Subprogram_Type or else Ekind (Btyp) = E_Access_Protected_Subprogram_Type
or else Ekind (Btyp) or else Ekind (Btyp)
= E_Anonymous_Access_Protected_Subprogram_Type = E_Anonymous_Access_Protected_Subprogram_Type
...@@ -7366,7 +7479,7 @@ package body Sem_Attr is ...@@ -7366,7 +7479,7 @@ package body Sem_Attr is
null; null;
elsif Comes_From_Source (N) then elsif Comes_From_Source (N) then
Error_Msg_N ("access-to-variable designates constant", P); Error_Msg_F ("access-to-variable designates constant", P);
end if; end if;
end if; end if;
...@@ -7377,14 +7490,12 @@ package body Sem_Attr is ...@@ -7377,14 +7490,12 @@ package body Sem_Attr is
or else Ekind (Btyp) = E_Anonymous_Access_Type) or else Ekind (Btyp) = E_Anonymous_Access_Type)
then then
-- Ada 2005 (AI-230): Check the accessibility of anonymous -- Ada 2005 (AI-230): Check the accessibility of anonymous
-- access types in record and array components. For a -- access types for stand-alone objects, record and array
-- component definition the level is the same of the -- components, and return objects. For a component definition
-- enclosing composite type. -- the level is the same of the enclosing composite type.
if Ada_Version >= Ada_05 if Ada_Version >= Ada_05
and then and then Is_Local_Anonymous_Access (Btyp)
(Is_Local_Anonymous_Access (Btyp)
or else Ekind (Scope (Btyp)) = E_Return_Statement)
and then Object_Access_Level (P) > Type_Access_Level (Btyp) and then Object_Access_Level (P) > Type_Access_Level (Btyp)
and then Attr_Id = Attribute_Access and then Attr_Id = Attribute_Access
then then
...@@ -7392,22 +7503,23 @@ package body Sem_Attr is ...@@ -7392,22 +7503,23 @@ package body Sem_Attr is
-- know will fail, so generate an appropriate warning. -- know will fail, so generate an appropriate warning.
if In_Instance_Body then if In_Instance_Body then
Error_Msg_N Error_Msg_F
("?non-local pointer cannot point to local object", P); ("?non-local pointer cannot point to local object", P);
Error_Msg_N Error_Msg_F
("\?Program_Error will be raised at run time", P); ("\?Program_Error will be raised at run time", P);
Rewrite (N, Rewrite (N,
Make_Raise_Program_Error (Loc, Make_Raise_Program_Error (Loc,
Reason => PE_Accessibility_Check_Failed)); Reason => PE_Accessibility_Check_Failed));
Set_Etype (N, Typ); Set_Etype (N, Typ);
else else
Error_Msg_N Error_Msg_F
("non-local pointer cannot point to local object", P); ("non-local pointer cannot point to local object", P);
end if; end if;
end if; end if;
if Is_Dependent_Component_Of_Mutable_Object (P) then if Is_Dependent_Component_Of_Mutable_Object (P) then
Error_Msg_N Error_Msg_F
("illegal attribute for discriminant-dependent component", ("illegal attribute for discriminant-dependent component",
P); P);
end if; end if;
...@@ -7419,7 +7531,7 @@ package body Sem_Attr is ...@@ -7419,7 +7531,7 @@ package body Sem_Attr is
Nom_Subt := Etype (P); Nom_Subt := Etype (P);
if Is_Constr_Subt_For_U_Nominal (Nom_Subt) then if Is_Constr_Subt_For_U_Nominal (Nom_Subt) then
Nom_Subt := Etype (Nom_Subt); Nom_Subt := Base_Type (Nom_Subt);
end if; end if;
Des_Btyp := Designated_Type (Btyp); Des_Btyp := Designated_Type (Btyp);
...@@ -7463,10 +7575,10 @@ package body Sem_Attr is ...@@ -7463,10 +7575,10 @@ package body Sem_Attr is
null; null;
else else
Error_Msg_NE Error_Msg_FE
("type of prefix: & not compatible", ("type of prefix: & not compatible",
P, Nom_Subt); P, Nom_Subt);
Error_Msg_NE Error_Msg_FE
("\with &, the expected designated type", ("\with &, the expected designated type",
P, Designated_Type (Typ)); P, Designated_Type (Typ));
end if; end if;
...@@ -7478,9 +7590,9 @@ package body Sem_Attr is ...@@ -7478,9 +7590,9 @@ package body Sem_Attr is
(not Is_Class_Wide_Type (Designated_Type (Typ)) (not Is_Class_Wide_Type (Designated_Type (Typ))
and then Is_Class_Wide_Type (Nom_Subt)) and then Is_Class_Wide_Type (Nom_Subt))
then then
Error_Msg_NE Error_Msg_FE
("type of prefix: & is not covered", P, Nom_Subt); ("type of prefix: & is not covered", P, Nom_Subt);
Error_Msg_NE Error_Msg_FE
("\by &, the expected designated type" & ("\by &, the expected designated type" &
" ('R'M 3.10.2 (27))", P, Designated_Type (Typ)); " ('R'M 3.10.2 (27))", P, Designated_Type (Typ));
end if; end if;
...@@ -7511,7 +7623,7 @@ package body Sem_Attr is ...@@ -7511,7 +7623,7 @@ package body Sem_Attr is
not Has_Constrained_Partial_View not Has_Constrained_Partial_View
(Designated_Type (Base_Type (Typ))))) (Designated_Type (Base_Type (Typ)))))
then then
Error_Msg_N Error_Msg_F
("object subtype must statically match " ("object subtype must statically match "
& "designated subtype", P); & "designated subtype", P);
...@@ -7552,17 +7664,19 @@ package body Sem_Attr is ...@@ -7552,17 +7664,19 @@ package body Sem_Attr is
if Is_Entity_Name (P) if Is_Entity_Name (P)
and then not Is_Protected_Type (Scope (Entity (P))) and then not Is_Protected_Type (Scope (Entity (P)))
then then
Error_Msg_N ("context requires a protected subprogram", P); Error_Msg_F ("context requires a protected subprogram", P);
-- Check accessibility of protected object against that -- Check accessibility of protected object against that
-- of the access type, but only on user code, because -- of the access type, but only on user code, because
-- the expander creates access references for handlers. -- the expander creates access references for handlers.
-- If the context is an anonymous_access_to_protected, -- If the context is an anonymous_access_to_protected,
-- there are no accessibility checks either. -- there are no accessibility checks either.
-- Omit check altogether for GNAT Unrestricted_Access.
elsif Object_Access_Level (P) > Type_Access_Level (Btyp) elsif Object_Access_Level (P) > Type_Access_Level (Btyp)
and then Comes_From_Source (N) and then Comes_From_Source (N)
and then Ekind (Btyp) = E_Access_Protected_Subprogram_Type and then Ekind (Btyp) = E_Access_Protected_Subprogram_Type
and then Attr_Id /= Attribute_Unrestricted_Access
then then
Accessibility_Message; Accessibility_Message;
return; return;
...@@ -7573,7 +7687,7 @@ package body Sem_Attr is ...@@ -7573,7 +7687,7 @@ package body Sem_Attr is
Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type) Ekind (Btyp) = E_Anonymous_Access_Subprogram_Type)
and then Ekind (Etype (N)) = E_Access_Protected_Subprogram_Type and then Ekind (Etype (N)) = E_Access_Protected_Subprogram_Type
then then
Error_Msg_N ("context requires a non-protected subprogram", P); Error_Msg_F ("context requires a non-protected subprogram", P);
end if; end if;
-- The context cannot be a pool-specific type, but this is a -- The context cannot be a pool-specific type, but this is a
...@@ -7586,7 +7700,12 @@ package body Sem_Attr is ...@@ -7586,7 +7700,12 @@ package body Sem_Attr is
Wrong_Type (N, Typ); Wrong_Type (N, Typ);
end if; end if;
Set_Etype (N, Typ); -- The context may be a constrained access type (however ill-
-- advised such subtypes might be) so in order to generate a
-- constraint check when needed set the type of the attribute
-- reference to the base type of the context.
Set_Etype (N, Btyp);
-- Check for incorrect atomic/volatile reference (RM C.6(12)) -- Check for incorrect atomic/volatile reference (RM C.6(12))
...@@ -7594,14 +7713,14 @@ package body Sem_Attr is ...@@ -7594,14 +7713,14 @@ package body Sem_Attr is
if Is_Atomic_Object (P) if Is_Atomic_Object (P)
and then not Is_Atomic (Designated_Type (Typ)) and then not Is_Atomic (Designated_Type (Typ))
then then
Error_Msg_N Error_Msg_F
("access to atomic object cannot yield access-to-" & ("access to atomic object cannot yield access-to-" &
"non-atomic type", P); "non-atomic type", P);
elsif Is_Volatile_Object (P) elsif Is_Volatile_Object (P)
and then not Is_Volatile (Designated_Type (Typ)) and then not Is_Volatile (Designated_Type (Typ))
then then
Error_Msg_N Error_Msg_F
("access to volatile object cannot yield access-to-" & ("access to volatile object cannot yield access-to-" &
"non-volatile type", P); "non-volatile type", P);
end if; end if;
...@@ -7631,9 +7750,8 @@ package body Sem_Attr is ...@@ -7631,9 +7750,8 @@ package body Sem_Attr is
if Present (It.Nam) then if Present (It.Nam) then
Error_Msg_Name_1 := Aname; Error_Msg_Name_1 := Aname;
Error_Msg_N Error_Msg_F
("prefix of % attribute cannot be overloaded", P); ("prefix of % attribute cannot be overloaded", P);
return;
end if; end if;
end if; end if;
...@@ -7994,9 +8112,23 @@ package body Sem_Attr is ...@@ -7994,9 +8112,23 @@ package body Sem_Attr is
end case; end case;
-- Normally the Freezing is done by Resolve but sometimes the Prefix -- Normally the Freezing is done by Resolve but sometimes the Prefix
-- is not resolved, in which case the freezing must be done now. -- is not resolved, in which case the freezing must be done now. The
-- exception to this general rule is the use of 'Address with
-- subprograms (this is required by the backend to support the static
-- allocation of the dispatch tables).
if Static_Dispatch_Tables
and then Nkind (P) in N_Has_Entity
and then not Is_Frozen (Entity (P))
and then Attr_Id = Attribute_Address
and then Is_Subprogram (Entity (P))
and then Is_Dispatching_Operation (Entity (P))
then
Set_Has_Delayed_Freeze (Entity (P));
Freeze_Expression (P); else
Freeze_Expression (P);
end if;
-- Finally perform static evaluation on the attribute reference -- Finally perform static evaluation on the attribute reference
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 1992-2006, Free Software Foundation, Inc. -- -- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
-- This spec also documents all GNAT implementation defined pragmas -- This spec also documents all GNAT implementation defined pragmas
with Exp_Tss; use Exp_Tss; with Exp_Tss; use Exp_Tss;
with Namet; use Namet;
with Snames; use Snames; with Snames; use Snames;
with Types; use Types; with Types; use Types;
...@@ -541,6 +542,19 @@ package Sem_Attr is ...@@ -541,6 +542,19 @@ package Sem_Attr is
-- in appropriate contexts (i.e. in subtype marks, or as prefixes for -- in appropriate contexts (i.e. in subtype marks, or as prefixes for
-- other attributes). -- other attributes).
function Name_Modifies_Prefix (Nam : Name_Id) return Boolean;
-- Determine whether the name of an attribute reference modifies the
-- contents of its prefix. "Read" is such an attribute.
function Requires_Simple_Name_Prefix (Nam : Name_Id) return Boolean;
-- Determine whether the name of an attribute reference requires a simple
-- name rather than a value as its prefix. Such prefixes do not need to be
-- optimized. For instance in the following example:
-- I : constant Integer := 5;
-- S : constant Integer := I'Size;
-- "Size" requires a simple name prefix since "5'Size" does not make
-- sense.
procedure Resolve_Attribute (N : Node_Id; Typ : Entity_Id); procedure Resolve_Attribute (N : Node_Id; Typ : Entity_Id);
-- Performs type resolution of attribute. If the attribute yields a -- Performs type resolution of attribute. If the attribute yields a
-- universal value, mark its type as that of the context. On the other -- universal value, mark its type as that of the context. On the other
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment