OSDN Git Service

* gcc-interface/decl.c (make_type_from_size) <INTEGER_TYPE>: Just copy
[pf3gnuchains/gcc-fork.git] / gcc / ada / sem_attr.adb
index 14f9102..e37b216 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2008, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2009, 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- --
@@ -35,6 +35,7 @@ with Exp_Dist; use Exp_Dist;
 with Exp_Util; use Exp_Util;
 with Expander; use Expander;
 with Freeze;   use Freeze;
+with Gnatvsn;  use Gnatvsn;
 with Itypes;   use Itypes;
 with Lib;      use Lib;
 with Lib.Xref; use Lib.Xref;
@@ -46,10 +47,13 @@ with Rident;   use Rident;
 with Rtsfind;  use Rtsfind;
 with Sdefault; use Sdefault;
 with Sem;      use Sem;
+with Sem_Aux;  use Sem_Aux;
 with Sem_Cat;  use Sem_Cat;
 with Sem_Ch6;  use Sem_Ch6;
 with Sem_Ch8;  use Sem_Ch8;
+with Sem_Ch10; use Sem_Ch10;
 with Sem_Dist; use Sem_Dist;
+with Sem_Elim; use Sem_Elim;
 with Sem_Eval; use Sem_Eval;
 with Sem_Res;  use Sem_Res;
 with Sem_Type; use Sem_Type;
@@ -230,7 +234,7 @@ package body Sem_Attr is
 
       procedure Check_Dereference;
       --  If the prefix of attribute is an object of an access type, then
-      --  introduce an explicit deference, and adjust P_Type accordingly.
+      --  introduce an explicit dereference, and adjust P_Type accordingly.
 
       procedure Check_Discrete_Type;
       --  Verify that prefix of attribute N is a discrete type
@@ -315,6 +319,9 @@ package body Sem_Attr is
       --  corresponding possible defined attribute function (e.g. for the
       --  Read attribute, Nam will be TSS_Stream_Read).
 
+      procedure Check_PolyORB_Attribute;
+      --  Validity checking for PolyORB/DSA attribute
+
       procedure Check_Task_Prefix;
       --  Verify that prefix of attribute N is a task or task type
 
@@ -415,7 +422,8 @@ package body Sem_Attr is
             --  an access, we set a flag to kill all tracked values on any call
             --  because this access value may be passed around, and any called
             --  code might use it to access a local procedure which clobbers a
-            --  tracked value.
+            --  tracked value. If the scope is a loop or block, indicate that
+            --  value tracking is disabled for the enclosing subprogram.
 
             function Get_Kind (E : Entity_Id) return Entity_Kind;
             --  Distinguish between access to regular/protected subprograms
@@ -428,6 +436,8 @@ package body Sem_Attr is
             begin
                if not Is_Library_Level_Entity (E) then
                   Set_Suppress_Value_Tracking_On_Call (Current_Scope);
+                  Set_Suppress_Value_Tracking_On_Call
+                    (Nearest_Dynamic_Scope (Current_Scope));
                end if;
             end Check_Local_Access;
 
@@ -569,6 +579,10 @@ package body Sem_Attr is
                Error_Attr ("attribute% cannot be applied to a subprogram", P);
             end if;
 
+            --  Issue an error if the prefix denotes an eliminated subprogram
+
+            Check_For_Eliminated_Subprogram (P, Entity (P));
+
             --  Build the appropriate subprogram type
 
             Build_Access_Subprogram_Type (P);
@@ -653,8 +667,8 @@ package body Sem_Attr is
                      end loop;
 
                      if Present (Q) then
-                        Set_Has_Per_Object_Constraint (
-                          Defining_Identifier (Q), True);
+                        Set_Has_Per_Object_Constraint
+                          (Defining_Identifier (Q), True);
                      end if;
                   end;
 
@@ -710,6 +724,11 @@ package body Sem_Attr is
                then
                   null;
 
