diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-12-13 10:32:11 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-12-13 10:32:11 +0000 |
commit | ad4eda7a496f684169ffcb8686e6ec95a642745a (patch) | |
tree | c855eb54b6cac53876d6174c71a1e215e6424cc0 /gcc/ada/sem_disp.adb | |
parent | 08ed1d869c6ba53ba20af96059ce251dca7a76de (diff) | |
download | gcc-ad4eda7a496f684169ffcb8686e6ec95a642745a.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130856 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/sem_disp.adb')
-rw-r--r-- | gcc/ada/sem_disp.adb | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb index 37eb9ed4196..06175587312 100644 --- a/gcc/ada/sem_disp.adb +++ b/gcc/ada/sem_disp.adb @@ -285,6 +285,10 @@ package body Sem_Disp is Indeterm_Ancestor_Call : Boolean := False; 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; -- If the call is tag-indeterminate and the entity being called is -- abstract, verify that the context is a call that will eventually @@ -379,6 +383,16 @@ package body Sem_Disp is then Indeterm_Ancestor_Call := True; 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; Next_Actual (Actual); @@ -400,11 +414,13 @@ package body Sem_Disp is if No (Control) and then Indeterm_Ancestor_Call + and then No (Static_Tag) then Control := Make_Attribute_Reference (Loc, Prefix => New_Occurrence_Of (Indeterm_Ctrl_Type, Loc), Attribute_Name => Name_Tag); + Analyze (Control); end if; @@ -455,12 +471,38 @@ package body Sem_Disp is Set_Controlling_Argument (N, Control); 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 -- The call is not dispatching, so check that there aren't any -- tag-indeterminate abstract calls left. Actual := First_Actual (N); - while Present (Actual) loop if Is_Tag_Indeterminate (Actual) then @@ -1381,6 +1423,7 @@ package body Sem_Disp is elsif Is_Subprogram (Prim) and then Present (Abstract_Interface_Alias (Prim)) and then Alias (Prim) = Prev_Op + and then Present (Etype (New_Op)) then Set_Alias (Prim, New_Op); Check_Subtype_Conformant (New_Op, Prim); |