mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-05 23:21:23 +08:00
sem_disp.adb (Check_Dispatching_Call): If an actual in a call to an inherited operation is a defaulted...
2007-12-06 Ed Schonberg <schonberg@adacore.com> * sem_disp.adb (Check_Dispatching_Call): If an actual in a call to an inherited operation is a defaulted tag-indeterminate call, and there is a statically tagged actual, use the static tag as a controlling actual for the defaulted actual. From-SVN: r130856
This commit is contained in:
parent
3ccd94107b
commit
d215a13cd9
@ -285,6 +285,10 @@ package body Sem_Disp is
|
|||||||
Indeterm_Ancestor_Call : Boolean := False;
|
Indeterm_Ancestor_Call : Boolean := False;
|
||||||
Indeterm_Ctrl_Type : Entity_Id;
|
Indeterm_Ctrl_Type : Entity_Id;
|
||||||
|
|
||||||
|
Static_Tag : Node_Id := Empty;
|
||||||
|
-- If a controlling formal has a statically tagged actual, the tag of
|
||||||
|
-- this actual is to be used for any tag-indeterminate actual
|
||||||
|
|
||||||
procedure Check_Dispatching_Context;
|
procedure Check_Dispatching_Context;
|
||||||
-- If the call is tag-indeterminate and the entity being called is
|
-- If the call is tag-indeterminate and the entity being called is
|
||||||
-- abstract, verify that the context is a call that will eventually
|
-- abstract, verify that the context is a call that will eventually
|
||||||
@ -379,6 +383,16 @@ package body Sem_Disp is
|
|||||||
then
|
then
|
||||||
Indeterm_Ancestor_Call := True;
|
Indeterm_Ancestor_Call := True;
|
||||||
Indeterm_Ctrl_Type := Etype (Formal);
|
Indeterm_Ctrl_Type := Etype (Formal);
|
||||||
|
|
||||||
|
-- If the formal is controlling but the actual is not, the type
|
||||||
|
-- of the actual is statically known, and may be used as the
|
||||||
|
-- controlling tag for some other-indeterminate actual.
|
||||||
|
|
||||||
|
elsif Is_Controlling_Formal (Formal)
|
||||||
|
and then Is_Entity_Name (Actual)
|
||||||
|
and then Is_Tagged_Type (Etype (Actual))
|
||||||
|
then
|
||||||
|
Static_Tag := Actual;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
Next_Actual (Actual);
|
Next_Actual (Actual);
|
||||||
@ -400,11 +414,13 @@ package body Sem_Disp is
|
|||||||
|
|
||||||
if No (Control)
|
if No (Control)
|
||||||
and then Indeterm_Ancestor_Call
|
and then Indeterm_Ancestor_Call
|
||||||
|
and then No (Static_Tag)
|
||||||
then
|
then
|
||||||
Control :=
|
Control :=
|
||||||
Make_Attribute_Reference (Loc,
|
Make_Attribute_Reference (Loc,
|
||||||
Prefix => New_Occurrence_Of (Indeterm_Ctrl_Type, Loc),
|
Prefix => New_Occurrence_Of (Indeterm_Ctrl_Type, Loc),
|
||||||
Attribute_Name => Name_Tag);
|
Attribute_Name => Name_Tag);
|
||||||
|
|
||||||
Analyze (Control);
|
Analyze (Control);
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
@ -455,12 +471,38 @@ package body Sem_Disp is
|
|||||||
Set_Controlling_Argument (N, Control);
|
Set_Controlling_Argument (N, Control);
|
||||||
Check_Restriction (No_Dispatching_Calls, N);
|
Check_Restriction (No_Dispatching_Calls, N);
|
||||||
|
|
||||||
|
-- If there is a statically tagged actual, check whether
|
||||||
|
-- some tag-indeterminate actual can use it.
|
||||||
|
|
||||||
|
elsif Present (Static_Tag) then
|
||||||
|
Control :=
|
||||||
|
Make_Attribute_Reference (Loc,
|
||||||
|
Prefix =>
|
||||||
|
New_Occurrence_Of (Etype (Static_Tag), Loc),
|
||||||
|
Attribute_Name => Name_Tag);
|
||||||
|
|
||||||
|
Analyze (Control);
|
||||||
|
|
||||||
|
Actual := First_Actual (N);
|
||||||
|
Formal := First_Formal (Subp_Entity);
|
||||||
|
while Present (Actual) loop
|
||||||
|
if Is_Tag_Indeterminate (Actual)
|
||||||
|
and then Is_Controlling_Formal (Formal)
|
||||||
|
then
|
||||||
|
Propagate_Tag (Control, Actual);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
Next_Actual (Actual);
|
||||||
|
Next_Formal (Formal);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
Check_Dispatching_Context;
|
||||||
|
|
||||||
else
|
else
|
||||||
-- The call is not dispatching, so check that there aren't any
|
-- The call is not dispatching, so check that there aren't any
|
||||||
-- tag-indeterminate abstract calls left.
|
-- tag-indeterminate abstract calls left.
|
||||||
|
|
||||||
Actual := First_Actual (N);
|
Actual := First_Actual (N);
|
||||||
|
|
||||||
while Present (Actual) loop
|
while Present (Actual) loop
|
||||||
if Is_Tag_Indeterminate (Actual) then
|
if Is_Tag_Indeterminate (Actual) then
|
||||||
|
|
||||||
@ -1381,6 +1423,7 @@ package body Sem_Disp is
|
|||||||
elsif Is_Subprogram (Prim)
|
elsif Is_Subprogram (Prim)
|
||||||
and then Present (Abstract_Interface_Alias (Prim))
|
and then Present (Abstract_Interface_Alias (Prim))
|
||||||
and then Alias (Prim) = Prev_Op
|
and then Alias (Prim) = Prev_Op
|
||||||
|
and then Present (Etype (New_Op))
|
||||||
then
|
then
|
||||||
Set_Alias (Prim, New_Op);
|
Set_Alias (Prim, New_Op);
|
||||||
Check_Subtype_Conformant (New_Op, Prim);
|
Check_Subtype_Conformant (New_Op, Prim);
|
||||||
|
Loading…
Reference in New Issue
Block a user