+               --  OK if reference to current instance of a protected object
+
+               elsif Is_Protected_Self_Reference (P) then
+                  null;
+
                --  Otherwise we have an error case
 
                else
@@ -1051,7 +1070,13 @@ package body Sem_Attr is
             --  the designated type of the access type, since the type of
             --  the referenced array is this type (see AI95-00106).
 
-            Freeze_Before (N, Designated_Type (P_Type));
+            --  As done elsewhere, freezing must not happen when pre-analyzing
+            --  a pre- or postcondition or a default value for an object or
+            --  for a formal parameter.
+
+            if not In_Spec_Expression then
+               Freeze_Before (N, Designated_Type (P_Type));
+            end if;
 
             Rewrite (P,
               Make_Explicit_Dereference (Sloc (P),
@@ -1321,15 +1346,32 @@ package body Sem_Attr is
                E := Prefix (E);
             end loop;
 
-            if From_With_Type (Etype (E)) then
+            Typ := Etype (E);
+
+            if From_With_Type (Typ) then
                Error_Attr_P
                  ("prefix of % attribute cannot be an incomplete type");
 
             else
-               if Is_Access_Type (Etype (E)) then
-                  Typ := Directly_Designated_Type (Etype (E));
-               else
-                  Typ := Etype (E);
+               if Is_Access_Type (Typ) then
+                  Typ := Directly_Designated_Type (Typ);
+               end if;
+
+               if Is_Class_Wide_Type (Typ) then
+                  Typ := Root_Type (Typ);
+               end if;
+
+               --  A legal use of a shadow entity occurs only when the unit
+               --  where the non-limited view resides is imported via a regular
+               --  with clause in the current body. Such references to shadow
+               --  entities may occur in subprogram formals.
+
+               if Is_Incomplete_Type (Typ)
+                 and then From_With_Type (Typ)
+                 and then Present (Non_Limited_View (Typ))
+                 and then Is_Legal_Shadow_Entity_In_Body (Typ)
+               then
+                  Typ := Non_Limited_View (Typ);
                end if;
 
                if Ekind (Typ) = E_Incomplete_Type
@@ -1380,6 +1422,23 @@ package body Sem_Attr is
          end if;
       end Check_Object_Reference;
 
+      ----------------------------
+      -- Check_PolyORB_Attribute --
+      ----------------------------
+
+      procedure Check_PolyORB_Attribute is
+      begin
+         Validate_Non_Static_Attribute_Function_Call;
+
+         Check_Type;
+         Check_Not_CPP_Type;
+
+         if Get_PCS_Name /= Name_PolyORB_DSA then
+            Error_Attr
+              ("attribute% requires the 'Poly'O'R'B 'P'C'S", N);
+         end if;
+      end Check_PolyORB_Attribute;
+
       ------------------------
       -- Check_Program_Unit --
       ------------------------
@@ -1529,7 +1588,19 @@ package body Sem_Attr is
             end if;
          end if;
 
-         --  Check for violation of restriction No_Stream_Attributes
+         --  Check restriction violations
+
+         --  First check the No_Streams restriction, which prohibits the use
+         --  of explicit stream attributes in the source program. We do not
+         --  prevent the occurrence of stream attributes in generated code,
+         --  for instance those generated implicitly for dispatching purposes.
+
+         if Comes_From_Source (N) then
+            Check_Restriction (No_Streams, P);
+         end if;
+
+         --  Check special case of Exception_Id and Exception_Occurrence which
+         --  are not allowed for restriction No_Exception_Regstriation.
 
          if Is_RTE (P_Type, RE_Exception_Id)
               or else
@@ -1623,6 +1694,11 @@ package body Sem_Attr is
          then
             Error_Attr_P ("prefix of % attribute must be a type");
 
+         elsif Is_Protected_Self_Reference (P) then
+            Error_Attr_P
+              ("prefix of % attribute denotes current instance "
+               & "(RM 9.4(21/2))");
+
          elsif Ekind (Entity (P)) = E_Incomplete_Type
             and then Present (Full_View (Entity (P)))
          then
@@ -1898,6 +1974,7 @@ package body Sem_Attr is
         and then Aname /= Name_Address
         and then Aname /= Name_Code_Address
         and then Aname /= Name_Count
+        and then Aname /= Name_Result
         and then Aname /= Name_Unchecked_Access
       then
          Error_Attr ("ambiguous prefix for % attribute", P);
@@ -1914,9 +1991,10 @@ package body Sem_Attr is
          --  entry wrappers, the attributes Count, Caller and AST_Entry require
          --  a context check
 
-         if Aname = Name_Count
-           or else Aname = Name_Caller
-           or else Aname = Name_AST_Entry
+         if Ada_Version >= Ada_05
+           and then (Aname = Name_Count
+                      or else Aname = Name_Caller
+                      or else Aname = Name_AST_Entry)
          then
             declare
                Count : Natural := 0;
@@ -1988,7 +2066,13 @@ package body Sem_Attr is
          --  An Address attribute created by expansion is legal even when it
          --  applies to other entity-denoting expressions.
 
-         if Is_Entity_Name (P) then
+         if Is_Protected_Self_Reference (P) then
+
+            --  Address attribute on a protected object self reference is legal
+
+            null;
+
+         elsif Is_Entity_Name (P) then
             declare
                Ent : constant Entity_Id := Entity (P);
 
@@ -2009,6 +2093,28 @@ package body Sem_Attr is
                      Error_Attr_P
                        ("prefix of % attribute cannot be Inline_Always" &
                         " subprogram");
+
+                  --  It is illegal to apply 'Address to an intrinsic
+                  --  subprogram. This is now formalized in AI05-0095.
+                  --  In an instance, an attempt to obtain 'Address of an
+                  --  intrinsic subprogram (e.g the renaming of a predefined
+                  --  operator that is an actual) raises Program_Error.
+
+                  elsif Convention (Ent) = Convention_Intrinsic then
+                     if In_Instance then
+                        Rewrite (N,
+                          Make_Raise_Program_Error (Loc,
+                            Reason => PE_Address_Of_Intrinsic));
+
+                     else
+                        Error_Msg_N
+                         ("cannot take Address of intrinsic subprogram", N);
+                     end if;
+
+                  --  Issue an error if prefix denotes an eliminated subprogram
+
+                  else
+                     Check_For_Eliminated_Subprogram (P, Ent);
                   end if;
 
                elsif Is_Object (Ent)
@@ -2449,10 +2555,25 @@ package body Sem_Attr is
          then
             Error_Attr ("invalid prefix for % attribute", P);
             Set_Address_Taken (Entity (P));
+
+         --  Issue an error if the prefix denotes an eliminated subprogram
+
+         else
+            Check_For_Eliminated_Subprogram (P, Entity (P));
          end if;
 
          Set_Etype (N, RTE (RE_Address));
 
+      ----------------------
+      -- Compiler_Version --
+      ----------------------
+
+      when Attribute_Compiler_Version =>
+         Check_E0;
+         Check_Standard_Prefix;
+         Rewrite (N, Make_String_Literal (Loc, "GNAT " & Gnat_Version_String));
+         Analyze_And_Resolve (N, Standard_String);
+
       --------------------
       -- Component_Size --
       --------------------
@@ -2975,6 +3096,15 @@ package body Sem_Attr is
          Set_Etype (N, P_Base_Type);
          Resolve (E1, P_Base_Type);
 
+      --------------
+      -- From_Any --
+      --------------
+
+      when Attribute_From_Any =>
+         Check_E1;
+         Check_PolyORB_Attribute;
+         Set_Etype (N, P_Base_Type);
+
       -----------------------
       -- Has_Access_Values --
       -----------------------
@@ -3737,10 +3867,20 @@ package body Sem_Attr is
       ------------
 
       when Attribute_Result => Result : declare
-         CS : constant Entity_Id := Current_Scope;
-         PS : constant Entity_Id := Scope (CS);
+         CS : Entity_Id := Current_Scope;
+         PS : Entity_Id := Scope (CS);
 
       begin
+         --  If the enclosing subprogram is always inlined, the enclosing
+         --  postcondition will not be propagated to the expanded call.
+
+         if Has_Pragma_Inline_Always (PS)
+           and then Warn_On_Redundant_Constructs
+         then
+            Error_Msg_N
+              ("postconditions on inlined functions not enforced?", N);
+         end if;
+
          --  If we are in the scope of a function and in Spec_Expression mode,
          --  this is likely the prescan of the postcondition pragma, and we
          --  just set the proper type. If there is an error it will be caught
@@ -3768,30 +3908,60 @@ package body Sem_Attr is
             end if;
 
          --  Body case, where we must be inside a generated _Postcondition
-         --  procedure, or the attribute use is definitely misplaced.
+         --  procedure, and the prefix must be on the scope stack, or else
+         --  the attribute use is definitely misplaced. The condition itself
+         --  may have generated transient scopes, and is not necessarily the
+         --  current one.
 
-         elsif Chars (CS) = Name_uPostconditions
-           and then Ekind (PS) = E_Function
-         then
-            --  Check OK prefix
+         else
+            while Present (CS)
+              and then CS /= Standard_Standard
+            loop
+               if Chars (CS) = Name_uPostconditions then
+                  exit;
+               else
+                  CS := Scope (CS);
+               end if;
+            end loop;
 
-            if Nkind (P) /= N_Identifier
-              or else Chars (P) /= Chars (PS)
+            PS := Scope (CS);
+
+            if Chars (CS) = Name_uPostconditions
+              and then Ekind (PS) = E_Function
             then
-               Error_Msg_NE
-                 ("incorrect prefix for % attribute, expected &", P, PS);
-               Error_Attr;
-            end if;
+               --  Check OK prefix
 
-            Rewrite (N,
-              Make_Identifier (Sloc (N),
-                Chars => Name_uResult));
-            Analyze_And_Resolve (N, Etype (PS));
+               if Nkind_In (P, N_Identifier, N_Operator_Symbol)
+                 and then Chars (P) = Chars (PS)
+               then
+                  null;
 
-         else
-            Error_Attr
-              ("% attribute can only appear in function Postcondition pragma",
-               P);
+               --  Within an instance, the prefix designates the local renaming
+               --  of the original generic.
+
+               elsif Is_Entity_Name (P)
+                 and then Ekind (Entity (P)) = E_Function
+                 and then Present (Alias (Entity (P)))
+                 and then Chars (Alias (Entity (P))) = Chars (PS)
+               then
+                  null;
+
+               else
+                  Error_Msg_NE
+                    ("incorrect prefix for % attribute, expected &", P, PS);
+                  Error_Attr;
+               end if;
+
+               Rewrite (N,
+                 Make_Identifier (Sloc (N),
+                   Chars => Name_uResult));
+               Analyze_And_Resolve (N, Etype (PS));
+
+            else
+               Error_Attr
+                 ("% attribute can only appear" &
+                   "  in function Postcondition pragma", P);
+            end if;
          end if;
       end Result;
 
@@ -4213,6 +4383,15 @@ package body Sem_Attr is
          Analyze_And_Resolve (E1, Any_Integer);
          Set_Etype (N, RTE (RE_Address));
 
+      ------------
+      -- To_Any --
+      ------------
+
+      when Attribute_To_Any =>
+         Check_E1;
+         Check_PolyORB_Attribute;
+         Set_Etype (N, RTE (RE_Any));
+
       ----------------
       -- Truncation --
       ----------------
@@ -4232,6 +4411,15 @@ package body Sem_Attr is
          Check_Not_Incomplete_Type;
          Set_Etype (N, RTE (RE_Type_Class));
 
+      --------------
+      -- TypeCode --
+      --------------
+
+      when Attribute_TypeCode =>
+         Check_E0;
+         Check_PolyORB_Attribute;
+         Set_Etype (N, RTE (RE_TypeCode));
+
       -----------------
       -- UET_Address --
       -----------------
@@ -4735,7 +4923,7 @@ package body Sem_Attr is
 
          --  Check that result is in bounds of the type if it is static
 
-         if Is_In_Range (N, T) then
+         if Is_In_Range (N, T, Assume_Valid => False) then
             null;
 
          elsif Is_Out_Of_Range (N, T) then
@@ -5153,7 +5341,7 @@ package body Sem_Attr is
                if Present (AS) and then Is_Constrained (AS) then
                   P_Entity := AS;
 
-               --  If we have an unconstrained type, cannot fold
+               --  If we have an unconstrained type we cannot fold
 
                else
                   Check_Expressions;
@@ -5413,6 +5601,10 @@ package body Sem_Attr is
          --  Again we compute the variable Static for easy reference later
          --  (note that no array attributes are static in Ada 83).
 
+         --  We also need to set Static properly for subsequent legality checks
+         --  which might otherwise accept non-static constants in contexts
+         --  where they are not legal.
+
          Static := Ada_Version >= Ada_95
                      and then Statically_Denotes_Entity (P);
 
@@ -5421,6 +5613,16 @@ package body Sem_Attr is
 
          begin
             N := First_Index (P_Type);
+
+            --  The expression is static if the array type is constrained
+            --  by given bounds, and not by an initial expression. Constant
+            --  strings are static in any case.
+
+            if Root_Type (P_Type) /= Standard_String then
+               Static :=
+                 Static and then not Is_Constr_Subt_For_U_Nominal (P_Type);
+            end if;
+
             while Present (N) loop
                Static := Static and then Is_Static_Subtype (Etype (N));
 
@@ -5990,12 +6192,11 @@ package body Sem_Attr is
          Ind : Node_Id;
 
       begin
-         --  In the case of a generic index type, the bounds may
-         --  appear static but the computation is not meaningful,
-         --  and may generate a spurious warning.
+         --  In the case of a generic index type, the bounds may appear static
+         --  but the computation is not meaningful in this case, and may
+         --  generate a spurious warning.
 
          Ind := First_Index (P_Type);
-
          while Present (Ind) loop
             if Is_Generic_Type (Etype (Ind)) then
                return;
@@ -6006,6 +6207,8 @@ package body Sem_Attr is
 
          Set_Bounds;
 
+         --  For two compile time values, we can compute length
+
          if Compile_Time_Known_Value (Lo_Bound)
            and then Compile_Time_Known_Value (Hi_Bound)
          then
@@ -6013,6 +6216,33 @@ package body Sem_Attr is
               UI_Max (0, 1 + (Expr_Value (Hi_Bound) - Expr_Value (Lo_Bound))),
               True);
          end if;
+
+         --  One more case is where Hi_Bound and Lo_Bound are compile-time
+         --  comparable, and we can figure out the difference between them.
+
+         declare
+            Diff : aliased Uint;
+
+         begin
+            case
+              Compile_Time_Compare
+                (Lo_Bound, Hi_Bound, Diff'Access, Assume_Valid => False)
+            is
+               when EQ =>
+                  Fold_Uint (N, Uint_1, False);
+
+               when GT =>
+                  Fold_Uint (N, Uint_0, False);
+
+               when LT =>
+                  if Diff /= No_Uint then
+                     Fold_Uint (N, Diff + 1, False);
+                  end if;
+
+               when others =>
+                  null;
+            end case;
+         end;
       end Length;
 
       -------------
@@ -6504,6 +6734,8 @@ package body Sem_Attr is
       when Attribute_Range_Length =>
          Set_Bounds;
 
+         --  Can fold if both bounds are compile time known
+
          if Compile_Time_Known_Value (Hi_Bound)
            and then Compile_Time_Known_Value (Lo_Bound)
          then
@@ -6513,6 +6745,33 @@ package body Sem_Attr is
                  Static);
          end if;
 
+         --  One more case is where Hi_Bound and Lo_Bound are compile-time
+         --  comparable, and we can figure out the difference between them.
+
+         declare
+            Diff : aliased Uint;
+
+         begin
+            case
+              Compile_Time_Compare
+                (Lo_Bound, Hi_Bound, Diff'Access, Assume_Valid => False)
+            is
+               when EQ =>
+                  Fold_Uint (N, Uint_1, False);
+
+               when GT =>
+                  Fold_Uint (N, Uint_0, False);
+
+               when LT =>
+                  if Diff /= No_Uint then
+                     Fold_Uint (N, Diff + 1, False);
+                  end if;
+
+               when others =>
+                  null;
+            end case;
+         end;
+
       ---------------
       -- Remainder --
       ---------------
@@ -7228,6 +7487,13 @@ package body Sem_Attr is
          end if;
       end Width;
 
+      --  The following attributes denote function that cannot be folded
+
+      when Attribute_From_Any |
+           Attribute_To_Any   |
+           Attribute_TypeCode =>
+         null;
+
       --  The following attributes can never be folded, and furthermore we
       --  should not even have entered the case statement for any of these.
       --  Note that in some cases, the values have already been folded as
@@ -7246,6 +7512,7 @@ package body Sem_Attr is
            Attribute_Caller                   |
            Attribute_Class                    |
            Attribute_Code_Address             |
+           Attribute_Compiler_Version         |
            Attribute_Count                    |
            Attribute_Default_Bit_Order        |
            Attribute_Elaborated               |
@@ -7463,6 +7730,19 @@ package body Sem_Attr is
                Note_Possible_Modification (P, Sure => False);
             end if;
 
+            --  The following comes from a query by Adam Beneschan, concerning
+            --  improper use of universal_access in equality tests involving
+            --  anonymous access types. Another good reason for 'Ref, but
+            --  for now disable the test, which breaks several filed tests.
+
+            if Ekind (Typ) = E_Anonymous_Access_Type
+              and then Nkind_In (Parent (N), N_Op_Eq, N_Op_Ne)
+              and then False
+            then
+               Error_Msg_N ("need unique type to resolve 'Access", N);
+               Error_Msg_N ("\qualify attribute with some access type", N);
+            end if;
+
             if Is_Entity_Name (P) then
                if Is_Overloaded (P) then
                   Get_First_Interp (P, Index, It);
@@ -7573,16 +7853,16 @@ package body Sem_Attr is
                   --  Check the static accessibility rule of 3.10.2(32).
                   --  This rule also applies within the private part of an
                   --  instantiation. This rule does not apply to anonymous
-                  --  access-to-subprogram types (Ada 2005).
+                  --  access-to-subprogram types in access parameters.
 
                   elsif Attr_Id = Attribute_Access
                     and then not In_Instance_Body
+                    and then
+                      (Ekind (Btyp) = E_Access_Subprogram_Type
+                        or else Is_Local_Anonymous_Access (Btyp))
+
                     and then Subprogram_Access_Level (Entity (P)) >
                                Type_Access_Level (Btyp)
-                    and then Ekind (Btyp) /=
-                               E_Anonymous_Access_Subprogram_Type
-                    and then Ekind (Btyp) /=
-                               E_Anonymous_Access_Protected_Subprogram_Type
                   then
                      Error_Msg_F
                        ("subprogram must not be deeper than access type", P);