aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGary Dismukes <dismukes@adacore.com>2007-12-19 17:25:18 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2007-12-19 17:25:18 +0100
commit20e8cdd795e6d426ff4b7750d6fbe9f2f866fd38 (patch)
treea4d387637bb01780bed1fc941cc8d38ce89a75f8 /gcc
parent90067a1585088aa84dde8cc7f796d567231af202 (diff)
downloadgcc-20e8cdd795e6d426ff4b7750d6fbe9f2f866fd38.zip
gcc-20e8cdd795e6d426ff4b7750d6fbe9f2f866fd38.tar.gz
gcc-20e8cdd795e6d426ff4b7750d6fbe9f2f866fd38.tar.bz2
re PR ada/34149 (GNAT crash - deeply inrerited function)
2007-12-19 Gary Dismukes <dismukes@adacore.com> PR ada/34149 * sem_disp.adb (Check_Dispatching_Call): Augment existing test for presence of a statically tagged operand (Present (Static_Tag)) with test for Indeterm_Ancestor_Call when determining whether to propagate the static tag to tag-indeterminate operands (which forces dispatching on such calls). (Check_Controlling_Formals): Ada2005, access parameters can have defaults. (Add_Dispatching_Operation, Check_Operation_From_Private_View): do not insert subprogram in list of primitive operations if already there. From-SVN: r131082
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/sem_disp.adb27
1 files changed, 21 insertions, 6 deletions
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index 0617558..0f3f57b 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -79,8 +79,14 @@ package body Sem_Disp is
New_Op : Entity_Id)
is
List : constant Elist_Id := Primitive_Operations (Tagged_Type);
+
begin
- Append_Elmt (New_Op, List);
+ -- The dispatching operation may already be on the list, if it the
+ -- wrapper for an inherited function of a null extension (see exp_ch3
+ -- for the construction of function wrappers). The list of primitive
+ -- operations must not contain duplicates.
+
+ Append_Unique_Elmt (New_Op, List);
end Add_Dispatching_Operation;
-------------------------------
@@ -143,7 +149,12 @@ package body Sem_Disp is
end if;
if Present (Default_Value (Formal)) then
- if Ekind (Etype (Formal)) = E_Anonymous_Access_Type then
+
+ -- In Ada 2005, access parameters can have defaults
+
+ if Ekind (Etype (Formal)) = E_Anonymous_Access_Type
+ and then Ada_Version < Ada_05
+ then
Error_Msg_N
("default not allowed for controlling access parameter",
Default_Value (Formal));
@@ -471,10 +482,12 @@ 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.
+ -- If there is a statically tagged actual and a tag-indeterminate
+ -- call to a function of the ancestor (such as that provided by a
+ -- default), then treat this as a dispatching call and propagate
+ -- the tag to the tag-indeterminate call(s).
- elsif Present (Static_Tag) then
+ elsif Present (Static_Tag) and then Indeterm_Ancestor_Call then
Control :=
Make_Attribute_Reference (Loc,
Prefix =>
@@ -1091,8 +1104,10 @@ package body Sem_Disp is
Set_Scope (Subp, Current_Scope);
Tagged_Type := Find_Dispatching_Type (Subp);
+ -- Add Old_Subp to primitive operations if not already present.
+
if Present (Tagged_Type) and then Is_Tagged_Type (Tagged_Type) then
- Append_Elmt (Old_Subp, Primitive_Operations (Tagged_Type));
+ Append_Unique_Elmt (Old_Subp, Primitive_Operations (Tagged_Type));
-- If Old_Subp isn't already marked as dispatching then
-- this is the case of an operation of an untagged private