aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Quinot <quinot@adacore.com>2006-02-15 10:44:24 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2006-02-15 10:44:24 +0100
commit57193e09243103515c50b2b433ddb15a90d311b7 (patch)
tree3ecf2b18b07d04d5c8637ab49fd55ce77b652b8a /gcc
parent561d9139e3ba1195a41f7fa0c55352dec96a0991 (diff)
downloadgcc-57193e09243103515c50b2b433ddb15a90d311b7.zip
gcc-57193e09243103515c50b2b433ddb15a90d311b7.tar.gz
gcc-57193e09243103515c50b2b433ddb15a90d311b7.tar.bz2
sem_ch12.adb (Inline_Instance_Body): Remove erroneous assumption that Scope_Stack.First = 1.
2006-02-13 Thomas Quinot <quinot@adacore.com> Robert Dewar <dewar@adacore.com> Ed Schonberg <schonberg@adacore.com> Javier Miranda <miranda@adacore.com> * sem_ch12.adb (Inline_Instance_Body): Remove erroneous assumption that Scope_Stack.First = 1. Properly handle Ada_Version_Explicit and Ada_Version_Config, which were not always properly handled previously. (Formal_Entity): Complete rewrite, to handle properly some complex case with multiple levels of parametrization by formal packages. (Analyze_Formal_Derived_Type): Propagate Ada 2005 "limited" indicator to the corresponding derived type declaration for proper semantics. * sem_prag.adb (Analyze_Pragma): Remove '!' in warning message. (Check_Component): Enforce restriction on components of unchecked_unions: a component in a variant cannot contain tasks or controlled types. (Unchecked_Union): Allow nested variants and multiple discriminants, to conform to AI-216. Add pragma Ada_2005 (synonym for Ada_05) Properly handle Ada_Version_Explicit and Ada_Version_Config, which were not always properly handled previously. Document that pragma Propagate_Exceptions has no effect (Analyze_Pragma, case Pure): Set new flag Has_Pragma_Pure (Set_Convention_From_Pragma): Check that if a convention is specified for a dispatching operation, then it must be consistent with the existing convention for the operation. (CPP_Class): Because of the C++ ABI compatibility, the programmer is no longer required to specify an vtable-ptr component in the record. For compatibility reasons we leave the support for the previous definition. (Analyze_Pragma, case No_Return): Allow multiple arguments * sem_ch3.ads, sem_ch3.adb (Check_Abstract_Overriding): Flag a non-overrideen inherited operation with a controlling result as illegal only its implicit declaration comes from the derived type declaration of its result's type. (Check_Possible_Deferred_Completion): Relocate the object definition node of the subtype indication of a deferred constant completion rather than directly analyzing it. The analysis of the generated subtype will correctly decorate the GNAT tree. (Record_Type_Declaration): Check whether this is a declaration for a limited derived record before analyzing components. (Analyze_Component_Declaration): Diagnose record types not explicitly declared limited when a component has a limited type. (Build_Derived_Record_Type): Code reorganization to check if some of the inherited subprograms of a tagged type cover interface primitives. This check was missing in case of a full-type associated with a private type declaration. (Constant_Redeclaration): Check that the subtypes of the partial and the full view of a constrained deferred constant statically match. (Mentions_T): A reference to the current type in an anonymous access component declaration must be an entity name. (Make_Incomplete_Type_Declaration): If type is tagged, set type of class_wide type to refer to full type, not to the incomplete one. (Add_Interface_Tag_Components): Do nothing if RE_Interface_Tag is not available. Required to give support to the certified run-time. (Analyze_Component_Declaration): In case of anonymous access components perform missing checks for AARM 3.9.2(9) and 3.10.2 (12.2). (Process_Discriminants): For an access discriminant, use the discriminant specification as the associated_node_for_itype, to simplify accessibility checks. From-SVN: r111091
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/sem_ch12.adb207
-rw-r--r--gcc/ada/sem_ch3.adb645
-rw-r--r--gcc/ada/sem_ch3.ads5
-rw-r--r--gcc/ada/sem_prag.adb174
4 files changed, 670 insertions, 361 deletions
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index 5e8e6dc..ba3cc95 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2005, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2006, 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- --
@@ -1351,6 +1351,7 @@ package body Sem_Ch12 is
Subtype_Indication => Subtype_Mark (Def));
Set_Abstract_Present (New_N, Abstract_Present (Def));
+ Set_Limited_Present (New_N, Limited_Present (Def));
else
New_N :=
@@ -1364,6 +1365,8 @@ package body Sem_Ch12 is
Set_Abstract_Present
(Type_Definition (New_N), Abstract_Present (Def));
+ Set_Limited_Present
+ (Type_Definition (New_N), Limited_Present (Def));
end if;
Rewrite (N, New_N);
@@ -1894,7 +1897,7 @@ package body Sem_Ch12 is
Ctrl_Type : constant Entity_Id := Find_Dispatching_Type (Nam);
begin
- if not Present (Ctrl_Type) then
+ if No (Ctrl_Type) then
Error_Msg_N
("abstract formal subprogram must have a controlling type",
N);
@@ -3030,9 +3033,13 @@ package body Sem_Ch12 is
Cunit_Entity (Current_Sem_Unit);
Removed : Boolean := False;
Num_Scopes : Int := 0;
- Use_Clauses : array (1 .. Scope_Stack.Last) of Node_Id;
- Instances : array (1 .. Scope_Stack.Last) of Entity_Id;
- Inner_Scopes : array (1 .. Scope_Stack.Last) of Entity_Id;
+
+ Scope_Stack_Depth : constant Int :=
+ Scope_Stack.Last - Scope_Stack.First + 1;
+
+ Use_Clauses : array (1 .. Scope_Stack_Depth) of Node_Id;
+ Instances : array (1 .. Scope_Stack_Depth) of Entity_Id;
+ Inner_Scopes : array (1 .. Scope_Stack_Depth) of Entity_Id;
Num_Inner : Int := 0;
N_Instances : Int := 0;
S : Entity_Id;
@@ -6568,16 +6575,23 @@ package body Sem_Ch12 is
-- because each actual has the same name as the formal, and they do
-- appear in the same order.
- function Formal_Entity
- (F : Node_Id;
- Act_Ent : Entity_Id) return Entity_Id;
- -- Returns the entity associated with the given formal F. In the
- -- case where F is a formal package, this function will iterate
- -- through all of F's formals and enter map associations from the
+ function Get_Formal_Entity (N : Node_Id) return Entity_Id;
+ -- Retrieve entity of defining entity of generic formal parameter.
+ -- Only the declarations of formals need to be considered when
+ -- linking them to actuals, but the declarative list may include
+ -- internal entities generated during analysis, and those are ignored.
+
+ procedure Match_Formal_Entity
+ (Formal_Node : Node_Id;
+ Formal_Ent : Entity_Id;
+ Actual_Ent : Entity_Id);
+ -- Associates the formal entity with the actual. In the case
+ -- where Formal_Ent is a formal package, this procedure iterates
+ -- through all of its formals and enters associations betwen the
-- actuals occurring in the formal package's corresponding actual
- -- package (obtained via Act_Ent) to the formal package's formal
- -- parameters. This function is called recursively for arbitrary
- -- levels of formal packages.
+ -- package (given by Actual_Ent) and the formal package's formal
+ -- parameters. This procedure recurses if any of the parameters is
+ -- itself a package.
function Is_Instance_Of
(Act_Spec : Entity_Id;
@@ -6641,118 +6655,109 @@ package body Sem_Ch12 is
end case;
end Find_Matching_Actual;
- -------------------
- -- Formal_Entity --
- -------------------
+ -------------------------
+ -- Match_Formal_Entity --
+ -------------------------
- function Formal_Entity
- (F : Node_Id;
- Act_Ent : Entity_Id) return Entity_Id
+ procedure Match_Formal_Entity
+ (Formal_Node : Node_Id;
+ Formal_Ent : Entity_Id;
+ Actual_Ent : Entity_Id)
is
- Orig_Node : Node_Id := F;
Act_Pkg : Entity_Id;
begin
- case Nkind (Original_Node (F)) is
- when N_Formal_Object_Declaration =>
- return Defining_Identifier (F);
+ Set_Instance_Of (Formal_Ent, Actual_Ent);
- when N_Formal_Type_Declaration =>
- return Defining_Identifier (F);
+ if Ekind (Actual_Ent) = E_Package then
+ -- Record associations for each parameter
- when N_Formal_Subprogram_Declaration =>
- return Defining_Unit_Name (Specification (F));
+ Act_Pkg := Actual_Ent;
- when N_Package_Declaration =>
- return Defining_Unit_Name (Specification (F));
+ declare
+ A_Ent : Entity_Id := First_Entity (Act_Pkg);
+ F_Ent : Entity_Id;
+ F_Node : Node_Id;
- when N_Formal_Package_Declaration |
- N_Generic_Package_Declaration =>
+ Gen_Decl : Node_Id;
+ Formals : List_Id;
+ Actual : Entity_Id;
- if Nkind (F) = N_Generic_Package_Declaration then
- Orig_Node := Original_Node (F);
- end if;
+ begin
+ -- Retrieve the actual given in the formal package declaration
- Act_Pkg := Act_Ent;
+ Actual := Entity (Name (Original_Node (Formal_Node)));
- -- Find matching actual package, skipping over itypes and
- -- other entities generated when analyzing the formal. We
- -- know that if the instantiation is legal then there is
- -- a matching package for the formal.
+ -- The actual in the formal package declaration may be a
+ -- renamed generic package, in which case we want to retrieve
+ -- the original generic in order to traverse its formal part.
- while Ekind (Act_Pkg) /= E_Package loop
- Act_Pkg := Next_Entity (Act_Pkg);
- end loop;
+ if Present (Renamed_Entity (Actual)) then
+ Gen_Decl := Unit_Declaration_Node (Renamed_Entity (Actual));
+ else
+ Gen_Decl := Unit_Declaration_Node (Actual);
+ end if;
- declare
- Actual_Ent : Entity_Id := First_Entity (Act_Pkg);
- Formal_Node : Node_Id;
- Formal_Ent : Entity_Id;
+ Formals := Generic_Formal_Declarations (Gen_Decl);
- Gen_Decl : Node_Id;
- Formals : List_Id;
+ if Present (Formals) then
+ F_Node := First_Non_Pragma (Formals);
+ else
+ F_Node := Empty;
+ end if;
- begin
- -- The actual may be a renamed generic package, in which
- -- case we want to retrieve the original generic in order
- -- to traverse its formal part.
-
- if Present (Renamed_Entity (Entity (Name (Orig_Node)))) then
- Gen_Decl :=
- Unit_Declaration_Node (
- Renamed_Entity (Entity (Name (Orig_Node))));
- else
- Gen_Decl :=
- Unit_Declaration_Node (Entity (Name (Orig_Node)));
- end if;
+ while Present (A_Ent)
+ and then Present (F_Node)
+ and then A_Ent /= First_Private_Entity (Act_Pkg)
+ loop
+ F_Ent := Get_Formal_Entity (F_Node);
- Formals := Generic_Formal_Declarations (Gen_Decl);
+ if Present (F_Ent) then
- if Present (Formals) then
- Formal_Node := First_Non_Pragma (Formals);
- else
- Formal_Node := Empty;
+ -- This is a formal of the original package. Record
+ -- association and recurse.
+
+ Find_Matching_Actual (F_Node, A_Ent);
+ Match_Formal_Entity (F_Node, F_Ent, A_Ent);
+ Next_Entity (A_Ent);
end if;
- while Present (Actual_Ent)
- and then Present (Formal_Node)
- and then Actual_Ent /= First_Private_Entity (Act_Pkg)
- loop
- -- ??? Are the following calls also needed here:
- --
- -- Set_Is_Hidden (Actual_Ent, False);
- -- Set_Is_Potentially_Use_Visible
- -- (Actual_Ent, In_Use (Act_Ent));
+ Next_Non_Pragma (F_Node);
+ end loop;
+ end;
+ end if;
+ end Match_Formal_Entity;
- Formal_Ent := Formal_Entity (Formal_Node, Actual_Ent);
- if Present (Formal_Ent) then
- Set_Instance_Of (Formal_Ent, Actual_Ent);
- end if;
- Next_Non_Pragma (Formal_Node);
+ -----------------------
+ -- Get_Formal_Entity --
+ -----------------------
- Next_Entity (Actual_Ent);
- end loop;
- end;
+ function Get_Formal_Entity (N : Node_Id) return Entity_Id is
+ Kind : constant Node_Kind := Nkind (Original_Node (N));
+ begin
+ case Kind is
+ when N_Formal_Object_Declaration =>
+ return Defining_Identifier (N);
+
+ when N_Formal_Type_Declaration =>
+ return Defining_Identifier (N);
- return Defining_Identifier (Orig_Node);
+ when N_Formal_Subprogram_Declaration =>
+ return Defining_Unit_Name (Specification (N));
- when N_Use_Package_Clause =>
- return Empty;
+ when N_Formal_Package_Declaration =>
+ return Defining_Identifier (Original_Node (N));
- when N_Use_Type_Clause =>
- return Empty;
+ when N_Generic_Package_Declaration =>
+ return Defining_Identifier (Original_Node (N));
- -- We return Empty for all other encountered forms of
- -- declarations because there are some cases of nonformal
- -- sorts of declaration that can show up (e.g., when array
- -- formals are present). Since it's not clear what kinds
- -- can appear among the formals, we won't raise failure here.
+ -- All other declarations are introduced by semantic analysis
+ -- and have no match in the actual.
- when others =>
+ when others =>
return Empty;
-
end case;
- end Formal_Entity;
+ end Get_Formal_Entity;
--------------------
-- Is_Instance_Of --
@@ -6987,11 +6992,12 @@ package body Sem_Ch12 is
end if;
if Present (Formal_Node) then
- Formal_Ent := Formal_Entity (Formal_Node, Actual_Ent);
+ Formal_Ent := Get_Formal_Entity (Formal_Node);
if Present (Formal_Ent) then
Find_Matching_Actual (Formal_Node, Actual_Ent);
- Set_Instance_Of (Formal_Ent, Actual_Ent);
+ Match_Formal_Entity
+ (Formal_Node, Formal_Ent, Actual_Ent);
end if;
Next_Non_Pragma (Formal_Node);
@@ -8529,7 +8535,7 @@ package body Sem_Ch12 is
and then Present (Ancestor_Discr)
loop
if Base_Type (Act_T) /= Base_Type (Ancestor) and then
- not Present (Corresponding_Discriminant (Actual_Discr))
+ No (Corresponding_Discriminant (Actual_Discr))
then
Error_Msg_NE
("discriminant & does not correspond " &
@@ -10444,7 +10450,6 @@ package body Sem_Ch12 is
(Fname => Unit_File_Name (Get_Source_Unit (Gen_Unit)),
Renamings_Included => True) then
Ada_Version := Ada_Version_Type'Last;
- Ada_Version_Explicit := Ada_Version_Explicit_Config;
end if;
Current_Instantiated_Parent := (Gen_Unit, Act_Unit, Assoc_Null);
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index d2442b4..7d706ce 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2005, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2006, 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- --
@@ -658,10 +658,10 @@ package body Sem_Ch3 is
(Def_Id : Entity_Id;
R : Node_Id;
Subt : Entity_Id);
- -- This routine is used to set the scalar range field for a subtype
- -- given Def_Id, the entity for the subtype, and R, the range expression
- -- for the scalar range. Subt provides the parent subtype to be used
- -- to analyze, resolve, and check the given range.
+ -- This routine is used to set the scalar range field for a subtype given
+ -- Def_Id, the entity for the subtype, and R, the range expression for the
+ -- scalar range. Subt provides the parent subtype to be used to analyze,
+ -- resolve, and check the given range.
procedure Signed_Integer_Type_Declaration (T : Entity_Id; Def : Node_Id);
-- Create a new signed integer entity, and apply the constraint to obtain
@@ -680,9 +680,7 @@ package body Sem_Ch3 is
(Related_Nod : Node_Id;
N : Node_Id) return Entity_Id
is
- Anon_Type : constant Entity_Id :=
- Create_Itype (E_Anonymous_Access_Type, Related_Nod,
- Scope_Id => Scope (Current_Scope));
+ Anon_Type : Entity_Id;
Desig_Type : Entity_Id;
begin
@@ -692,16 +690,14 @@ package body Sem_Ch3 is
Error_Msg_N ("task entries cannot have access parameters", N);
end if;
- -- Ada 2005: for an object declaration or function with an anonymous
- -- access result, the corresponding anonymous type is declared in the
- -- current scope. For access formals, access components, and access
- -- discriminants, the scope is that of the enclosing declaration,
- -- as set above. This special-case handling of resetting the scope
- -- is awkward, and it might be better to pass in the required scope
- -- as a parameter. ???
+ -- Ada 2005: for an object declaration the corresponding anonymous
+ -- type is declared in the current scope.
if Nkind (Related_Nod) = N_Object_Declaration then
- Set_Scope (Anon_Type, Current_Scope);
+ Anon_Type :=
+ Create_Itype
+ (E_Anonymous_Access_Type, Related_Nod,
+ Scope_Id => Current_Scope);
-- For the anonymous function result case, retrieve the scope of
-- the function specification's associated entity rather than using
@@ -713,7 +709,19 @@ package body Sem_Ch3 is
elsif Nkind (Related_Nod) = N_Function_Specification
and then Nkind (Parent (N)) /= N_Parameter_Specification
then
- Set_Scope (Anon_Type, Scope (Defining_Unit_Name (Related_Nod)));
+ Anon_Type :=
+ Create_Itype
+ (E_Anonymous_Access_Type, Related_Nod,
+ Scope_Id => Scope (Defining_Unit_Name (Related_Nod)));
+
+ else
+ -- For access formals, access components, and access
+ -- discriminants, the scope is that of the enclosing declaration,
+
+ Anon_Type :=
+ Create_Itype
+ (E_Anonymous_Access_Type, Related_Nod,
+ Scope_Id => Scope (Current_Scope));
end if;
if All_Present (N)
@@ -1081,9 +1089,10 @@ package body Sem_Ch3 is
-------------
procedure Add_Tag (Iface : Entity_Id) is
- Def : Node_Id;
- Tag : Entity_Id;
- Decl : Node_Id;
+ Decl : Node_Id;
+ Def : Node_Id;
+ Tag : Entity_Id;
+ Offset : Entity_Id;
begin
pragma Assert (Is_Tagged_Type (Iface)
@@ -1115,21 +1124,52 @@ package body Sem_Ch3 is
Set_DT_Entry_Count (Tag,
DT_Entry_Count (First_Entity (Iface)));
- if not Present (Last_Tag) then
+ if No (Last_Tag) then
Prepend (Decl, L);
else
Insert_After (Last_Tag, Decl);
end if;
Last_Tag := Decl;
+
+ -- If the ancestor has discriminants we need to give special support
+ -- to store the offset_to_top value of the secondary dispatch tables.
+ -- For this purpose we add a supplementary component just after the
+ -- field that contains the tag associated with each secondary DT.
+
+ if Typ /= Etype (Typ)
+ and then Has_Discriminants (Etype (Typ))
+ then
+ Def :=
+ Make_Component_Definition (Loc,
+ Subtype_Indication =>
+ New_Occurrence_Of (RTE (RE_Storage_Offset), Loc));
+
+ Offset :=
+ Make_Defining_Identifier (Loc, New_Internal_Name ('V'));
+
+ Decl :=
+ Make_Component_Declaration (Loc,
+ Defining_Identifier => Offset,
+ Component_Definition => Def);
+
+ Analyze_Component_Declaration (Decl);
+
+ Set_Analyzed (Decl);
+ Set_Ekind (Offset, E_Component);
+ Init_Component_Location (Offset);
+ Insert_After (Last_Tag, Decl);
+ Last_Tag := Decl;
+ end if;
end Add_Tag;
-- Start of processing for Add_Interface_Tag_Components
begin
if Ekind (Typ) /= E_Record_Type
- or else not Present (Abstract_Interfaces (Typ))
+ or else No (Abstract_Interfaces (Typ))
or else Is_Empty_Elmt_List (Abstract_Interfaces (Typ))
+ or else not RTE_Available (RE_Interface_Tag)
then
return;
end if;
@@ -1207,6 +1247,13 @@ package body Sem_Ch3 is
-- Determines whether a constraint uses the discriminant of a record
-- type thus becoming a per-object constraint (POC).
+ function Is_Known_Limited (Typ : Entity_Id) return Boolean;
+ -- Check whether enclosing record is limited, to validate declaration
+ -- of components with limited types.
+ -- This seems a wrong description to me???
+ -- What is Typ? For sure it can return a result without checking
+ -- the enclosing record (enclosing what???)
+
------------------
-- Contains_POC --
------------------
@@ -1259,6 +1306,41 @@ package body Sem_Ch3 is
end case;
end Contains_POC;
+ ----------------------
+ -- Is_Known_Limited --
+ ----------------------
+
+ function Is_Known_Limited (Typ : Entity_Id) return Boolean is
+ P : constant Entity_Id := Etype (Typ);
+ R : constant Entity_Id := Root_Type (Typ);
+
+ begin
+ if Is_Limited_Record (Typ) then
+ return True;
+
+ -- If the root type is limited (and not a limited interface)
+ -- so is the current type
+
+ elsif Is_Limited_Record (R)
+ and then
+ (not Is_Interface (R)
+ or else not Is_Limited_Interface (R))
+ then
+ return True;
+
+ -- Else the type may have a limited interface progenitor, but a
+ -- limited record parent.
+
+ elsif R /= P
+ and then Is_Limited_Record (P)
+ then
+ return True;
+
+ else
+ return False;
+ end if;
+ end Is_Known_Limited;
+
-- Start of processing for Analyze_Component_Declaration
begin
@@ -1321,6 +1403,40 @@ package body Sem_Ch3 is
if Present (Expression (N)) then
Analyze_Per_Use_Expression (Expression (N), T);
Check_Initialization (T, Expression (N));
+
+ if Ada_Version >= Ada_05
+ and then Is_Access_Type (T)
+ and then Ekind (T) = E_Anonymous_Access_Type
+ then
+ -- Check RM 3.9.2(9): "if the expected type for an expression is
+ -- an anonymous access-to-specific tagged type, then the object
+ -- designated by the expression shall not be dynamically tagged
+ -- unless it is a controlling operand in a call on a dispatching
+ -- operation"
+
+ if Is_Tagged_Type (Directly_Designated_Type (T))
+ and then
+ Ekind (Directly_Designated_Type (T)) /= E_Class_Wide_Type
+ and then
+ Ekind (Directly_Designated_Type (Etype (Expression (N)))) =
+ E_Class_Wide_Type
+ then
+ Error_Msg_N
+ ("access to specific tagged type required ('R'M 3.9.2(9))",
+ Expression (N));
+ end if;
+
+ -- (Ada 2005: AI-230): Accessibility check for anonymous
+ -- components
+
+ if Type_Access_Level (Etype (Expression (N))) >
+ Type_Access_Level (T)
+ then
+ Error_Msg_N
+ ("expression has deeper access level than component " &
+ "('R'M 3.10.2 (12.2))", Expression (N));
+ end if;
+ end if;
end if;
-- The parent type may be a private view with unknown discriminants,
@@ -1406,11 +1522,19 @@ package body Sem_Ch3 is
and then Is_Tagged_Type (Current_Scope)
then
if Is_Derived_Type (Current_Scope)
- and then not Is_Limited_Record (Root_Type (Current_Scope))
+ and then not Is_Known_Limited (Current_Scope)
then
Error_Msg_N
("extension of nonlimited type cannot have limited components",
N);
+
+ if Is_Interface (Root_Type (Current_Scope)) then
+ Error_Msg_N
+ ("\limitedness is not inherited from limited interface", N);
+ Error_Msg_N
+ ("\add LIMITED to type indication", N);
+ end if;
+
Explain_Limited_Type (T, N);
Set_Etype (Id, Any_Type);
Set_Is_Limited_Composite (Current_Scope, False);
@@ -2067,7 +2191,7 @@ package body Sem_Ch3 is
-- In case of errors detected in the analysis of the expression,
-- decorate it with the expected type to avoid cascade errors
- if not Present (Etype (E)) then
+ if No (Etype (E)) then
Set_Etype (E, T);
end if;
@@ -2660,7 +2784,11 @@ package body Sem_Ch3 is
if Limited_Present (N) then
Set_Is_Limited_Record (T);
- if not Is_Limited_Type (Parent_Type) then
+ if not Is_Limited_Type (Parent_Type)
+ and then
+ (not Is_Interface (Parent_Type)
+ or else not Is_Limited_Interface (Parent_Type))
+ then
Error_Msg_NE ("parent type& of limited extension must be limited",
N, Parent_Type);
end if;
@@ -5332,7 +5460,6 @@ package body Sem_Ch3 is
Constraint_Present : Boolean;
Has_Interfaces : Boolean := False;
Inherit_Discrims : Boolean := False;
- Last_Inherited_Prim_Op : Elmt_Id;
Tagged_Partial_View : Entity_Id;
Save_Etype : Entity_Id;
Save_Discr_Constr : Elist_Id;
@@ -5768,7 +5895,7 @@ package body Sem_Ch3 is
Discrim := First_Discriminant (Derived_Type);
while Present (Discrim) loop
if not Is_Tagged
- and then not Present (Corresponding_Discriminant (Discrim))
+ and then No (Corresponding_Discriminant (Discrim))
then
Error_Msg_N
("new discriminants must constrain old ones", Discrim);
@@ -6006,40 +6133,6 @@ package body Sem_Ch3 is
else
Collect_Interfaces (Type_Definition (N), Derived_Type);
end if;
-
- -- Ada 2005 (AI-251): The progenitor types specified in a private
- -- extension declaration and the progenitor types specified in the
- -- corresponding declaration of a record extension given in the
- -- private part need not be the same; the only requirement is that
- -- the private extension must be descended from each interface
- -- from which the record extension is descended (AARM 7.3, 20.1/2)
-
- if Has_Private_Declaration (Derived_Type) then
- declare
- N_Partial : constant Node_Id := Parent (Tagged_Partial_View);
- Iface_Partial : Entity_Id;
-
- begin
- if Nkind (N_Partial) = N_Private_Extension_Declaration
- and then not Is_Empty_List (Interface_List (N_Partial))
- then
- Iface_Partial := First (Interface_List (N_Partial));
-
- while Present (Iface_Partial) loop
- if not Interface_Present_In_Ancestor
- (Derived_Type, Etype (Iface_Partial))
- then
- Error_Msg_N
- ("(Ada 2005) full type and private extension must"
- & " have the same progenitors", Derived_Type);
- exit;
- end if;
-
- Next (Iface_Partial);
- end loop;
- end if;
- end;
- end if;
end if;
else
@@ -6060,8 +6153,9 @@ package body Sem_Ch3 is
Constrs := Discriminant_Constraint (Parent_Type);
end if;
- Assoc_List := Inherit_Components (N,
- Parent_Base, Derived_Type, Is_Tagged, Inherit_Discrims, Constrs);
+ Assoc_List :=
+ Inherit_Components
+ (N, Parent_Base, Derived_Type, Is_Tagged, Inherit_Discrims, Constrs);
-- STEP 5a: Copy the parent record declaration for untagged types
@@ -6208,116 +6302,103 @@ package body Sem_Ch3 is
end;
end if;
- -- Ada 2005 (AI-251): Keep separate the management of tagged types
- -- implementing interfaces
+ Derive_Subprograms (Parent_Type, Derived_Type);
+
+ -- Ada 2005 (AI-251): Handle tagged types implementing interfaces
- if not Is_Tagged_Type (Derived_Type)
- or else not Has_Interfaces
+ if Is_Tagged_Type (Derived_Type)
+ and then Has_Interfaces
then
- Derive_Subprograms (Parent_Type, Derived_Type);
+ -- Ada 2005 (AI-251): If we are analyzing a full view that has
+ -- no partial view we derive the abstract interface Subprograms
- else
- -- Ada 2005 (AI-251): Complete the decoration of tagged private
- -- types that implement interfaces
+ if No (Tagged_Partial_View) then
+ Derive_Interface_Subprograms (Derived_Type);
- if Present (Tagged_Partial_View) then
- Derive_Subprograms
- (Parent_Type, Derived_Type);
+ -- Ada 2005 (AI-251): if we are analyzing a full view that has
+ -- a partial view we complete the derivation of the subprograms
+ else
Complete_Subprograms_Derivation
(Partial_View => Tagged_Partial_View,
Derived_Type => Derived_Type);
+ end if;
- -- Ada 2005 (AI-251): Derive the interface subprograms of all the
- -- implemented interfaces and check if some of the subprograms
- -- inherited from the ancestor cover some interface subprogram.
+ -- Ada 2005 (AI-251): In both cases we check if some of the
+ -- inherited subprograms cover interface primitives.
- else
- Derive_Subprograms (Parent_Type, Derived_Type);
+ declare
+ Iface_Subp : Entity_Id;
+ Iface_Subp_Elmt : Elmt_Id;
+ Prev_Alias : Entity_Id;
+ Subp : Entity_Id;
+ Subp_Elmt : Elmt_Id;
- declare
- Subp_Elmt : Elmt_Id;
- First_Iface_Elmt : Elmt_Id;
- Iface_Subp_Elmt : Elmt_Id;
- Subp : Entity_Id;
- Iface_Subp : Entity_Id;
- Is_Interface_Subp : Boolean;
+ begin
+ Iface_Subp_Elmt :=
+ First_Elmt (Primitive_Operations (Derived_Type));
+ while Present (Iface_Subp_Elmt) loop
+ Iface_Subp := Node (Iface_Subp_Elmt);
+
+ -- Look for an abstract interface subprogram
+
+ if Is_Abstract (Iface_Subp)
+ and then Present (Alias (Iface_Subp))
+ and then Present (DTC_Entity (Alias (Iface_Subp)))
+ and then Is_Interface
+ (Scope (DTC_Entity (Alias (Iface_Subp))))
+ then
+ -- Look for candidate primitive subprograms of the tagged
+ -- type that can cover this interface subprogram.
- begin
- -- Ada 2005 (AI-251): Remember the entity corresponding to
- -- the last inherited primitive operation. This is required
- -- to check if some of the inherited subprograms covers some
- -- of the new interfaces.
-
- Last_Inherited_Prim_Op := No_Elmt;
-
- Subp_Elmt :=
- First_Elmt (Primitive_Operations (Derived_Type));
- while Present (Subp_Elmt) loop
- Last_Inherited_Prim_Op := Subp_Elmt;
- Next_Elmt (Subp_Elmt);
- end loop;
+ Subp_Elmt :=
+ First_Elmt (Primitive_Operations (Derived_Type));
+ while Present (Subp_Elmt) loop
+ Subp := Node (Subp_Elmt);
- -- Ada 2005 (AI-251): Derive subprograms in abstract
- -- interfaces.
+ if not Is_Abstract (Subp)
+ and then Chars (Subp) = Chars (Iface_Subp)
+ and then Type_Conformant (Iface_Subp, Subp)
+ then
+ Prev_Alias := Alias (Iface_Subp);
- Derive_Interface_Subprograms (Derived_Type);
-
- -- Ada 2005 (AI-251): Check if some of the inherited
- -- subprograms cover some of the new interfaces.
-
- if Present (Last_Inherited_Prim_Op) then
- First_Iface_Elmt := Next_Elmt (Last_Inherited_Prim_Op);
- Iface_Subp_Elmt := First_Iface_Elmt;
- while Present (Iface_Subp_Elmt) loop
- Subp_Elmt := First_Elmt (Primitive_Operations
- (Derived_Type));
- while Subp_Elmt /= First_Iface_Elmt loop
- Subp := Node (Subp_Elmt);
- Iface_Subp := Node (Iface_Subp_Elmt);
-
- Is_Interface_Subp :=
- Present (Alias (Subp))
- and then Present (DTC_Entity (Alias (Subp)))
- and then Is_Interface (Scope
- (DTC_Entity
- (Alias (Subp))));
-
- if Chars (Subp) = Chars (Iface_Subp)
- and then not Is_Interface_Subp
- and then not Is_Abstract (Subp)
- and then Type_Conformant (Iface_Subp, Subp)
- then
- Check_Dispatching_Operation
- (Subp => Subp,
- Old_Subp => Iface_Subp);
-
- -- Traverse the list of aliased subprograms
-
- declare
- E : Entity_Id;
-
- begin
- E := Alias (Subp);
- while Present (Alias (E)) loop
- E := Alias (E);
- end loop;
-
- Set_Alias (Subp, E);
- end;
-
- Set_Has_Delayed_Freeze (Subp);
- exit;
- end if;
-
- Next_Elmt (Subp_Elmt);
- end loop;
+ Check_Dispatching_Operation
+ (Subp => Subp,
+ Old_Subp => Iface_Subp);
+
+ pragma Assert
+ (Alias (Iface_Subp) = Subp);
+ pragma Assert
+ (Abstract_Interface_Alias (Iface_Subp)
+ = Prev_Alias);
+
+ -- Traverse the list of aliased subprograms to link
+ -- subp with its ultimate aliased subprogram. This
+ -- avoids problems with the backend.
+
+ declare
+ E : Entity_Id;
+
+ begin
+ E := Alias (Subp);
+ while Present (Alias (E)) loop
+ E := Alias (E);
+ end loop;
+
+ Set_Alias (Subp, E);
+ end;
- Next_Elmt (Iface_Subp_Elmt);
+ Set_Has_Delayed_Freeze (Subp);
+ exit;
+ end if;
+
+ Next_Elmt (Subp_Elmt);
end loop;
end if;
- end;
- end if;
+
+ Next_Elmt (Iface_Subp_Elmt);
+ end loop;
+ end;
end if;
end if;
@@ -7092,10 +7173,11 @@ package body Sem_Ch3 is
-------------------------------
procedure Check_Abstract_Overriding (T : Entity_Id) is
- Op_List : Elist_Id;
- Elmt : Elmt_Id;
- Subp : Entity_Id;
- Type_Def : Node_Id;
+ Op_List : Elist_Id;
+ Elmt : Elmt_Id;
+ Subp : Entity_Id;
+ Alias_Subp : Entity_Id;
+ Type_Def : Node_Id;
begin
Op_List := Primitive_Operations (T);
@@ -7105,13 +7187,22 @@ package body Sem_Ch3 is
Elmt := First_Elmt (Op_List);
while Present (Elmt) loop
Subp := Node (Elmt);
+ Alias_Subp := Alias (Subp);
+
+ -- Inherited subprograms are identified by the fact that they do not
+ -- come from source, and the associated source location is the
+ -- location of the first subtype of the derived type.
-- Special exception, do not complain about failure to override the
-- stream routines _Input and _Output, as well as the primitive
-- operations used in dispatching selects since we always provide
-- automatic overridings for these subprograms.
- if Is_Abstract (Subp)
+ if (Is_Abstract (Subp)
+ or else (Has_Controlling_Result (Subp)
+ and then Present (Alias_Subp)
+ and then not Comes_From_Source (Subp)
+ and then Sloc (Subp) = Sloc (First_Subtype (T))))
and then not Is_TSS (Subp, TSS_Stream_Input)
and then not Is_TSS (Subp, TSS_Stream_Output)
and then not Is_Abstract (T)
@@ -7120,31 +7211,44 @@ package body Sem_Ch3 is
and then Chars (Subp) /= Name_uDisp_Get_Prim_Op_Kind
and then Chars (Subp) /= Name_uDisp_Timed_Select
then
- if Present (Alias (Subp)) then
-
- -- Only perform the check for a derived subprogram when
- -- the type has an explicit record extension. This avoids
- -- incorrectly flagging abstract subprograms for the case
- -- of a type without an extension derived from a formal type
- -- with a tagged actual (can occur within a private part).
+ if Present (Alias_Subp) then
+
+ -- Only perform the check for a derived subprogram when the
+ -- type has an explicit record extension. This avoids
+ -- incorrectly flagging abstract subprograms for the case of a
+ -- type without an extension derived from a formal type with a
+ -- tagged actual (can occur within a private part).
+
+ -- Ada 2005 (AI-391): In the case of an inherited function with
+ -- a controlling result of the type, the rule does not apply if
+ -- the type is a null extension (unless the parent function
+ -- itself is abstract, in which case the function must still be
+ -- be overridden). The expander will generate an overriding
+ -- wrapper function calling the parent subprogram (see
+ -- Exp_Ch3.Make_Controlling_Wrapper_Functions).
Type_Def := Type_Definition (Parent (T));
if Nkind (Type_Def) = N_Derived_Type_Definition
and then Present (Record_Extension_Part (Type_Def))
+ and then
+ (Ada_Version < Ada_05
+ or else not Is_Null_Extension (T)
+ or else Ekind (Subp) = E_Procedure
+ or else not Has_Controlling_Result (Subp)
+ or else Is_Abstract (Alias_Subp)
+ or else Is_Access_Type (Etype (Subp)))
then
Error_Msg_NE
("type must be declared abstract or & overridden",
T, Subp);
-- Traverse the whole chain of aliased subprograms to
- -- complete the error notification. This is useful for
- -- traceability of the chain of entities when the subprogram
- -- corresponds with interface subprogram (that may be
- -- defined in another package)
+ -- complete the error notification. This is especially
+ -- useful for traceability of the chain of entities when the
+ -- subprogram corresponds with an interface subprogram
+ -- (which might be defined in another package)
- if Ada_Version >= Ada_05
- and then Present (Alias (Subp))
- then
+ if Present (Alias_Subp) then
declare
E : Entity_Id;
@@ -7657,7 +7761,7 @@ package body Sem_Ch3 is
Next_Elmt (Elmt);
end loop;
- if not Present (Elmt) then
+ if No (Elmt) then
Append_Elmt (Node => Iface,
To => Abstract_Interfaces (Derived_Type));
end if;
@@ -8018,6 +8122,15 @@ package body Sem_Ch3 is
Obj_Def : constant Node_Id := Object_Definition (N);
New_T : Entity_Id;
+ procedure Check_Possible_Deferred_Completion
+ (Prev_Id : Entity_Id;
+ Prev_Obj_Def : Node_Id;
+ Curr_Obj_Def : Node_Id);
+ -- Determine whether the two object definitions describe the partial
+ -- and the full view of a constrained deferred constant. Generate
+ -- a subtype for the full view and verify that it statically matches
+ -- the subtype of the partial view.
+
procedure Check_Recursive_Declaration (Typ : Entity_Id);
-- If deferred constant is an access type initialized with an allocator,
-- check whether there is an illegal recursion in the definition,
@@ -8025,6 +8138,46 @@ package body Sem_Ch3 is
-- detected when generating init procs, but requires this additional
-- mechanism when expansion is disabled.
+ ----------------------------------------
+ -- Check_Possible_Deferred_Completion --
+ ----------------------------------------
+
+ procedure Check_Possible_Deferred_Completion
+ (Prev_Id : Entity_Id;
+ Prev_Obj_Def : Node_Id;
+ Curr_Obj_Def : Node_Id)
+ is
+ begin
+ if Nkind (Prev_Obj_Def) = N_Subtype_Indication
+ and then Present (Constraint (Prev_Obj_Def))
+ and then Nkind (Curr_Obj_Def) = N_Subtype_Indication
+ and then Present (Constraint (Curr_Obj_Def))
+ then
+ declare
+ Loc : constant Source_Ptr := Sloc (N);
+ Def_Id : constant Entity_Id :=
+ Make_Defining_Identifier (Loc,
+ New_Internal_Name ('S'));
+ Decl : constant Node_Id :=
+ Make_Subtype_Declaration (Loc,
+ Defining_Identifier =>
+ Def_Id,
+ Subtype_Indication =>
+ Relocate_Node (Curr_Obj_Def));
+
+ begin
+ Insert_Before_And_Analyze (N, Decl);
+ Set_Etype (Id, Def_Id);
+
+ if not Subtypes_Statically_Match (Etype (Prev_Id), Def_Id) then
+ Error_Msg_Sloc := Sloc (Prev_Id);
+ Error_Msg_N ("subtype does not statically match deferred " &
+ "declaration#", N);
+ end if;
+ end;
+ end if;
+ end Check_Possible_Deferred_Completion;
+
---------------------------------
-- Check_Recursive_Declaration --
---------------------------------
@@ -8124,6 +8277,16 @@ package body Sem_Ch3 is
-- If so, process the full constant declaration
else
+ -- RM 7.4 (6): If the subtype defined by the subtype_indication in
+ -- the deferred declaration is constrained, then the subtype defined
+ -- by the subtype_indication in the full declaration shall match it
+ -- statically.
+
+ Check_Possible_Deferred_Completion
+ (Prev_Id => Prev,
+ Prev_Obj_Def => Object_Definition (Parent (Prev)),
+ Curr_Obj_Def => Obj_Def);
+
Set_Full_View (Prev, Id);
Set_Is_Public (Id, Is_Public (Prev));
Set_Is_Internal (Id);
@@ -10413,6 +10576,13 @@ package body Sem_Ch3 is
(New_Subp, Is_Valued_Procedure (Parent_Subp));
end if;
+ -- No_Return must be inherited properly. If this is overridden in the
+ -- case of a dispatching operation, then a check is made in Sem_Disp
+ -- that the overriding operation is also No_Return (no such check is
+ -- required for the case of non-dispatching operation.
+
+ Set_No_Return (New_Subp, No_Return (Parent_Subp));
+
-- A derived function with a controlling result is abstract. If the
-- Derived_Type is a nonabstract formal generic derived type, then
-- inherited operations are not abstract: the required check is done at
@@ -10845,7 +11015,7 @@ package body Sem_Ch3 is
Partial_View := First_Entity (Current_Scope);
loop
- exit when not Present (Partial_View)
+ exit when No (Partial_View)
or else (Has_Private_Declaration (Partial_View)
and then Full_View (Partial_View) = T);
@@ -11020,13 +11190,15 @@ package body Sem_Ch3 is
Build_Derived_Type (N, Parent_Type, T, Is_Completion);
-- AI-419: the parent type of an explicitly limited derived type must
- -- be limited. Interface progenitors were checked earlier.
+ -- be a limited type or a limited interface.
if Limited_Present (Def) then
Set_Is_Limited_Record (T);
if not Is_Limited_Type (Parent_Type)
- and then not Is_Interface (Parent_Type)
+ and then
+ (not Is_Interface (Parent_Type)
+ or else not Is_Limited_Interface (Parent_Type))
then
Error_Msg_NE ("parent type& of limited type must be limited",
N, Parent_Type);
@@ -11273,6 +11445,21 @@ package body Sem_Ch3 is
then
Error_Msg_N
("completion of nonlimited type cannot be limited", N);
+
+ elsif Ekind (Prev) = E_Record_Type_With_Private
+ and then
+ (Nkind (N) = N_Task_Type_Declaration
+ or else Nkind (N) = N_Protected_Type_Declaration)
+ then
+ if not Is_Limited_Record (Prev) then
+ Error_Msg_N
+ ("completion of nonlimited type cannot be limited", N);
+
+ elsif No (Interface_List (N)) then
+ Error_Msg_N
+ ("completion of tagged private type must be tagged",
+ N);
+ end if;
end if;
-- Ada 2005 (AI-251): Private extension declaration of a
@@ -12144,6 +12331,7 @@ package body Sem_Ch3 is
if Ekind (Component) = E_Component
and then Is_Tag (Component)
+ and then RTE_Available (RE_Interface_Tag)
and then Etype (Component) = RTE (RE_Interface_Tag)
then
null;
@@ -12191,6 +12379,41 @@ package body Sem_Ch3 is
return Assoc_List;
end Inherit_Components;
+ -----------------------
+ -- Is_Null_Extension --
+ -----------------------
+
+ function Is_Null_Extension (T : Entity_Id) return Boolean is
+ Full_Type_Decl : constant Node_Id := Parent (T);
+ Full_Type_Defn : constant Node_Id := Type_Definition (Full_Type_Decl);
+ Comp_List : Node_Id;
+ First_Comp : Node_Id;
+
+ begin
+ if not Is_Tagged_Type (T)
+ or else Nkind (Full_Type_Defn) /= N_Derived_Type_Definition
+ then
+ return False;
+ end if;
+
+ Comp_List := Component_List (Record_Extension_Part (Full_Type_Defn));
+
+ if Present (Discriminant_Specifications (Full_Type_Decl)) then
+ return False;
+
+ elsif Present (Comp_List)
+ and then Is_Non_Empty_List (Component_Items (Comp_List))
+ then
+ First_Comp := First (Component_Items (Comp_List));
+
+ return Chars (Defining_Identifier (First_Comp)) = Name_uParent
+ and then No (Next (First_Comp));
+
+ else
+ return True;
+ end if;
+ end Is_Null_Extension;
+
------------------------------
-- Is_Valid_Constraint_Kind --
------------------------------
@@ -13111,7 +13334,7 @@ package body Sem_Ch3 is
end if;
if Nkind (Discriminant_Type (Discr)) = N_Access_Definition then
- Discr_Type := Access_Definition (N, Discriminant_Type (Discr));
+ Discr_Type := Access_Definition (Discr, Discriminant_Type (Discr));
-- Ada 2005 (AI-230): Access discriminants are now allowed for
-- nonlimited types, and are treated like other components of
@@ -13344,6 +13567,14 @@ package body Sem_Ch3 is
Iface_Elmt : Elmt_Id;
begin
+ -- Abstract interfaces are only associated with tagged record types
+
+ if not Is_Tagged_Type (Typ)
+ or else not Is_Record_Type (Typ)
+ then
+ return;
+ end if;
+
-- Implementations of the form:
-- type Typ is new Iface ...
@@ -13361,10 +13592,11 @@ package body Sem_Ch3 is
while Present (Iface_Elmt) loop
Iface := Node (Iface_Elmt);
- if Is_Interface (Iface)
- and then not Contain_Interface (Iface, Ifaces)
- then
+ pragma Assert (Is_Interface (Iface));
+
+ if not Contain_Interface (Iface, Ifaces) then
Append_Elmt (Iface, Ifaces);
+ Collect_Implemented_Interfaces (Iface, Ifaces);
end if;
Next_Elmt (Iface_Elmt);
@@ -13495,15 +13727,22 @@ package body Sem_Ch3 is
Collect_Implemented_Interfaces (Priv_T, Priv_T_Ifaces);
Collect_Implemented_Interfaces (Full_T, Full_T_Ifaces);
- -- Ada 2005 (AI-396): The partial view shall be a descendant of
- -- an interface type if and only if the full view is a descendant
- -- of the interface type.
+ -- Ada 2005 (AI-251): The partial view shall be a descendant of
+ -- an interface type if and only if the full type is descendant
+ -- of the interface type (AARM 7.3 (7.3/2).
+
+ Iface := Find_Hidden_Interface (Priv_T_Ifaces, Full_T_Ifaces);
+
+ if Present (Iface) then
+ Error_Msg_NE ("interface & not implemented by full type " &
+ "('R'M'-2005 7.3 (7.3/2))", Priv_T, Iface);
+ end if;
Iface := Find_Hidden_Interface (Full_T_Ifaces, Priv_T_Ifaces);
if Present (Iface) then
Error_Msg_NE ("interface & not implemented by partial view " &
- "('R'M'-2005 7.3(9))", Full_T, Iface);
+ "('R'M'-2005 7.3 (7.3/2))", Full_T, Iface);
end if;
end;
end if;
@@ -13543,7 +13782,14 @@ package body Sem_Ch3 is
then
null;
- elsif not Is_Ancestor (Base_Type (Priv_Parent), Full_Parent) then
+ -- Ada 2005 (AI-251): If the parent of the private type declaration
+ -- is an interface there is no need to check that it is an ancestor
+ -- of the associated full type declaration. The required tests for
+ -- this case case are performed by Build_Derived_Record_Type.
+
+ elsif not Is_Interface (Base_Type (Priv_Parent))
+ and then not Is_Ancestor (Base_Type (Priv_Parent), Full_Parent)
+ then
Error_Msg_N
("parent of full type must descend from parent"
& " of private extension", Full_Indic);
@@ -13554,7 +13800,7 @@ package body Sem_Ch3 is
-- subtype of the full type must be constrained if and only if
-- the ancestor subtype of the private extension is constrained.
- elsif not Present (Discriminant_Specifications (Parent (Priv_T)))
+ elsif No (Discriminant_Specifications (Parent (Priv_T)))
and then not Has_Unknown_Discriminants (Priv_T)
and then Has_Discriminants (Base_Type (Priv_Parent))
then
@@ -14512,8 +14758,13 @@ package body Sem_Ch3 is
if Nkind (Subt) = N_Identifier then
return Chars (Subt) = Chars (T);
+
+ -- A reference to the current type may appear as the prefix
+ -- of a 'Class attribute.
+
elsif Nkind (Subt) = N_Attribute_Reference
and then Attribute_Name (Subt) = Name_Class
+ and then Is_Entity_Name (Prefix (Subt))
then
return (Chars (Prefix (Subt))) = Chars (T);
else
@@ -14638,8 +14889,12 @@ package body Sem_Ch3 is
begin
-- If there is a previous partial view, no need to create a new one
+ -- If the partial view is incomplete, it is given by Prev. If it is
+ -- a private declaration, full declaration is flagged accordingly.
- if Prev /= T then
+ if Prev /= T
+ or else Has_Private_Declaration (T)
+ then
return;
elsif No (Inc_T) then
@@ -14671,6 +14926,7 @@ package body Sem_Ch3 is
if Tagged_Present (Def) then
Make_Class_Wide_Type (Inc_T);
Set_Class_Wide_Type (T, Class_Wide_Type (Inc_T));
+ Set_Etype (Class_Wide_Type (T), T);
end if;
end if;
end Make_Incomplete_Type_Declaration;
@@ -14915,6 +15171,15 @@ package body Sem_Ch3 is
Final_Storage_Only := not Is_Controlled (T);
+ -- Ada 2005: check whether an explicit Limited is present in a derived
+ -- type declaration.
+
+ if Nkind (Parent (Def)) = N_Derived_Type_Definition
+ and then Limited_Present (Parent (Def))
+ then
+ Set_Is_Limited_Record (T);
+ end if;
+
-- If the component list of a record type is defined by the reserved
-- word null and there is no discriminant part, then the record type has
-- no components and all records of the type are null records (RM 3.7)
diff --git a/gcc/ada/sem_ch3.ads b/gcc/ada/sem_ch3.ads
index 95354d6..d4d3799 100644
--- a/gcc/ada/sem_ch3.ads
+++ b/gcc/ada/sem_ch3.ads
@@ -157,6 +157,11 @@ package Sem_Ch3 is
-- Given a discriminant somewhere in the Typ_For_Constraint tree
-- and a Constraint, return the value of that discriminant.
+ function Is_Null_Extension (T : Entity_Id) return Boolean;
+ -- Returns True if the tagged type T has an N_Full_Type_Declaration that
+ -- is a null extension, meaning that it has an extension part without any
+ -- components and does not have a known discriminant part.
+
function Is_Visible_Component (C : Entity_Id) return Boolean;
-- Determines if a record component C is visible in the present context.
-- Note that even though component C could appear in the entity chain
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 1610c28..bec0eb5 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2005, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2006, 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- --
@@ -341,7 +341,7 @@ package body Sem_Prag is
procedure Check_Component (Comp : Node_Id);
-- Examine Unchecked_Union component for correct use of per-object
- -- constrained subtypes.
+ -- constrained subtypes, and for restrictions on finalizable components.
procedure Check_Duplicated_Export_Name (Nam : Node_Id);
-- Nam is an N_String_Literal node containing the external name set
@@ -988,7 +988,8 @@ package body Sem_Prag is
declare
Sindic : constant Node_Id :=
Subtype_Indication (Component_Definition (Comp));
-
+ Typ : constant Entity_Id :=
+ Etype (Defining_Identifier (Comp));
begin
if Nkind (Sindic) = N_Subtype_Indication then
@@ -1004,6 +1005,15 @@ package body Sem_Prag is
" constraint must be an Unchecked_Union", Comp);
end if;
end if;
+
+ if Is_Controlled (Typ) then
+ Error_Msg_N
+ ("component of unchecked union cannot be controlled", Comp);
+
+ elsif Has_Task (Typ) then
+ Error_Msg_N
+ ("component of unchecked union cannot have tasks", Comp);
+ end if;
end;
end if;
end Check_Component;
@@ -1440,12 +1450,6 @@ package body Sem_Prag is
Comp : Node_Id;
begin
- if Present (Variant_Part (Clist)) then
- Error_Msg_N
- ("Unchecked_Union may not have nested variants",
- Variant_Part (Clist));
- end if;
-
if not Is_Non_Empty_List (Component_Items (Clist)) then
Error_Msg_N
("Unchecked_Union may not have empty component list",
@@ -1957,6 +1961,24 @@ package body Sem_Prag is
procedure Set_Convention_From_Pragma (E : Entity_Id) is
begin
+ -- Check invalid attempt to change convention for an overridden
+ -- dispatching operation. This is Ada 2005 AI 430. Technically
+ -- this is an amendment and should only be done in Ada 2005 mode.
+ -- However, this is clearly a mistake, since the problem that is
+ -- addressed by this AI is that there is a clear gap in the RM!
+
+ if Is_Dispatching_Operation (E)
+ and then Present (Overridden_Operation (E))
+ and then C /= Convention (Overridden_Operation (E))
+ then
+ Error_Pragma_Arg
+ ("cannot change convention for " &
+ "overridden dispatching operation",
+ Arg1);
+ end if;
+
+ -- Set the convention
+
Set_Convention (E, C);
Set_Has_Convention_Pragma (E);
@@ -2862,7 +2884,7 @@ package body Sem_Prag is
else
Dval := Default_Value (Formal);
- if not Present (Dval) then
+ if No (Dval) then
Error_Msg_NE
("optional formal& does not have default value!",
Arg_First_Optional_Parameter, Formal);
@@ -4222,9 +4244,9 @@ package body Sem_Prag is
Error_Msg_Sloc := Task_Dispatching_Policy_Sloc;
Error_Pragma ("Profile (Ravenscar) incompatible with policy#");
- -- Set the FIFO_Within_Priorities policy, but always
- -- preserve System_Location since we like the error
- -- message with the run time name.
+ -- Set the FIFO_Within_Priorities policy, but always preserve
+ -- System_Location since we like the error message with the run time
+ -- name.
else
Task_Dispatching_Policy := 'F';
@@ -4242,9 +4264,8 @@ package body Sem_Prag is
Error_Msg_Sloc := Locking_Policy_Sloc;
Error_Pragma ("Profile (Ravenscar) incompatible with policy#");
- -- Set the Ceiling_Locking policy, but always preserve
- -- System_Location since we like the error message with the
- -- run time name.
+ -- Set the Ceiling_Locking policy, but preserve System_Location since
+ -- we like the error message with the run time name.
else
Locking_Policy := 'C';
@@ -4268,7 +4289,7 @@ package body Sem_Prag is
begin
if not Is_Pragma_Name (Chars (N)) then
if Warn_On_Unrecognized_Pragma then
- Error_Pragma ("unrecognized pragma%!?");
+ Error_Pragma ("unrecognized pragma%?");
else
return;
end if;
@@ -4368,17 +4389,20 @@ package body Sem_Prag is
Ada_Version_Explicit := Ada_Version;
Check_Arg_Count (0);
- ------------
- -- Ada_05 --
- ------------
+ ---------------------
+ -- Ada_05/Ada_2005 --
+ ---------------------
-- pragma Ada_05;
-- pragma Ada_05 (LOCAL_NAME);
- -- Note: this pragma also has some specific processing in Par.Prag
+ -- pragma Ada_2005;
+ -- pragma Ada_2005 (LOCAL_NAME):
+
+ -- Note: these pragma also have some specific processing in Par.Prag
-- because we want to set the Ada 2005 version mode during parsing.
- when Pragma_Ada_05 => declare
+ when Pragma_Ada_05 | Pragma_Ada_2005 => declare
E_Id : Node_Id;
begin
@@ -4397,7 +4421,7 @@ package body Sem_Prag is
else
Check_Arg_Count (0);
Ada_Version := Ada_05;
- Ada_Version_Explicit := Ada_Version;
+ Ada_Version_Explicit := Ada_05;
end if;
end;
@@ -4618,7 +4642,7 @@ package body Sem_Prag is
procedure Process_Async_Pragma is
begin
- if not Present (L) then
+ if No (L) then
Set_Is_Asynchronous (Nm);
return;
end if;
@@ -5255,16 +5279,15 @@ package body Sem_Prag is
("only tagged records can contain vtable pointers", Arg1);
end if;
- -- Case of tagged type with no vtable ptr
-
- -- What is test for Typ = Root_Typ (Typ) about here ???
+ -- Case of tagged type with no user-defined vtable ptr. In this
+ -- case, because of our C++ ABI compatibility, the programmer
+ -- does not need to specify the tag component.
elsif Is_Tagged_Type (Typ)
- and then Typ = Root_Type (Typ)
and then No (Default_DTC)
then
- Error_Pragma_Arg
- ("a cpp_class must contain a vtable pointer", Arg1);
+ Set_Is_CPP_Class (Typ);
+ Set_Is_Limited_Record (Typ);
-- Tagged type that has a vtable ptr
@@ -5438,6 +5461,8 @@ package body Sem_Prag is
Next_Component (DTC);
end loop;
+ -- Case of tagged type with no user-defined vtable ptr
+
if No (DTC) then
Error_Msg_NE ("must be a& component name", Arg, Typ);
raise Pragma_Exit;
@@ -8101,48 +8126,57 @@ package body Sem_Prag is
-- No_Return --
---------------
- -- pragma No_Return (procedure_LOCAL_NAME);
+ -- pragma No_Return (procedure_LOCAL_NAME {, procedure_Local_Name});
when Pragma_No_Return => No_Return : declare
Id : Node_Id;
E : Entity_Id;
Found : Boolean;
+ Arg : Node_Id;
begin
GNAT_Pragma;
- Check_Arg_Count (1);
- Check_No_Identifiers;
- Check_Arg_Is_Local_Name (Arg1);
- Id := Expression (Arg1);
- Analyze (Id);
+ Check_At_Least_N_Arguments (1);
- if not Is_Entity_Name (Id) then
- Error_Pragma_Arg ("entity name required", Arg1);
- end if;
+ -- Loop through arguments of pragma
- if Etype (Id) = Any_Type then
- raise Pragma_Exit;
- end if;
+ Arg := Arg1;
+ while Present (Arg) loop
+ Check_Arg_Is_Local_Name (Arg);
+ Id := Expression (Arg);
+ Analyze (Id);
- E := Entity (Id);
+ if not Is_Entity_Name (Id) then
+ Error_Pragma_Arg ("entity name required", Arg);
+ end if;
- Found := False;
- while Present (E)
- and then Scope (E) = Current_Scope
- loop
- if Ekind (E) = E_Procedure
- or else Ekind (E) = E_Generic_Procedure
- then
- Set_No_Return (E);
- Found := True;
+ if Etype (Id) = Any_Type then
+ raise Pragma_Exit;
end if;
- E := Homonym (E);
- end loop;
+ -- Loop to find matching procedures
- if not Found then
- Error_Pragma ("no procedures found for pragma%");
- end if;
+ E := Entity (Id);
+ Found := False;
+ while Present (E)
+ and then Scope (E) = Current_Scope
+ loop
+ if Ekind (E) = E_Procedure
+ or else Ekind (E) = E_Generic_Procedure
+ then
+ Set_No_Return (E);
+ Found := True;
+ end if;
+
+ E := Homonym (E);
+ end loop;
+
+ if not Found then
+ Error_Pragma_Arg ("no procedure & found for pragma%", Arg);
+ end if;
+
+ Next (Arg);
+ end loop;
end No_Return;
------------------------
@@ -8181,7 +8215,7 @@ package body Sem_Prag is
-- Obsolescent --
-----------------
- -- pragma Obsolescent [(static_string_EXPRESSION [, Ada_05])];
+ -- pragma Obsolescent [(static_string_EXPRESSION [, Ada_05])];
when Pragma_Obsolescent => Obsolescent : declare
Subp : Node_Or_Entity_Id;
@@ -8789,6 +8823,8 @@ package body Sem_Prag is
-- pragma Propagate_Exceptions;
+ -- Note: this pragma is obsolete and has no effect
+
when Pragma_Propagate_Exceptions =>
GNAT_Pragma;
Check_Arg_Count (0);
@@ -8956,6 +8992,7 @@ package body Sem_Prag is
Ent := Find_Lib_Unit_Name;
Set_Is_Pure (Ent);
+ Set_Has_Pragma_Pure (Ent);
Set_Suppress_Elaboration_Warnings (Ent);
end Pure;
@@ -10146,18 +10183,14 @@ package body Sem_Prag is
Discr := First_Discriminant (Typ);
- if Present (Next_Discriminant (Discr)) then
- Error_Msg_N
- ("Unchecked_Union must have exactly one discriminant",
- Next_Discriminant (Discr));
- return;
- end if;
-
- if No (Discriminant_Default_Value (Discr)) then
- Error_Msg_N
- ("Unchecked_Union discriminant must have default value",
- Discr);
- end if;
+ while Present (Discr) loop
+ if No (Discriminant_Default_Value (Discr)) then
+ Error_Msg_N
+ ("Unchecked_Union discriminant must have default value",
+ Discr);
+ end if;
+ Next_Discriminant (Discr);
+ end loop;
Tdef := Type_Definition (Declaration_Node (Typ));
Clist := Component_List (Tdef);
@@ -10686,6 +10719,7 @@ package body Sem_Prag is
Pragma_Ada_83 => -1,
Pragma_Ada_95 => -1,
Pragma_Ada_05 => -1,
+ Pragma_Ada_2005 => -1,
Pragma_All_Calls_Remote => -1,
Pragma_Annotate => -1,
Pragma_Assert => -1,