+2011-08-02 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch4.adb: Minor reformatting.
+
+2011-08-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch5.adb (Analyze_Loop_Statement): If the iteration scheme is an
+ Ada2012 iterator, the loop will be rewritten during expansion into a
+ while loop with a cursor and an element declaration. Do not analyze the
+ body in this case, because if the container is for indefinite types the
+ actual subtype of the elements will only be determined when the cursor
+ declaration is analyzed.
+
+2011-08-02 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_ch13.adb (Analyze_Attribute_Definition_Clause): Ignore
+ size/alignment related attributes in CodePeer_Mode.
+
+2011-08-02 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_ch3.adb (Check_Ops_From_Incomplete_Type): Remove call to
+ Prepend_Element, since this can result in the operation getting the
+ wrong slot in the full type's dispatch table if the full type has
+ inherited operations. The incomplete type's operation will get added
+ to the proper position in the full type's primitives
+ list later in Sem_Disp.Check_Operation_From_Incomplete_Type.
+ (Process_Incomplete_Dependents): Add Is_Primitive test when checking for
+ dispatching operations, since there are cases where nonprimitive
+ subprograms can get added to the list of incomplete dependents (such
+ as subprograms in nested packages).
+ * sem_ch6.adb (Process_Formals): First, remove test for being in a
+ private part when determining whether to add a primitive with a
+ parameter of a tagged incomplete type to the Private_Dependents list.
+ Such primitives can also occur in the visible part, and should not have
+ been excluded from being private dependents.
+ * sem_ch7.adb (Uninstall_Declarations): When checking the rule of
+ RM05-3.10.1(9.3/2), test that a subprogram in the Private_Dependents
+ list of a Taft-amendment incomplete type is a primitive before issuing
+ an error that the full type must appear in the same unit. There are
+ cases where nonprimitives can be in the list (such as subprograms in
+ nested packages).
+ * sem_disp.adb (Derives_From): Use correct condition for checking that
+ a formal's type is derived from the type of the corresponding formal in
+ the parent subprogram (the condition was completely wrong). Add
+ checking that was missing for controlling result types being derived
+ from the result type of the parent operation.
+
2011-08-02 Yannick Moy <moy@adacore.com>
* errout.adb (First_Node): minor renaming
Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
end if;
- -- For navigation purposes, the inequality is treated as an
+ -- For navigation purposes, we want to treat the inequality as an
-- implicit reference to the corresponding equality. Preserve the
- -- Comes_From_ source flag so that the proper Xref entry is
- -- generated.
+ -- Comes_From_ source flag to generate proper Xref entries.
Preserve_Comes_From_Source (Neg, N);
Preserve_Comes_From_Source (Right_Opnd (Neg), N);
Set_Analyzed (N, True);
end if;
- -- Process Ignore_Rep_Clauses option
+ -- Process Ignore_Rep_Clauses option (we also ignore rep clauses in
+ -- CodePeer mode, since they are not relevant in that context).
- if Ignore_Rep_Clauses then
+ if Ignore_Rep_Clauses or CodePeer_Mode then
case Id is
-- The following should be ignored. They do not affect legality
Attribute_Machine_Radix |
Attribute_Object_Size |
Attribute_Size |
- Attribute_Small |
Attribute_Stream_Size |
Attribute_Value_Size =>
-
Rewrite (N, Make_Null_Statement (Sloc (N)));
return;
+ -- We do not want too ignore 'Small in CodePeer_Mode, since it
+ -- has an impact on the exact computations performed.
+
+ -- Perhaps 'Small should also not be ignored by
+ -- Ignore_Rep_Clauses ???
+
+ when Attribute_Small =>
+ if Ignore_Rep_Clauses then
+ Rewrite (N, Make_Null_Statement (Sloc (N)));
+ return;
+ end if;
+
-- The following should not be ignored, because in the first place
-- they are reasonably portable, and should not cause problems in
-- compiling code from another target, and also they do affect
-- legality, e.g. failing to provide a stream attribute for a
-- type may make a program illegal.
- when Attribute_External_Tag |
- Attribute_Input |
- Attribute_Output |
- Attribute_Read |
- Attribute_Storage_Pool |
- Attribute_Storage_Size |
- Attribute_Write =>
+ when Attribute_External_Tag |
+ Attribute_Input |
+ Attribute_Output |
+ Attribute_Read |
+ Attribute_Storage_Pool |
+ Attribute_Storage_Size |
+ Attribute_Write =>
null;
-- Other cases are errors ("attribute& cannot be set with
or else In_Package_Body (Current_Scope));
procedure Check_Ops_From_Incomplete_Type;
- -- If there is a tagged incomplete partial view of the type, transfer
- -- its operations to the full view, and indicate that the type of the
- -- controlling parameter (s) is this full view.
+ -- If there is a tagged incomplete partial view of the type, traverse
+ -- the primitives of the incomplete view and change the type of any
+ -- controlling formals and result to indicate the full view. The
+ -- primitives will be added to the full type's primitive operations
+ -- list later in Sem_Disp.Check_Operation_From_Incomplete_Type (which
+ -- is called from Process_Incomplete_Dependents).
------------------------------------
-- Check_Ops_From_Incomplete_Type --
Elmt := First_Elmt (Primitive_Operations (Prev));
while Present (Elmt) loop
Op := Node (Elmt);
- Prepend_Elmt (Op, Primitive_Operations (T));
Formal := First_Formal (Op);
while Present (Formal) loop
elsif Is_Overloadable (Priv_Dep) then
- -- A protected operation is never dispatching: only its
- -- wrapper operation (which has convention Ada) is.
+ -- If a subprogram in the incomplete dependents list is primitive
+ -- for a tagged full type then mark it as a dispatching operation,
+ -- check whether it overrides an inherited subprogram, and check
+ -- restrictions on its controlling formals. Note that a protected
+ -- operation is never dispatching: only its wrapper operation
+ -- (which has convention Ada) is.
if Is_Tagged_Type (Full_T)
+ and then Is_Primitive (Priv_Dep)
and then Convention (Priv_Dep) /= Convention_Protected
then
-
- -- Subprogram has an access parameter whose designated type
- -- was incomplete. Reexamine declaration now, because it may
- -- be a primitive operation of the full type.
-
Check_Operation_From_Incomplete_Type (Priv_Dep, Inc_T);
Set_Is_Dispatching_Operation (Priv_Dep);
Check_Controlling_Formals (Full_T, Priv_Dep);
Kill_Current_Values;
Push_Scope (Ent);
Analyze_Iteration_Scheme (Iter);
- Analyze_Statements (Statements (Loop_Statement));
+
+ -- Analyze the statements of the body except in the case of an Ada 2012
+ -- iterator with the expander active. In this case the expander will do
+ -- a rewrite of the loop into a while loop. We will then analyze the
+ -- loop body when we analyze this while loop.
+
+ -- We need to do this delay because if the container is for indefinite
+ -- types the actual subtype of the components will only be determined
+ -- when the cursor declaration is analyzed.
+
+ -- If the expander is not active, then we want to analyze the loop body
+ -- now even in the Ada 2012 iterator case, since the rewriting will not
+ -- be done.
+
+ if No (Iter)
+ or else No (Iterator_Specification (Iter))
+ or else not Expander_Active
+ then
+ Analyze_Statements (Statements (Loop_Statement));
+ end if;
+
+ -- Finish up processing for the loop. We kill all current values, since
+ -- in general we don't know if the statements in the loop have been
+ -- executed. We could do a bit better than this with a loop that we
+ -- know will execute at least once, but it's not worth the trouble and
+ -- the front end is not in the business of flow tracing.
+
Process_End_Label (Loop_Statement, 'e', Ent);
End_Scope;
Kill_Current_Values;
if Is_Tagged_Type (Formal_Type) then
if Ekind (Scope (Current_Scope)) = E_Package
- and then In_Private_Part (Scope (Current_Scope))
and then not From_With_Type (Formal_Type)
and then not Is_Class_Wide_Type (Formal_Type)
then
Append_Elmt
(Current_Scope,
Private_Dependents (Base_Type (Formal_Type)));
+
+ -- Freezing is delayed to ensure that Register_Prim
+ -- will get called for this operation, which is needed
+ -- in cases where static dispatch tables aren't built.
+ -- (Note that the same is done for controlling access
+ -- parameter cases in function Access_Definition.)
+
+ Set_Has_Delayed_Freeze (Current_Scope);
end if;
end if;
while Present (Elmt) loop
Subp := Node (Elmt);
- if Is_Overloadable (Subp) then
+ -- Is_Primitive is tested because there can be cases where
+ -- nonprimitive subprograms (in nested packages) are added
+ -- to the Private_Dependents list.
+
+ if Is_Overloadable (Subp) and then Is_Primitive (Subp) then
Error_Msg_NE
("type& must be completed in the private part",
Parent (Subp), Id);
Op1, Op2 : Elmt_Id;
Prev : Elmt_Id := No_Elmt;
- function Derives_From (Proc : Entity_Id) return Boolean;
- -- Check that Subp has the signature of an operation derived from Proc.
- -- Subp has an access parameter that designates Typ.
+ function Derives_From (Parent_Subp : Entity_Id) return Boolean;
+ -- Check that Subp has profile of an operation derived from Parent_Subp.
+ -- Subp must have a parameter or result type that is Typ or an access
+ -- parameter or access result type that designates Typ.
------------------
-- Derives_From --
------------------
- function Derives_From (Proc : Entity_Id) return Boolean is
+ function Derives_From (Parent_Subp : Entity_Id) return Boolean is
F1, F2 : Entity_Id;
begin
- if Chars (Proc) /= Chars (Subp) then
+ if Chars (Parent_Subp) /= Chars (Subp) then
return False;
end if;
- F1 := First_Formal (Proc);
+ -- Check that the type of controlling formals is derived from the
+ -- parent subprogram's controlling formal type (or designated type
+ -- if the formal type is an anonymous access type).
+
+ F1 := First_Formal (Parent_Subp);
F2 := First_Formal (Subp);
while Present (F1) and then Present (F2) loop
if Ekind (Etype (F1)) = E_Anonymous_Access_Type then
elsif Ekind (Etype (F2)) = E_Anonymous_Access_Type then
return False;
- elsif Etype (F1) /= Etype (F2) then
+ elsif Etype (F1) = Parent_Typ and then Etype (F2) /= Full then
return False;
end if;
Next_Formal (F2);
end loop;
+ -- Check that a controlling result type is derived from the parent
+ -- subprogram's result type (or designated type if the result type
+ -- is an anonymous access type).
+
+ if Ekind (Parent_Subp) = E_Function then
+ if Ekind (Subp) /= E_Function then
+ return False;
+
+ elsif Ekind (Etype (Parent_Subp)) = E_Anonymous_Access_Type then
+ if Ekind (Etype (Subp)) /= E_Anonymous_Access_Type then
+ return False;
+
+ elsif Designated_Type (Etype (Parent_Subp)) = Parent_Typ
+ and then Designated_Type (Etype (Subp)) /= Full
+ then
+ return False;
+ end if;
+
+ elsif Ekind (Etype (Subp)) = E_Anonymous_Access_Type then
+ return False;
+
+ elsif Etype (Parent_Subp) = Parent_Typ
+ and then Etype (Subp) /= Full
+ then
+ return False;
+ end if;
+
+ elsif Ekind (Subp) = E_Function then
+ return False;
+ end if;
+
return No (F1) and then No (F2);
end Derives_From;