aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Dismukes <dismukes@adacore.com>2008-07-31 13:04:10 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2008-07-31 13:04:10 +0200
commit01aef5ad76b8314af7406d515aa36e9e1eefa1b6 (patch)
treea7da433816d4b3f46e8dfc4ed89205d226a52326
parent1d06f67ee225537cf9984b384dbe116830730705 (diff)
downloadgcc-01aef5ad76b8314af7406d515aa36e9e1eefa1b6.zip
gcc-01aef5ad76b8314af7406d515aa36e9e1eefa1b6.tar.gz
gcc-01aef5ad76b8314af7406d515aa36e9e1eefa1b6.tar.bz2
exp_attr.adb (Enclosing_Object): New function local to handling of access attributes...
2008-07-31 Gary Dismukes <dismukes@adacore.com> * exp_attr.adb (Enclosing_Object): New function local to handling of access attributes, for retrieving the innermost enclosing object prefix of a compound name. (Expand_N_Attribute_Reference, N_Attribute_Access): In the case where an Access attribute has a prefix that is a dereference of an access parameter (or the prefix is a subcomponent selected from such a dereference), apply an accessibility check to the access parameter. Replaces code that rewrote the prefix as a type conversion (and that didn't handle subcomponent cases). Also, this is now only applied in the case of 'Access. * exp_ch6.adb (Expand_Call): Add handling for the case of an access discriminant passed as an actual to an access formal, passing the Object_Access_Level of the object containing the access discriminant. From-SVN: r138388
-rw-r--r--gcc/ada/exp_attr.adb74
-rw-r--r--gcc/ada/exp_ch6.adb68
2 files changed, 90 insertions, 52 deletions
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 006b8f8..6ad5568 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -651,6 +651,37 @@ package body Exp_Attr is
Btyp_DDT : constant Entity_Id := Directly_Designated_Type (Btyp);
Ref_Object : constant Node_Id := Get_Referenced_Object (Pref);
+ function Enclosing_Object (N : Node_Id) return Node_Id;
+ -- If N denotes a compound name (selected component, indexed
+ -- component, or slice), returns the name of the outermost
+ -- such enclosing object. Otherwise returns N. If the object
+ -- is a renaming, then the renamed object is returned.
+
+ ----------------------
+ -- Enclosing_Object --
+ ----------------------
+
+ function Enclosing_Object (N : Node_Id) return Node_Id is
+ Obj_Name : Node_Id;
+
+ begin
+ Obj_Name := N;
+ while Nkind_In (Obj_Name, N_Selected_Component,
+ N_Indexed_Component,
+ N_Slice)
+ loop
+ Obj_Name := Prefix (Obj_Name);
+ end loop;
+
+ return Get_Referenced_Object (Obj_Name);
+ end Enclosing_Object;
+
+ -- Local declarations
+
+ Enc_Object : constant Node_Id := Enclosing_Object (Ref_Object);
+
+ -- Start of processing for Access_Cases
+
begin
-- In order to improve the text of error messages, the designated
-- type of access-to-subprogram itypes is set by the semantics as
@@ -800,35 +831,28 @@ package body Exp_Attr is
end;
-- If the prefix of an Access attribute is a dereference of an
- -- access parameter (or a renaming of such a dereference) and
- -- the context is a general access type (but not an anonymous
- -- access type), then rewrite the attribute as a conversion of
- -- the access parameter to the context access type. This will
- -- result in an accessibility check being performed, if needed.
-
- -- (X.all'Access => Acc_Type (X))
-
- -- Note: Limit the expansion of an attribute applied to a
- -- dereference of an access parameter so that it's only done
- -- for 'Access. This fixes a problem with 'Unrestricted_Access
- -- that leads to errors in the case where the attribute type
- -- is access-to-variable and the access parameter is
- -- access-to-constant. The conversion is only done to get
- -- accessibility checks, so it makes sense to limit it to
- -- 'Access.
-
- elsif Nkind (Ref_Object) = N_Explicit_Dereference
- and then Is_Entity_Name (Prefix (Ref_Object))
+ -- access parameter (or a renaming of such a dereference, or a
+ -- subcomponent of such a dereference) and the context is a
+ -- general access type (but not an anonymous access type), then
+ -- apply an accessibility check to the access parameter. We used
+ -- to rewrite the access parameter as a type conversion, but that
+ -- could only be done if the immediate prefix of the Access
+ -- attribute was the dereference, and didn't handle cases where
+ -- the attribute is applied to a subcomponent of the dereference,
+ -- since there's generally no available, appropriate access type
+ -- to convert to in that case.
+
+ elsif Id = Attribute_Access
+ and then Nkind (Enc_Object) = N_Explicit_Dereference
+ and then Is_Entity_Name (Prefix (Enc_Object))
and then Ekind (Btyp) = E_General_Access_Type
- and then Ekind (Entity (Prefix (Ref_Object))) in Formal_Kind
- and then Ekind (Etype (Entity (Prefix (Ref_Object))))
+ and then Ekind (Entity (Prefix (Enc_Object))) in Formal_Kind
+ and then Ekind (Etype (Entity (Prefix (Enc_Object))))
= E_Anonymous_Access_Type
and then Present (Extra_Accessibility
- (Entity (Prefix (Ref_Object))))
+ (Entity (Prefix (Enc_Object))))
then
- Rewrite (N,
- Convert_To (Typ, New_Copy_Tree (Prefix (Ref_Object))));
- Analyze_And_Resolve (N, Typ);
+ Apply_Accessibility_Check (Prefix (Enc_Object), Typ);
-- Ada 2005 (AI-251): If the designated type is an interface we
-- add an implicit conversion to force the displacement of the
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 3e3c10d..d1d43cf 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -1,4 +1,4 @@
------------------------------------------------------------------------------
+------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
@@ -2070,16 +2070,16 @@ package body Exp_Ch6 is
if Ekind (Etype (Prev)) in Private_Kind
and then not Has_Discriminants (Base_Type (Etype (Prev)))
then
- Add_Extra_Actual (
- New_Occurrence_Of (Standard_False, Loc),
- Extra_Constrained (Formal));
+ Add_Extra_Actual
+ (New_Occurrence_Of (Standard_False, Loc),
+ Extra_Constrained (Formal));
elsif Is_Constrained (Etype (Formal))
or else not Has_Discriminants (Etype (Prev))
then
- Add_Extra_Actual (
- New_Occurrence_Of (Standard_True, Loc),
- Extra_Constrained (Formal));
+ Add_Extra_Actual
+ (New_Occurrence_Of (Standard_True, Loc),
+ Extra_Constrained (Formal));
-- Do not produce extra actuals for Unchecked_Union parameters.
-- Jump directly to the end of the loop.
@@ -2220,7 +2220,7 @@ package body Exp_Ch6 is
else
Add_Extra_Actual
(Make_Integer_Literal (Loc,
- Intval => Scope_Depth (Standard_Standard)),
+ Intval => Scope_Depth (Standard_Standard)),
Extra_Accessibility (Formal));
end if;
end;
@@ -2231,11 +2231,25 @@ package body Exp_Ch6 is
else
Add_Extra_Actual
(Make_Integer_Literal (Loc,
- Intval => Type_Access_Level (Etype (Prev_Orig))),
+ Intval => Type_Access_Level (Etype (Prev_Orig))),
Extra_Accessibility (Formal));
end if;
- -- All cases other than thunks
+ -- If the actual is an access discriminant, then pass the level
+ -- of the enclosing object (RM05-3.10.2(12.4/2)).
+
+ elsif Nkind (Prev_Orig) = N_Selected_Component
+ and then Ekind (Entity (Selector_Name (Prev_Orig))) =
+ E_Discriminant
+ and then Ekind (Etype (Entity (Selector_Name (Prev_Orig)))) =
+ E_Anonymous_Access_Type
+ then
+ Add_Extra_Actual
+ (Make_Integer_Literal (Loc,
+ Intval => Object_Access_Level (Prefix (Prev_Orig))),
+ Extra_Accessibility (Formal));
+
+ -- All other cases
else
case Nkind (Prev_Orig) is
@@ -2246,20 +2260,20 @@ package body Exp_Ch6 is
-- For X'Access, pass on the level of the prefix X
when Attribute_Access =>
- Add_Extra_Actual (
- Make_Integer_Literal (Loc,
- Intval =>
- Object_Access_Level (Prefix (Prev_Orig))),
- Extra_Accessibility (Formal));
+ Add_Extra_Actual
+ (Make_Integer_Literal (Loc,
+ Intval =>
+ Object_Access_Level (Prefix (Prev_Orig))),
+ Extra_Accessibility (Formal));
-- Treat the unchecked attributes as library-level
when Attribute_Unchecked_Access |
Attribute_Unrestricted_Access =>
- Add_Extra_Actual (
- Make_Integer_Literal (Loc,
- Intval => Scope_Depth (Standard_Standard)),
- Extra_Accessibility (Formal));
+ Add_Extra_Actual
+ (Make_Integer_Literal (Loc,
+ Intval => Scope_Depth (Standard_Standard)),
+ Extra_Accessibility (Formal));
-- No other cases of attributes returning access
-- values that can be passed to access parameters
@@ -2274,19 +2288,19 @@ package body Exp_Ch6 is
-- current scope level.
when N_Allocator =>
- Add_Extra_Actual (
- Make_Integer_Literal (Loc,
- Scope_Depth (Current_Scope) + 1),
- Extra_Accessibility (Formal));
+ Add_Extra_Actual
+ (Make_Integer_Literal (Loc,
+ Intval => Scope_Depth (Current_Scope) + 1),
+ Extra_Accessibility (Formal));
-- For other cases we simply pass the level of the
-- actual's access type.
when others =>
- Add_Extra_Actual (
- Make_Integer_Literal (Loc,
- Intval => Type_Access_Level (Etype (Prev_Orig))),
- Extra_Accessibility (Formal));
+ Add_Extra_Actual
+ (Make_Integer_Literal (Loc,
+ Intval => Type_Access_Level (Etype (Prev_Orig))),
+ Extra_Accessibility (Formal));
end case;
end if;