diff mbox

[Ada] Aliased view of a type in various Ada dialects

Message ID 20120123083044.GA20612@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Jan. 23, 2012, 8:30 a.m. UTC
This patch corrects the detection of a proper aliased view of a type in the
context of attributes Access and Unchecked_Access.

Tested on x86_64-pc-linux-gnu, committed on trunk

2012-01-23  Hristian Kirtchev  <kirtchev@adacore.com>

	* freeze.adb (Check_Current_Instance): Issue an
	error when the prefix of 'Unchecked_Access or 'Access does not
	denote a legal aliased view of a type.
	(Freeze_Record_Type): Do not halt the processing of record components
	once the Has_Controlled_Component is set as this bypasses the remaining
	checks.
	(Is_Aliased_View_Of_Type): New routine.
diff mbox

Patch

Index: freeze.adb
===================================================================
--- freeze.adb	(revision 183406)
+++ freeze.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2012, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -1592,14 +1592,93 @@ 
 
       procedure Check_Current_Instance (Comp_Decl : Node_Id) is
 
-         Rec_Type : constant Entity_Id :=
-                      Scope (Defining_Identifier (Comp_Decl));
+         function Is_Aliased_View_Of_Type (Typ : Entity_Id) return Boolean;
+         --  Determine whether Typ is compatible with the rules for aliased
+         --  views of types as defined in RM 3.10 in the various dialects.
 
-         Decl : constant Node_Id := Parent (Rec_Type);
-
          function Process (N : Node_Id) return Traverse_Result;
          --  Process routine to apply check to given node
 
+         -----------------------------
+         -- Is_Aliased_View_Of_Type --
+         -----------------------------
+
+         function Is_Aliased_View_Of_Type (Typ : Entity_Id) return Boolean is
+            Typ_Decl : constant Node_Id := Parent (Typ);
+
+         begin
+            --  Common case
+
+            if Nkind (Typ_Decl) = N_Full_Type_Declaration
+              and then Limited_Present (Type_Definition (Typ_Decl))
+            then
+               return True;
+
+            --  The following paragraphs describe what a legal aliased view of
+            --  a type is in the various dialects of Ada.
+
+            --  Ada 95
+
+            --  The current instance of a limited type, and a formal parameter
+            --  or generic formal object of a tagged type.
+
+            --  Ada 95 limited type
+            --    * Type with reserved word "limited"
+            --    * A protected or task type
+            --    * A composite type with limited component
+
+            elsif Ada_Version <= Ada_95 then
+               return Is_Limited_Type (Typ);
+
+            --  Ada 2005
+
+            --  The current instance of a limited tagged type, a protected
+            --  type, a task type, or a type that has the reserved word
+            --  "limited" in its full definition ... a formal parameter or
+            --  generic formal object of a tagged type.
+
+            --  Ada 2005 limited type
+            --    * Type with reserved word "limited", "synchronized", "task"
+            --      or "protected"
+            --    * A composite type with limited component
+            --    * A derived type whose parent is a non-interface limited type
+
+            elsif Ada_Version = Ada_2005 then
+               return
+                 (Is_Limited_Type (Typ) and then Is_Tagged_Type (Typ))
+                   or else
+                     (Is_Derived_Type (Typ)
+                       and then not Is_Interface (Etype (Typ))
+                       and then Is_Limited_Type (Etype (Typ)));
+
+            --  Ada 2012 and beyond
+
+            --  The current instance of an immutably limited type ... a formal
+            --  parameter or generic formal object of a tagged type.
+
+            --  Ada 2012 limited type
+            --    * Type with reserved word "limited", "synchronized", "task"
+            --      or "protected"
+            --    * A composite type with limited component
+            --    * A derived type whose parent is a non-interface limited type
+            --    * An incomplete view
+
+            --  Ada 2012 immutably limited type
+            --    * Explicitly limited record type
+            --    * Record extension with "limited" present
+            --    * Non-formal limited private type that is either tagged
+            --      or has at least one access discriminant with a default
+            --      expression
+            --    * Task type, protected type or synchronized interface
+            --    * Type derived from immutably limited type
+
+            else
+               return
+                 Is_Immutably_Limited_Type (Typ)
+                   or else Is_Incomplete_Type (Typ);
+            end if;
+         end Is_Aliased_View_Of_Type;
+
          -------------
          -- Process --
          -------------
@@ -1628,24 +1707,15 @@ 
 
          procedure Traverse is new Traverse_Proc (Process);
 
+         --  Local variables
+
+         Rec_Type : constant Entity_Id :=
+                      Scope (Defining_Identifier (Comp_Decl));
+
       --  Start of processing for Check_Current_Instance
 
       begin
-         --  In Ada 95, the (imprecise) rule is that the current instance
-         --  of a limited type is aliased. In Ada 2005, limitedness must be
-         --  explicit: either a tagged type, or a limited record.
-
-         if Is_Limited_Type (Rec_Type)
-           and then (Ada_Version < Ada_2005 or else Is_Tagged_Type (Rec_Type))
-         then
-            return;
-
-         elsif Nkind (Decl) = N_Full_Type_Declaration
-           and then Limited_Present (Type_Definition (Decl))
-         then
-            return;
-
-         else
+         if not Is_Aliased_View_Of_Type (Rec_Type) then
             Traverse (Comp_Decl);
          end if;
       end Check_Current_Instance;
@@ -2158,18 +2228,16 @@ 
                                           (Etype (Comp)))))
                then
                   Set_Has_Controlled_Component (Rec);
-                  exit;
                end if;
 
                if Has_Unchecked_Union (Etype (Comp)) then
                   Set_Has_Unchecked_Union (Rec);
                end if;
 
+               --  Scan component declaration for likely misuses of current
+               --  instance, either in a constraint or a default expression.
+
                if Has_Per_Object_Constraint (Comp) then
-
-                  --  Scan component declaration for likely misuses of current
-                  --  instance, either in a constraint or a default expression.
-
                   Check_Current_Instance (Parent (Comp));
                end if;