diff options
Diffstat (limited to 'gcc/ada/sem_attr.adb')
-rw-r--r-- | gcc/ada/sem_attr.adb | 1160 |
1 files changed, 746 insertions, 414 deletions
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index ca6b3ea0204..83833c15b5a 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2002, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2003, 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_Tss; use Exp_Tss; with Exp_Util; use Exp_Util; with Expander; use Expander; with Freeze; use Freeze; +with Lib; use Lib; with Lib.Xref; use Lib.Xref; with Namet; use Namet; with Nlists; use Nlists; @@ -42,6 +43,7 @@ with Nmake; use Nmake; with Opt; use Opt; with Restrict; use Restrict; with Rtsfind; use Rtsfind; +with Sdefault; use Sdefault; with Sem; use Sem; with Sem_Cat; use Sem_Cat; with Sem_Ch6; use Sem_Ch6; @@ -78,7 +80,7 @@ package body Sem_Attr is -- The following array is the list of attributes defined in the Ada 83 RM - Attribute_83 : Attribute_Class_Array := Attribute_Class_Array'( + Attribute_83 : constant Attribute_Class_Array := Attribute_Class_Array'( Attribute_Address | Attribute_Aft | Attribute_Alignment | @@ -171,16 +173,11 @@ package body Sem_Attr is P_Base_Type : Entity_Id; -- Base type of prefix after analysis - P_Root_Type : Entity_Id; - -- Root type of prefix after analysis - - Unanalyzed : Node_Id; - ----------------------- -- Local Subprograms -- ----------------------- - procedure Access_Attribute; + procedure Analyze_Access_Attribute; -- Used for Access, Unchecked_Access, Unrestricted_Access attributes. -- Internally, Id distinguishes which of the three cases is involved. @@ -279,10 +276,10 @@ package body Sem_Attr is procedure Check_Standard_Prefix; -- Verify that prefix of attribute N is package Standard - procedure Check_Stream_Attribute (Nam : Name_Id); - -- Validity checking for stream attribute. Nam is the name of the + procedure Check_Stream_Attribute (Nam : TSS_Name_Type); + -- Validity checking for stream attribute. Nam is the TSS name of the -- corresponding possible defined attribute function (e.g. for the - -- Read attribute, Nam will be Name_uRead). + -- Read attribute, Nam will be TSS_Stream_Read). procedure Check_Task_Prefix; -- Verify that prefix of attribute N is a task or task type @@ -301,10 +298,14 @@ package body Sem_Attr is procedure Error_Attr (Msg : String; Error_Node : Node_Id); pragma No_Return (Error_Attr); + procedure Error_Attr; + pragma No_Return (Error_Attr); -- Posts error using Error_Msg_N at given node, sets type of attribute -- node to Any_Type, and then raises Bad_Attribute to avoid any further -- semantic processing. The message typically contains a % insertion - -- character which is replaced by the attribute name. + -- character which is replaced by the attribute name. The call with + -- no arguments is used when the caller has already generated the + -- required error messages. procedure Standard_Attribute (Val : Int); -- Used to process attributes whose prefix is package Standard which @@ -320,11 +321,11 @@ package body Sem_Attr is -- non-scalar arguments or returns a non-scalar result. Verifies that -- such a call does not appear in a preelaborable context. - ---------------------- - -- Access_Attribute -- - ---------------------- + ------------------------------ + -- Analyze_Access_Attribute -- + ------------------------------ - procedure Access_Attribute is + procedure Analyze_Access_Attribute is Acc_Type : Entity_Id; Scop : Entity_Id; @@ -378,6 +379,10 @@ package body Sem_Attr is -- Distinguish between access to regular and protected -- subprograms. + -------------- + -- Get_Kind -- + -------------- + function Get_Kind (E : Entity_Id) return Entity_Kind is begin if Convention (E) = Convention_Protected then @@ -422,7 +427,7 @@ package body Sem_Attr is end if; end Build_Access_Subprogram_Type; - -- Start of processing for Access_Attribute + -- Start of processing for Analyze_Access_Attribute begin Check_E0; @@ -430,12 +435,13 @@ package body Sem_Attr is if Nkind (P) = N_Character_Literal then Error_Attr ("prefix of % attribute cannot be enumeration literal", P); + end if; -- In the case of an access to subprogram, use the name of the -- subprogram itself as the designated type. Type-checking in -- this case compares the signatures of the designated types. - elsif Is_Entity_Name (P) + if Is_Entity_Name (P) and then Is_Overloadable (Entity (P)) then if not Is_Library_Level_Entity (Entity (P)) then @@ -443,12 +449,21 @@ package body Sem_Attr is end if; Build_Access_Subprogram_Type (P); + + -- For unrestricted access, kill current values, since this + -- attribute allows a reference to a local subprogram that + -- could modify local variables to be passed out of scope + + if Aname = Name_Unrestricted_Access then + Kill_Current_Values; + end if; + return; -- Component is an operation of a protected type. - elsif (Nkind (P) = N_Selected_Component - and then Is_Overloadable (Entity (Selector_Name (P)))) + elsif Nkind (P) = N_Selected_Component + and then Is_Overloadable (Entity (Selector_Name (P))) then if Ekind (Entity (Selector_Name (P))) = E_Entry then Error_Attr ("prefix of % attribute must be subprogram", P); @@ -518,7 +533,7 @@ package body Sem_Attr is -- is rewritten as a reference to the current object. elsif Ekind (Scop) = E_Procedure - and then Chars (Scop) = Name_uInit_Proc + and then Is_Init_Proc (Scop) and then Etype (First_Formal (Scop)) = Typ then Rewrite (N, @@ -568,6 +583,16 @@ package body Sem_Attr is end; end if; + -- If we have an access to an object, and the attribute comes + -- from source, then set the object as potentially source modified. + -- We do this because the resulting access pointer can be used to + -- modify the variable, and we might not detect this, leading to + -- some junk warnings. + + if Is_Entity_Name (P) then + Set_Never_Set_In_Source (Entity (P), False); + end if; + -- Check for aliased view unless unrestricted case. We allow -- a nonaliased prefix when within an instance because the -- prefix may have been a tagged formal object, which is @@ -580,8 +605,7 @@ package body Sem_Attr is then Error_Attr ("prefix of % attribute must be aliased", P); end if; - - end Access_Attribute; + end Analyze_Access_Attribute; -------------------------------- -- Check_Array_Or_Scalar_Type -- @@ -743,7 +767,9 @@ package body Sem_Attr is if not Is_Static_Expression (E1) or else Raises_Constraint_Error (E1) then - Error_Attr ("expression for dimension must be static", E1); + Flag_Non_Static_Expr + ("expression for dimension must be static!", E1); + Error_Attr; elsif UI_To_Int (Expr_Value (E1)) > D or else UI_To_Int (Expr_Value (E1)) < 1 @@ -770,8 +796,9 @@ package body Sem_Attr is return; elsif not Is_OK_Static_Expression (E1) then - Error_Attr - ("constraint argument must be static string expression", E1); + Flag_Non_Static_Expr + ("constraint argument must be static string expression!", E1); + Error_Attr; end if; -- Check second argument is right type @@ -838,7 +865,6 @@ package body Sem_Attr is end if; P_Base_Type := Base_Type (P_Type); - P_Root_Type := Root_Type (P_Base_Type); end if; end Check_Dereference; @@ -1152,7 +1178,7 @@ package body Sem_Attr is -- Check_Stream_Attribute -- ---------------------------- - procedure Check_Stream_Attribute (Nam : Name_Id) is + procedure Check_Stream_Attribute (Nam : TSS_Name_Type) is Etyp : Entity_Id; Btyp : Entity_Id; @@ -1164,7 +1190,7 @@ package body Sem_Attr is -- for this here, before they are rewritten, to give a more precise -- diagnostic. - if Nam = Name_uInput then + if Nam = TSS_Stream_Input then null; elsif Is_List_Member (N) @@ -1175,7 +1201,7 @@ package body Sem_Attr is else Error_Attr - ("invalid context for attribute %, which is a procedure", N); + ("invalid context for attribute%, which is a procedure", N); end if; Check_Type; @@ -1189,22 +1215,19 @@ package body Sem_Attr is and then not Present (TSS (Btyp, Nam)) and then No (Get_Rep_Pragma (Btyp, Name_Stream_Convert)) then - -- Special case the message if we are compiling the stub version - -- of a remote operation. One error on the type is sufficient. + Error_Msg_Name_1 := Aname; + Error_Msg_NE + ("limited type& has no% attribute", P, Btyp); + Explain_Limited_Type (P_Type, P); + end if; - if (Is_Remote_Types (Current_Scope) - or else Is_Remote_Call_Interface (Current_Scope)) - and then not Error_Posted (Btyp) - then - Error_Msg_Node_2 := Current_Scope; - Error_Msg_NE - ("limited type& used in& has no stream attributes", P, Btyp); - Set_Error_Posted (Btyp); - - elsif not Error_Posted (Btyp) then - Error_Msg_NE - ("limited type& has no stream attributes", P, Btyp); - end if; + -- Check for violation of restriction No_Stream_Attributes + + if Is_RTE (P_Type, RE_Exception_Id) + or else + Is_RTE (P_Type, RE_Exception_Occurrence) + then + Check_Restriction (No_Exception_Registration, P); end if; -- Here we must check that the first argument is an access type @@ -1231,7 +1254,7 @@ package body Sem_Attr is if Present (E2) then Analyze (E2); - if Nam = Name_uRead + if Nam = TSS_Stream_Read and then not Is_OK_Variable_For_Out_Formal (E2) then Error_Attr @@ -1254,7 +1277,7 @@ package body Sem_Attr is or else (Is_Access_Type (Etype (P)) and then Is_Task_Type (Designated_Type (Etype (P)))) then - Resolve (P, Etype (P)); + Resolve (P); else Error_Attr ("prefix of % attribute must be a task", P); end if; @@ -1307,15 +1330,20 @@ package body Sem_Attr is -- Error_Attr -- ---------------- - procedure Error_Attr (Msg : String; Error_Node : Node_Id) is + procedure Error_Attr is begin - Error_Msg_Name_1 := Aname; - Error_Msg_N (Msg, Error_Node); Set_Etype (N, Any_Type); Set_Entity (N, Any_Type); raise Bad_Attribute; end Error_Attr; + procedure Error_Attr (Msg : String; Error_Node : Node_Id) is + begin + Error_Msg_Name_1 := Aname; + Error_Msg_N (Msg, Error_Node); + Error_Attr; + end Error_Attr; + ---------------------------- -- Legal_Formal_Attribute -- ---------------------------- @@ -1355,8 +1383,81 @@ package body Sem_Attr is procedure Standard_Attribute (Val : Int) is begin Check_Standard_Prefix; - Rewrite (N, - Make_Integer_Literal (Loc, Val)); + + -- First a special check (more like a kludge really). For GNAT5 + -- on Windows, the alignments in GCC are severely mixed up. In + -- particular, we have a situation where the maximum alignment + -- that GCC thinks is possible is greater than the guaranteed + -- alignment at run-time. That causes many problems. As a partial + -- cure for this situation, we force a value of 4 for the maximum + -- alignment attribute on this target. This still does not solve + -- all problems, but it helps. + + -- A further (even more horrible) dimension to this kludge is now + -- installed. There are two uses for Maximum_Alignment, one is to + -- determine the maximum guaranteed alignment, that's the one we + -- want the kludge to yield as 4. The other use is to maximally + -- align objects, we can't use 4 here, since for example, long + -- long integer has an alignment of 8, so we will get errors. + + -- It is of course impossible to determine which use the programmer + -- has in mind, but an approximation for now is to disconnect the + -- kludge if the attribute appears in an alignment clause. + + -- To be removed if GCC ever gets its act together here ??? + + Alignment_Kludge : declare + P : Node_Id; + + function On_X86 return Boolean; + -- Determine if target is x86 (ia32), return True if so + + ------------ + -- On_X86 -- + ------------ + + function On_X86 return Boolean is + T : String := Sdefault.Target_Name.all; + + begin + -- There is no clean way to check this. That's not surprising, + -- the front end should not be doing this kind of test ???. The + -- way we do it is test for either "86" or "pentium" being in + -- the string for the target name. + + for J in T'First .. T'Last - 1 loop + if T (J .. J + 1) = "86" + or else (J <= T'Last - 6 + and then T (J .. J + 6) = "pentium") + then + return True; + end if; + end loop; + + return False; + end On_X86; + + begin + if Aname = Name_Maximum_Alignment and then On_X86 then + P := Parent (N); + + while Nkind (P) in N_Subexpr loop + P := Parent (P); + end loop; + + if Nkind (P) /= N_Attribute_Definition_Clause + or else Chars (P) /= Name_Alignment + then + Rewrite (N, Make_Integer_Literal (Loc, 4)); + Analyze (N); + return; + end if; + end if; + end Alignment_Kludge; + + -- Normally we get the value from gcc ??? + + Rewrite (N, Make_Integer_Literal (Loc, Val)); Analyze (N); end Standard_Attribute; @@ -1380,7 +1481,8 @@ package body Sem_Attr is if In_Preelaborated_Unit and then not In_Subprogram_Or_Concurrent_Unit then - Error_Msg_N ("non-static function call in preelaborated unit", N); + Flag_Non_Static_Expr + ("non-static function call in preelaborated unit!", N); end if; end Validate_Non_Static_Attribute_Function_Call; @@ -1398,14 +1500,16 @@ package body Sem_Attr is -- Deal with Ada 83 and Features issues - if not Attribute_83 (Attr_Id) then - if Ada_83 and then Comes_From_Source (N) then - Error_Msg_Name_1 := Aname; - Error_Msg_N ("(Ada 83) attribute% is not standard?", N); - end if; + if Comes_From_Source (N) then + if not Attribute_83 (Attr_Id) then + if Ada_83 and then Comes_From_Source (N) then + Error_Msg_Name_1 := Aname; + Error_Msg_N ("(Ada 83) attribute% is not standard?", N); + end if; - if Attribute_Impl_Def (Attr_Id) then - Check_Restriction (No_Implementation_Attributes, N); + if Attribute_Impl_Def (Attr_Id) then + Check_Restriction (No_Implementation_Attributes, N); + end if; end if; end if; @@ -1416,7 +1520,7 @@ package body Sem_Attr is -- with N_aggregate which represents a fat pointer aggregate. if Aname = Name_Access then - Unanalyzed := Copy_Separate_Tree (N); + Discard_Node (Copy_Separate_Tree (N)); end if; -- Analyze prefix and exit if error in analysis. If the prefix is an @@ -1448,7 +1552,6 @@ package body Sem_Attr is end if; P_Base_Type := Base_Type (P_Type); - P_Root_Type := Root_Type (P_Base_Type); end if; -- Analyze expressions that may be present, exiting if an error occurs @@ -1511,7 +1614,7 @@ package body Sem_Attr is ------------ when Attribute_Access => - Access_Attribute; + Analyze_Access_Attribute; ------------- -- Address -- @@ -1533,33 +1636,46 @@ 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_Subprogram (Entity (P)) then - if not Is_Library_Level_Entity (Entity (P)) then - Check_Restriction (No_Implicit_Dynamic_Code, P); - end if; + if Is_Entity_Name (P) then + declare + Ent : constant Entity_Id := Entity (P); - Set_Address_Taken (Entity (P)); + begin + if Is_Subprogram (Ent) then + if not Is_Library_Level_Entity (Ent) then + Check_Restriction (No_Implicit_Dynamic_Code, P); + end if; - elsif Is_Object (Entity (P)) - or else Ekind (Entity (P)) = E_Label - then - Set_Address_Taken (Entity (P)); + Set_Address_Taken (Ent); - elsif (Is_Concurrent_Type (Etype (Entity (P))) - and then Etype (Entity (P)) = Base_Type (Entity (P))) - or else Ekind (Entity (P)) = E_Package - or else Is_Generic_Unit (Entity (P)) - then - Rewrite (N, - New_Occurrence_Of (RTE (RE_Null_Address), Sloc (N))); + elsif Is_Object (Ent) + or else Ekind (Ent) = E_Label + then + Set_Address_Taken (Ent); - else - Error_Attr ("invalid prefix for % attribute", P); - end if; + -- If we have an address of an object, and the attribute + -- comes from source, then set the object as potentially + -- source modified. We do this because the resulting address + -- can potentially be used to modify the variable and we + -- might not detect this, leading to some junk warnings. + + Set_Never_Set_In_Source (Ent, False); + + elsif (Is_Concurrent_Type (Etype (Ent)) + and then Etype (Ent) = Base_Type (Ent)) + or else Ekind (Ent) = E_Package + or else Is_Generic_Unit (Ent) + then + Rewrite (N, + New_Occurrence_Of (RTE (RE_Null_Address), Sloc (N))); + + else + Error_Attr ("invalid prefix for % attribute", P); + end if; + end; elsif Nkind (P) = N_Attribute_Reference - and then Attribute_Name (P) = Name_AST_Entry + and then Attribute_Name (P) = Name_AST_Entry then Rewrite (N, New_Occurrence_Of (RTE (RE_Null_Address), Sloc (N))); @@ -1572,6 +1688,9 @@ package body Sem_Attr is then null; + -- What exactly are we allowing here ??? and is this properly + -- documented in the sinfo documentation for this node ??? + elsif not Comes_From_Source (N) then null; @@ -1767,6 +1886,10 @@ package body Sem_Attr is -- Base -- ---------- + -- Note: when the base attribute appears in the context of a subtype + -- mark, the analysis is done by Sem_Ch8.Find_Type, rather than by + -- the following circuit. + when Attribute_Base => Base : declare Typ : Entity_Id; @@ -1775,7 +1898,13 @@ package body Sem_Attr is Find_Type (P); Typ := Entity (P); - if Sloc (Typ) = Standard_Location + if Ada_95 + and then not Is_Scalar_Type (Typ) + and then not Is_Generic_Type (Typ) + then + Error_Msg_N ("prefix of Base attribute must be scalar type", N); + + elsif Sloc (Typ) = Standard_Location and then Base_Type (Typ) = Typ and then Warn_On_Redundant_Constructs then @@ -1859,7 +1988,7 @@ package body Sem_Attr is end if; Set_Etype (N, RTE (RE_Bit_Order)); - Resolve (N, Etype (N)); + Resolve (N); -- Reset incorrect indication of staticness @@ -2058,10 +2187,18 @@ package body Sem_Attr is -- be completed, cannot apply Constrained to incomplete type. elsif Is_Private_Type (Entity (P)) then + + -- Note: this is one of the Annex J features that does not + -- generate a warning from -gnatwj, since in fact it seems + -- very useful, and is used in the GNAT runtime. + Check_Not_Incomplete_Type; return; end if; + -- Normal (non-obsolescent case) of application to object of + -- a discriminated type. + else Check_Object_Reference (P); @@ -2221,17 +2358,8 @@ package body Sem_Attr is if It.Nam = Ent then null; - elsif Scope (It.Nam) = Scope (Ent) then - Error_Attr ("ambiguous entry name", N); - else - -- For now make this into a warning. Will become an - -- error after the 3.15 release. - - Error_Msg_N - ("ambiguous name, resolved to entry?", N); - Error_Msg_N - ("\(this will become an error in a later release)?", N); + Error_Attr ("ambiguous entry name", N); end if; Get_Next_Interp (Index, It); @@ -2473,7 +2601,7 @@ package body Sem_Attr is or else (Is_Access_Type (Etype (P)) and then Is_Task_Type (Designated_Type (Etype (P)))) then - Resolve (P, Etype (P)); + Resolve (P); Set_Etype (N, RTE (RO_AT_Task_ID)); else @@ -2532,8 +2660,7 @@ package body Sem_Attr is when Attribute_Input => Check_E1; - Check_Stream_Attribute (Name_uInput); - Disallow_In_No_Run_Time_Mode (N); + Check_Stream_Attribute (TSS_Stream_Input); Set_Etype (N, P_Base_Type); ------------------- @@ -2700,7 +2827,6 @@ package body Sem_Attr is -------------------- when Attribute_Mechanism_Code => - if not Is_Entity_Name (P) or else not Is_Subprogram (Entity (P)) then @@ -2714,8 +2840,9 @@ package body Sem_Attr is Set_Etype (E1, Standard_Integer); if not Is_Static_Expression (E1) then - Error_Attr - ("expression for parameter number must be static", E1); + Flag_Non_Static_Expr + ("expression for parameter number must be static!", E1); + Error_Attr; elsif UI_To_Int (Intval (E1)) > Number_Formals (Entity (P)) or else UI_To_Int (Intval (E1)) < 0 @@ -2901,9 +3028,8 @@ package body Sem_Attr is when Attribute_Output => Check_E2; - Check_Stream_Attribute (Name_uInput); + Check_Stream_Attribute (TSS_Stream_Output); Set_Etype (N, Standard_Void_Type); - Disallow_In_No_Run_Time_Mode (N); Resolve (N, Standard_Void_Type); ------------------ @@ -2941,6 +3067,14 @@ package body Sem_Attr is Check_Type; Set_Etype (N, Standard_Boolean); + ------------------ + -- Pool_Address -- + ------------------ + + when Attribute_Pool_Address => + Check_E0; + Set_Etype (N, RTE (RE_Address)); + --------- -- Pos -- --------- @@ -3013,10 +3147,9 @@ package body Sem_Attr is when Attribute_Read => Check_E2; - Check_Stream_Attribute (Name_uRead); + Check_Stream_Attribute (TSS_Stream_Read); Set_Etype (N, Standard_Void_Type); Resolve (N, Standard_Void_Type); - Disallow_In_No_Run_Time_Mode (N); Note_Possible_Modification (E2); --------------- @@ -3295,6 +3428,31 @@ package body Sem_Attr is Set_Etype (N, RTE (RE_Tag)); + ----------------- + -- Target_Name -- + ----------------- + + when Attribute_Target_Name => Target_Name : declare + TN : constant String := Sdefault.Target_Name.all; + TL : Integer := TN'Last; + + begin + Check_Standard_Prefix; + Check_E0; + Start_String; + + if TN (TL) = '/' or else TN (TL) = '\' then + TL := TL - 1; + end if; + + Store_String_Chars (TN (TN'First .. TL)); + + Rewrite (N, + Make_String_Literal (Loc, + Strval => End_String)); + Analyze_And_Resolve (N, Standard_String); + end Target_Name; + ---------------- -- Terminated -- ---------------- @@ -3368,7 +3526,17 @@ package body Sem_Attr is Check_Restriction (No_Unchecked_Access, N); end if; - Access_Attribute; + Analyze_Access_Attribute; + + ------------------------- + -- Unconstrained_Array -- + ------------------------- + + when Attribute_Unconstrained_Array => + Check_E0; + Check_Type; + Check_Not_Incomplete_Type; + Set_Etype (N, Standard_Boolean); ------------------------------ -- Universal_Literal_String -- @@ -3455,7 +3623,7 @@ package body Sem_Attr is Set_Address_Taken (Entity (P)); end if; - Access_Attribute; + Analyze_Access_Attribute; --------- -- Val -- @@ -3507,10 +3675,11 @@ package body Sem_Attr is Check_Restriction (No_Enumeration_Maps, N); end if; - -- Set Etype before resolving expression because expansion - -- of expression may require enclosing type. + -- Set Etype before resolving expression because expansion of + -- expression may require enclosing type. Note that the type + -- returned by 'Value is the base type of the prefix type. - Set_Etype (N, P_Type); + Set_Etype (N, P_Base_Type); Validate_Non_Static_Attribute_Function_Call; end Value; @@ -3600,9 +3769,8 @@ package body Sem_Attr is when Attribute_Write => Check_E2; - Check_Stream_Attribute (Name_uWrite); + Check_Stream_Attribute (TSS_Stream_Write); Set_Etype (N, Standard_Void_Type); - Disallow_In_No_Run_Time_Mode (N); Resolve (N, Standard_Void_Type); end case; @@ -3651,7 +3819,9 @@ package body Sem_Attr is -- The root type of the prefix type Static : Boolean; - -- True if prefix type is static + -- True if the result is Static. This is set by the general processing + -- to true if the prefix is static, and all expressions are static. It + -- can be reset as processing continues for particular attributes Lo_Bound, Hi_Bound : Node_Id; -- Expressions for low and high bounds of type or array index referenced @@ -3673,6 +3843,12 @@ package body Sem_Attr is -- any, of the attribute, are in a non-static context. This procedure -- performs the required additional checks. + function Compile_Time_Known_Bounds (Typ : Entity_Id) return Boolean; + -- Determines if the given type has compile time known bounds. Note + -- that we enter the case statement even in cases where the prefix + -- type does NOT have known bounds, so it is important to guard any + -- attempt to evaluate both bounds with a call to this function. + procedure Compile_Time_Known_Attribute (N : Node_Id; Val : Uint); -- This procedure is called when the attribute N has a non-static -- but compile time known value given by Val. It includes the @@ -3684,7 +3860,9 @@ package body Sem_Attr is IEEEX_Val : Int; VAXFF_Val : Int; VAXDF_Val : Int; - VAXGF_Val : Int); + VAXGF_Val : Int; + AAMPS_Val : Int; + AAMPL_Val : Int); -- This procedure evaluates a float attribute with no arguments that -- returns a universal integer result. The parameters give the values -- for the possible floating-point root types. See ttypef for details. @@ -3696,7 +3874,9 @@ package body Sem_Attr is IEEEX_Val : String; VAXFF_Val : String; VAXDF_Val : String; - VAXGF_Val : String); + VAXGF_Val : String; + AAMPS_Val : String; + AAMPL_Val : String); -- This procedure evaluates a float attribute with no arguments that -- returns a universal real result. The parameters give the values -- required for the possible floating-point root types in string @@ -3712,11 +3892,12 @@ package body Sem_Attr is procedure Set_Bounds; -- Used for First, Last and Length attributes applied to an array or - -- array subtype. Sets the variables Index_Lo and Index_Hi to the low + -- array subtype. Sets the variables Lo_Bound and Hi_Bound to the low -- and high bound expressions for the index referenced by the attribute -- designator (i.e. the first index if no expression is present, and -- the N'th index if the value N is present as an expression). Also - -- used for First and Last of scalar types. + -- used for First and Last of scalar types. Static is reset to False + -- if the type or index type is not statically constrained. --------------- -- Aft_Value -- @@ -3760,8 +3941,7 @@ package body Sem_Attr is T : constant Entity_Id := Etype (N); begin - Fold_Uint (N, Val); - Set_Is_Static_Expression (N, False); + Fold_Uint (N, Val, False); -- Check that result is in bounds of the type if it is static @@ -3780,6 +3960,18 @@ package body Sem_Attr is end if; end Compile_Time_Known_Attribute; + ------------------------------- + -- Compile_Time_Known_Bounds -- + ------------------------------- + + function Compile_Time_Known_Bounds (Typ : Entity_Id) return Boolean is + begin + return + Compile_Time_Known_Value (Type_Low_Bound (Typ)) + and then + Compile_Time_Known_Value (Type_High_Bound (Typ)); + end Compile_Time_Known_Bounds; + --------------------------------------- -- Float_Attribute_Universal_Integer -- --------------------------------------- @@ -3790,22 +3982,15 @@ package body Sem_Attr is IEEEX_Val : Int; VAXFF_Val : Int; VAXDF_Val : Int; - VAXGF_Val : Int) + VAXGF_Val : Int; + AAMPS_Val : Int; + AAMPL_Val : Int) is Val : Int; Digs : constant Nat := UI_To_Int (Digits_Value (P_Base_Type)); begin - if not Vax_Float (P_Base_Type) then - if Digs = IEEES_Digits then - Val := IEEES_Val; - elsif Digs = IEEEL_Digits then - Val := IEEEL_Val; - else pragma Assert (Digs = IEEEX_Digits); - Val := IEEEX_Val; - end if; - - else + if Vax_Float (P_Base_Type) then if Digs = VAXFF_Digits then Val := VAXFF_Val; elsif Digs = VAXDF_Digits then @@ -3813,9 +3998,25 @@ package body Sem_Attr is else pragma Assert (Digs = VAXGF_Digits); Val := VAXGF_Val; end if; + + elsif Is_AAMP_Float (P_Base_Type) then + if Digs = AAMPS_Digits then + Val := AAMPS_Val; + else pragma Assert (Digs = AAMPL_Digits); + Val := AAMPL_Val; + end if; + + else + if Digs = IEEES_Digits then + Val := IEEES_Val; + elsif Digs = IEEEL_Digits then + Val := IEEEL_Val; + else pragma Assert (Digs = IEEEX_Digits); + Val := IEEEX_Val; + end if; end if; - Fold_Uint (N, UI_From_Int (Val)); + Fold_Uint (N, UI_From_Int (Val), True); end Float_Attribute_Universal_Integer; ------------------------------------ @@ -3828,22 +4029,15 @@ package body Sem_Attr is IEEEX_Val : String; VAXFF_Val : String; VAXDF_Val : String; - VAXGF_Val : String) + VAXGF_Val : String; + AAMPS_Val : String; + AAMPL_Val : String) is Val : Node_Id; Digs : constant Nat := UI_To_Int (Digits_Value (P_Base_Type)); begin - if not Vax_Float (P_Base_Type) then - if Digs = IEEES_Digits then - Val := Real_Convert (IEEES_Val); - elsif Digs = IEEEL_Digits then - Val := Real_Convert (IEEEL_Val); - else pragma Assert (Digs = IEEEX_Digits); - Val := Real_Convert (IEEEX_Val); - end if; - - else + if Vax_Float (P_Base_Type) then if Digs = VAXFF_Digits then Val := Real_Convert (VAXFF_Val); elsif Digs = VAXDF_Digits then @@ -3851,10 +4045,27 @@ package body Sem_Attr is else pragma Assert (Digs = VAXGF_Digits); Val := Real_Convert (VAXGF_Val); end if; + + elsif Is_AAMP_Float (P_Base_Type) then + if Digs = AAMPS_Digits then + Val := Real_Convert (AAMPS_Val); + else pragma Assert (Digs = AAMPL_Digits); + Val := Real_Convert (AAMPL_Val); + end if; + + else + if Digs = IEEES_Digits then + Val := Real_Convert (IEEES_Val); + elsif Digs = IEEEL_Digits then + Val := Real_Convert (IEEEL_Val); + else pragma Assert (Digs = IEEEX_Digits); + Val := Real_Convert (IEEEX_Val); + end if; end if; Set_Sloc (Val, Loc); Rewrite (N, Val); + Set_Is_Static_Expression (N, Static); Analyze_And_Resolve (N, C_Type); end Float_Attribute_Universal_Real; @@ -3975,8 +4186,8 @@ package body Sem_Attr is -- low bound. if Ekind (P_Type) = E_String_Literal_Subtype then - Lo_Bound := - Type_Low_Bound (Etype (First_Index (Base_Type (P_Type)))); + Ityp := Etype (First_Index (Base_Type (P_Type))); + Lo_Bound := Type_Low_Bound (Ityp); Hi_Bound := Make_Integer_Literal (Sloc (P), @@ -3992,6 +4203,9 @@ package body Sem_Attr is elsif Is_Scalar_Type (P_Type) then Ityp := P_Type; + -- For a fixed-point type, we must freeze to get the attributes + -- of the fixed-point type set now so we can reference them. + if Is_Fixed_Point_Type (P_Type) and then not Is_Frozen (Base_Type (P_Type)) and then Compile_Time_Known_Value (Type_Low_Bound (P_Type)) @@ -4037,6 +4251,9 @@ package body Sem_Attr is Lo_Bound := Type_Low_Bound (Ityp); Hi_Bound := Type_High_Bound (Ityp); + if not Is_Static_Subtype (Ityp) then + Static := False; + end if; end Set_Bounds; -- Start of processing for Eval_Attribute @@ -4053,9 +4270,11 @@ package body Sem_Attr is E2 := Empty; end if; - -- Special processing for cases where the prefix is an object + -- Special processing for cases where the prefix is an object. For + -- this purpose, a string literal counts as an object (attributes + -- of string literals can only appear in generated code). - if Is_Object_Reference (P) then + if Is_Object_Reference (P) or else Nkind (P) = N_String_Literal then -- For Component_Size, the prefix is an array object, and we apply -- the attribute to the type of the object. This is allowed for @@ -4079,10 +4298,10 @@ package body Sem_Attr is AS : constant Entity_Id := Get_Actual_Subtype_If_Available (P); begin - if Present (AS) then + if Present (AS) and then Is_Constrained (AS) then P_Entity := AS; - -- If no actual subtype, cannot fold + -- If we have an unconstrained type, cannot fold else Check_Expressions; @@ -4094,7 +4313,6 @@ package body Sem_Attr is -- cannot fold Size. elsif Id = Attribute_Size then - if Is_Entity_Name (P) and then Known_Esize (Entity (P)) then @@ -4110,12 +4328,10 @@ package body Sem_Attr is -- cannot fold Alignment. elsif Id = Attribute_Alignment then - if Is_Entity_Name (P) and then Known_Alignment (Entity (P)) then - Fold_Uint (N, Alignment (Entity (P))); - Set_Is_Static_Expression (N, False); + Fold_Uint (N, Alignment (Entity (P)), False); return; else @@ -4187,13 +4403,16 @@ package body Sem_Attr is -- Definite must be folded if the prefix is not a generic type, -- that is to say if we are within an instantiation. Same processing - -- applies to the GNAT attributes Has_Discriminants and Type_Class + -- applies to the GNAT attributes Has_Discriminants, Type_Class, + -- and Unconstrained_Array. elsif (Id = Attribute_Definite or else Id = Attribute_Has_Discriminants or else - Id = Attribute_Type_Class) + Id = Attribute_Type_Class + or else + Id = Attribute_Unconstrained_Array) and then not Is_Generic_Type (P_Entity) then P_Type := P_Entity; @@ -4213,8 +4432,23 @@ package body Sem_Attr is Compile_Time_Known_Attribute (N, RM_Size (P_Entity)); return; + -- We can fold 'Alignment applied to a type if the alignment is known + -- (as happens for an alignment from an attribute definition clause). + -- At this stage, this can happen only for types (e.g. record + -- types) for which the size is always non-static. We exclude + -- generic types from consideration (since they have bogus + -- sizes set within templates). + + elsif Id = Attribute_Alignment + and then Is_Type (P_Entity) + and then (not Is_Generic_Type (P_Entity)) + and then Known_Alignment (P_Entity) + then + Compile_Time_Known_Attribute (N, Alignment (P_Entity)); + return; + -- No other cases are foldable (they certainly aren't static, and at - -- the moment we don't try to fold any cases other than the two above) + -- the moment we don't try to fold any cases other than these three). else Check_Expressions; @@ -4269,14 +4503,16 @@ package body Sem_Attr is -- In addition Component_Size is possibly foldable, even though it -- can never be static. - -- Definite, Has_Discriminants and Type_Class are again exceptions, - -- because they apply as well to unconstrained types. + -- Definite, Has_Discriminants, Type_Class and Unconstrained_Array are + -- again exceptions, because they apply as well to unconstrained types. elsif Id = Attribute_Definite or else Id = Attribute_Has_Discriminants or else Id = Attribute_Type_Class + or else + Id = Attribute_Unconstrained_Array then Static := False; @@ -4296,7 +4532,7 @@ package body Sem_Attr is -- cases which we can fold at compile time even though they are not -- static (e.g. 'Length applied to a static index, even though other -- non-static indexes make the array type non-static). This is only - -- ab optimization, but it falls out essentially free, so why not. + -- an optimization, but it falls out essentially free, so why not. -- Again we compute the variable Static for easy reference later -- (note that no array attributes are static in Ada 83). @@ -4308,7 +4544,17 @@ package body Sem_Attr is begin N := First_Index (P_Type); while Present (N) loop - Static := Static and Is_Static_Subtype (Etype (N)); + Static := Static and then Is_Static_Subtype (Etype (N)); + + -- If however the index type is generic, attributes cannot + -- be folded. + + if Is_Generic_Type (Etype (N)) + and then Id /= Attribute_Component_Size + then + return; + end if; + Next_Index (N); end loop; end; @@ -4330,15 +4576,23 @@ package body Sem_Attr is while Present (E) loop -- If expression is not static, then the attribute reference - -- certainly is neither foldable nor static, so we can quit - -- after calling Apply_Range_Check for 'Pos attributes. + -- result certainly cannot be static. + + if not Is_Static_Expression (E) then + Static := False; + end if; - -- We can also quit if the expression is not of a scalar type - -- as noted above. + -- If the result is not known at compile time, or is not of + -- a scalar type, then the result is definitely not static, + -- so we can quit now. - if not Is_Static_Expression (E) + if not Compile_Time_Known_Value (E) or else not Is_Scalar_Type (Etype (E)) then + -- An odd special case, if this is a Pos attribute, this + -- is where we need to apply a range check since it does + -- not get done anywhere else. + if Id = Attribute_Pos then if Is_Integer_Type (Etype (E)) then Apply_Range_Check (E, Etype (N)); @@ -4397,6 +4651,15 @@ package body Sem_Attr is -- be foldable, and the individual attribute processing routines -- test Static as required in cases where it makes a difference. + -- In the case where Static is not set, we do know that all the + -- expressions present are at least known at compile time (we + -- assumed above that if this was not the case, then there was + -- no hope of static evaluation). However, we did not require + -- that the bounds of the prefix type be compile time known, + -- let alone static). That's because there are many attributes + -- that can be computed at compile time on non-static subtypes, + -- even though such references are not static expressions. + case Id is -------------- @@ -4404,18 +4667,16 @@ package body Sem_Attr is -------------- when Attribute_Adjacent => - if Static then - Fold_Ureal (N, - Eval_Fat.Adjacent - (P_Root_Type, Expr_Value_R (E1), Expr_Value_R (E2))); - end if; + Fold_Ureal (N, + Eval_Fat.Adjacent + (P_Root_Type, Expr_Value_R (E1), Expr_Value_R (E2)), Static); --------- -- Aft -- --------- when Attribute_Aft => - Fold_Uint (N, UI_From_Int (Aft_Value)); + Fold_Uint (N, UI_From_Int (Aft_Value), True); --------------- -- Alignment -- @@ -4428,7 +4689,7 @@ package body Sem_Attr is -- Fold if alignment is set and not otherwise if Known_Alignment (P_TypeA) then - Fold_Uint (N, Alignment (P_TypeA)); + Fold_Uint (N, Alignment (P_TypeA), Is_Discrete_Type (P_TypeA)); end if; end Alignment_Block; @@ -4469,18 +4730,16 @@ package body Sem_Attr is ------------- when Attribute_Ceiling => - if Static then - Fold_Ureal (N, - Eval_Fat.Ceiling (P_Root_Type, Expr_Value_R (E1))); - end if; + Fold_Ureal (N, + Eval_Fat.Ceiling (P_Root_Type, Expr_Value_R (E1)), Static); -------------------- -- Component_Size -- -------------------- when Attribute_Component_Size => - if Component_Size (P_Type) /= 0 then - Fold_Uint (N, Component_Size (P_Type)); + if Known_Static_Component_Size (P_Type) then + Fold_Uint (N, Component_Size (P_Type), False); end if; ------------- @@ -4488,11 +4747,10 @@ package body Sem_Attr is ------------- when Attribute_Compose => - if Static then - Fold_Ureal (N, - Eval_Fat.Compose - (P_Root_Type, Expr_Value_R (E1), Expr_Value (E2))); - end if; + Fold_Ureal (N, + Eval_Fat.Compose + (P_Root_Type, Expr_Value_R (E1), Expr_Value (E2)), + Static); ----------------- -- Constrained -- @@ -4509,18 +4767,16 @@ package body Sem_Attr is --------------- when Attribute_Copy_Sign => - if Static then - Fold_Ureal (N, - Eval_Fat.Copy_Sign - (P_Root_Type, Expr_Value_R (E1), Expr_Value_R (E2))); - end if; + Fold_Ureal (N, + Eval_Fat.Copy_Sign + (P_Root_Type, Expr_Value_R (E1), Expr_Value_R (E2)), Static); ----------- -- Delta -- ----------- when Attribute_Delta => - Fold_Ureal (N, Delta_Value (P_Type)); + Fold_Ureal (N, Delta_Value (P_Type), True); -------------- -- Definite -- @@ -4547,14 +4803,14 @@ package body Sem_Attr is when Attribute_Denorm => Fold_Uint - (N, UI_From_Int (Boolean'Pos (Denorm_On_Target))); + (N, UI_From_Int (Boolean'Pos (Denorm_On_Target)), True); ------------ -- Digits -- ------------ when Attribute_Digits => - Fold_Uint (N, Digits_Value (P_Type)); + Fold_Uint (N, Digits_Value (P_Type), True); ---------- -- Emax -- @@ -4566,34 +4822,32 @@ package body Sem_Attr is -- T'Emax = 4 * T'Mantissa - Fold_Uint (N, 4 * Mantissa); + Fold_Uint (N, 4 * Mantissa, True); -------------- -- Enum_Rep -- -------------- when Attribute_Enum_Rep => - if Static then - -- For an enumeration type with a non-standard representation - -- use the Enumeration_Rep field of the proper constant. Note - -- that this would not work for types Character/Wide_Character, - -- since no real entities are created for the enumeration - -- literals, but that does not matter since these two types - -- do not have non-standard representations anyway. + -- For an enumeration type with a non-standard representation + -- use the Enumeration_Rep field of the proper constant. Note + -- that this would not work for types Character/Wide_Character, + -- since no real entities are created for the enumeration + -- literals, but that does not matter since these two types + -- do not have non-standard representations anyway. - if Is_Enumeration_Type (P_Type) - and then Has_Non_Standard_Rep (P_Type) - then - Fold_Uint (N, Enumeration_Rep (Expr_Value_E (E1))); + if Is_Enumeration_Type (P_Type) + and then Has_Non_Standard_Rep (P_Type) + then + Fold_Uint (N, Enumeration_Rep (Expr_Value_E (E1)), Static); - -- For enumeration types with standard representations and all - -- other cases (i.e. all integer and modular types), Enum_Rep - -- is equivalent to Pos. + -- For enumeration types with standard representations and all + -- other cases (i.e. all integer and modular types), Enum_Rep + -- is equivalent to Pos. - else - Fold_Uint (N, Expr_Value (E1)); - end if; + else + Fold_Uint (N, Expr_Value (E1), Static); end if; ------------- @@ -4606,17 +4860,15 @@ package body Sem_Attr is -- T'Epsilon = 2.0**(1 - T'Mantissa) - Fold_Ureal (N, Ureal_2 ** (1 - Mantissa)); + Fold_Ureal (N, Ureal_2 ** (1 - Mantissa), True); -------------- -- Exponent -- -------------- when Attribute_Exponent => - if Static then - Fold_Uint (N, - Eval_Fat.Exponent (P_Root_Type, Expr_Value_R (E1))); - end if; + Fold_Uint (N, + Eval_Fat.Exponent (P_Root_Type, Expr_Value_R (E1)), Static); ----------- -- First -- @@ -4628,9 +4880,9 @@ package body Sem_Attr is if Compile_Time_Known_Value (Lo_Bound) then if Is_Real_Type (P_Type) then - Fold_Ureal (N, Expr_Value_R (Lo_Bound)); + Fold_Ureal (N, Expr_Value_R (Lo_Bound), Static); else - Fold_Uint (N, Expr_Value (Lo_Bound)); + Fold_Uint (N, Expr_Value (Lo_Bound), Static); end if; end if; end First_Attr; @@ -4647,18 +4899,16 @@ package body Sem_Attr is ----------- when Attribute_Floor => - if Static then - Fold_Ureal (N, - Eval_Fat.Floor (P_Root_Type, Expr_Value_R (E1))); - end if; + Fold_Ureal (N, + Eval_Fat.Floor (P_Root_Type, Expr_Value_R (E1)), Static); ---------- -- Fore -- ---------- when Attribute_Fore => - if Static then - Fold_Uint (N, UI_From_Int (Fore_Value)); + if Compile_Time_Known_Bounds (P_Type) then + Fold_Uint (N, UI_From_Int (Fore_Value), Static); end if; -------------- @@ -4666,10 +4916,8 @@ package body Sem_Attr is -------------- when Attribute_Fraction => - if Static then - Fold_Ureal (N, - Eval_Fat.Fraction (P_Root_Type, Expr_Value_R (E1))); - end if; + Fold_Ureal (N, + Eval_Fat.Fraction (P_Root_Type, Expr_Value_R (E1)), Static); ----------------------- -- Has_Discriminants -- @@ -4766,8 +5014,8 @@ package body Sem_Attr is -- T'Emax = 4 * T'Mantissa Fold_Ureal (N, - Ureal_2 ** (4 * Mantissa) * - (Ureal_1 - Ureal_2 ** (-Mantissa))); + Ureal_2 ** (4 * Mantissa) * (Ureal_1 - Ureal_2 ** (-Mantissa)), + True); end if; ---------- @@ -4780,9 +5028,9 @@ package body Sem_Attr is if Compile_Time_Known_Value (Hi_Bound) then if Is_Real_Type (P_Type) then - Fold_Ureal (N, Expr_Value_R (Hi_Bound)); + Fold_Ureal (N, Expr_Value_R (Hi_Bound), Static); else - Fold_Uint (N, Expr_Value (Hi_Bound)); + Fold_Uint (N, Expr_Value (Hi_Bound), Static); end if; end if; end Last; @@ -4792,25 +5040,40 @@ package body Sem_Attr is ------------------ when Attribute_Leading_Part => - if Static then - Fold_Ureal (N, - Eval_Fat.Leading_Part - (P_Root_Type, Expr_Value_R (E1), Expr_Value (E2))); - end if; + Fold_Ureal (N, + Eval_Fat.Leading_Part + (P_Root_Type, Expr_Value_R (E1), Expr_Value (E2)), Static); ------------ -- Length -- ------------ - when Attribute_Length => Length : + when Attribute_Length => Length : declare + 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. + + Ind := First_Index (P_Type); + + while Present (Ind) loop + if Is_Generic_Type (Etype (Ind)) then + return; + end if; + + Next_Index (Ind); + end loop; + Set_Bounds; if Compile_Time_Known_Value (Lo_Bound) and then Compile_Time_Known_Value (Hi_Bound) then Fold_Uint (N, - UI_Max (0, 1 + (Expr_Value (Hi_Bound) - Expr_Value (Lo_Bound)))); + UI_Max (0, 1 + (Expr_Value (Hi_Bound) - Expr_Value (Lo_Bound))), + True); end if; end Length; @@ -4819,11 +5082,10 @@ package body Sem_Attr is ------------- when Attribute_Machine => - if Static then - Fold_Ureal (N, - Eval_Fat.Machine (P_Root_Type, Expr_Value_R (E1), - Eval_Fat.Round)); - end if; + Fold_Ureal (N, + Eval_Fat.Machine + (P_Root_Type, Expr_Value_R (E1), Eval_Fat.Round, N), + Static); ------------------ -- Machine_Emax -- @@ -4836,7 +5098,9 @@ package body Sem_Attr is IEEEX_Machine_Emax, VAXFF_Machine_Emax, VAXDF_Machine_Emax, - VAXGF_Machine_Emax); + VAXGF_Machine_Emax, + AAMPS_Machine_Emax, + AAMPL_Machine_Emax); ------------------ -- Machine_Emin -- @@ -4849,7 +5113,9 @@ package body Sem_Attr is IEEEX_Machine_Emin, VAXFF_Machine_Emin, VAXDF_Machine_Emin, - VAXGF_Machine_Emin); + VAXGF_Machine_Emin, + AAMPS_Machine_Emin, + AAMPL_Machine_Emin); ---------------------- -- Machine_Mantissa -- @@ -4862,7 +5128,9 @@ package body Sem_Attr is IEEEX_Machine_Mantissa, VAXFF_Machine_Mantissa, VAXDF_Machine_Mantissa, - VAXGF_Machine_Mantissa); + VAXGF_Machine_Mantissa, + AAMPS_Machine_Mantissa, + AAMPL_Machine_Mantissa); ----------------------- -- Machine_Overflows -- @@ -4873,13 +5141,14 @@ package body Sem_Attr is -- Always true for fixed-point if Is_Fixed_Point_Type (P_Type) then - Fold_Uint (N, True_Value); + Fold_Uint (N, True_Value, True); -- Floating point case else - Fold_Uint - (N, UI_From_Int (Boolean'Pos (Machine_Overflows_On_Target))); + Fold_Uint (N, + UI_From_Int (Boolean'Pos (Machine_Overflows_On_Target)), + True); end if; ------------------- @@ -4891,15 +5160,15 @@ package body Sem_Attr is if Is_Decimal_Fixed_Point_Type (P_Type) and then Machine_Radix_10 (P_Type) then - Fold_Uint (N, Uint_10); + Fold_Uint (N, Uint_10, True); else - Fold_Uint (N, Uint_2); + Fold_Uint (N, Uint_2, True); end if; -- All floating-point type always have radix 2 else - Fold_Uint (N, Uint_2); + Fold_Uint (N, Uint_2, True); end if; -------------------- @@ -4911,13 +5180,13 @@ package body Sem_Attr is -- Always False for fixed-point if Is_Fixed_Point_Type (P_Type) then - Fold_Uint (N, False_Value); + Fold_Uint (N, False_Value, True); -- Else yield proper floating-point result else Fold_Uint - (N, UI_From_Int (Boolean'Pos (Machine_Rounds_On_Target))); + (N, UI_From_Int (Boolean'Pos (Machine_Rounds_On_Target)), True); end if; ------------------ @@ -4931,7 +5200,7 @@ package body Sem_Attr is begin if Known_Esize (P_TypeA) then - Fold_Uint (N, Esize (P_TypeA)); + Fold_Uint (N, Esize (P_TypeA), True); end if; end Machine_Size; @@ -5004,7 +5273,7 @@ package body Sem_Attr is Siz := Siz + 1; end loop; - Fold_Uint (N, Siz); + Fold_Uint (N, Siz, True); end; else @@ -5017,7 +5286,7 @@ package body Sem_Attr is -- Floating-point Mantissa else - Fold_Uint (N, Mantissa); + Fold_Uint (N, Mantissa, True); end if; --------- @@ -5027,9 +5296,10 @@ package body Sem_Attr is when Attribute_Max => Max : begin if Is_Real_Type (P_Type) then - Fold_Ureal (N, UR_Max (Expr_Value_R (E1), Expr_Value_R (E2))); + Fold_Ureal + (N, UR_Max (Expr_Value_R (E1), Expr_Value_R (E2)), Static); else - Fold_Uint (N, UI_Max (Expr_Value (E1), Expr_Value (E2))); + Fold_Uint (N, UI_Max (Expr_Value (E1), Expr_Value (E2)), Static); end if; end Max; @@ -5045,7 +5315,8 @@ package body Sem_Attr is if Known_Esize (P_Type) then Fold_Uint (N, (Esize (P_Type) + System_Storage_Unit - 1) / - System_Storage_Unit); + System_Storage_Unit, + Static); end if; -------------------- @@ -5073,7 +5344,7 @@ package body Sem_Attr is end if; if Mech < 0 then - Fold_Uint (N, UI_From_Int (Int (-Mech))); + Fold_Uint (N, UI_From_Int (Int (-Mech)), True); end if; end; @@ -5084,9 +5355,10 @@ package body Sem_Attr is when Attribute_Min => Min : begin if Is_Real_Type (P_Type) then - Fold_Ureal (N, UR_Min (Expr_Value_R (E1), Expr_Value_R (E2))); + Fold_Ureal + (N, UR_Min (Expr_Value_R (E1), Expr_Value_R (E2)), Static); else - Fold_Uint (N, UI_Min (Expr_Value (E1), Expr_Value (E2))); + Fold_Uint (N, UI_Min (Expr_Value (E1), Expr_Value (E2)), Static); end if; end Min; @@ -5095,10 +5367,8 @@ package body Sem_Attr is ----------- when Attribute_Model => - if Static then - Fold_Ureal (N, - Eval_Fat.Model (P_Root_Type, Expr_Value_R (E1))); - end if; + Fold_Ureal (N, + Eval_Fat.Model (P_Root_Type, Expr_Value_R (E1)), Static); ---------------- -- Model_Emin -- @@ -5111,7 +5381,9 @@ package body Sem_Attr is IEEEX_Model_Emin, VAXFF_Model_Emin, VAXDF_Model_Emin, - VAXGF_Model_Emin); + VAXGF_Model_Emin, + AAMPS_Model_Emin, + AAMPL_Model_Emin); ------------------- -- Model_Epsilon -- @@ -5124,7 +5396,9 @@ package body Sem_Attr is IEEEX_Model_Epsilon'Universal_Literal_String, VAXFF_Model_Epsilon'Universal_Literal_String, VAXDF_Model_Epsilon'Universal_Literal_String, - VAXGF_Model_Epsilon'Universal_Literal_String); + VAXGF_Model_Epsilon'Universal_Literal_String, + AAMPS_Model_Epsilon'Universal_Literal_String, + AAMPL_Model_Epsilon'Universal_Literal_String); -------------------- -- Model_Mantissa -- @@ -5137,7 +5411,9 @@ package body Sem_Attr is IEEEX_Model_Mantissa, VAXFF_Model_Mantissa, VAXDF_Model_Mantissa, - VAXGF_Model_Mantissa); + VAXGF_Model_Mantissa, + AAMPS_Model_Mantissa, + AAMPL_Model_Mantissa); ----------------- -- Model_Small -- @@ -5150,14 +5426,16 @@ package body Sem_Attr is IEEEX_Model_Small'Universal_Literal_String, VAXFF_Model_Small'Universal_Literal_String, VAXDF_Model_Small'Universal_Literal_String, - VAXGF_Model_Small'Universal_Literal_String); + VAXGF_Model_Small'Universal_Literal_String, + AAMPS_Model_Small'Universal_Literal_String, + AAMPL_Model_Small'Universal_Literal_String); ------------- -- Modulus -- ------------- when Attribute_Modulus => - Fold_Uint (N, Modulus (P_Type)); + Fold_Uint (N, Modulus (P_Type), True); -------------------- -- Null_Parameter -- @@ -5182,7 +5460,7 @@ package body Sem_Attr is begin if Known_Esize (P_TypeA) then - Fold_Uint (N, Esize (P_TypeA)); + Fold_Uint (N, Esize (P_TypeA), True); end if; end Object_Size; @@ -5193,14 +5471,14 @@ package body Sem_Attr is -- Scalar types are never passed by reference when Attribute_Passed_By_Reference => - Fold_Uint (N, False_Value); + Fold_Uint (N, False_Value, True); --------- -- Pos -- --------- when Attribute_Pos => - Fold_Uint (N, Expr_Value (E1)); + Fold_Uint (N, Expr_Value (E1), True); ---------- -- Pred -- @@ -5208,43 +5486,43 @@ package body Sem_Attr is when Attribute_Pred => Pred : begin - if Static then - - -- Floating-point case. For now, do not fold this, since we - -- don't know how to do it right (see fixed bug 3512-001 ???) + -- Floating-point case - if Is_Floating_Point_Type (P_Type) then - Fold_Ureal (N, - Eval_Fat.Pred (P_Root_Type, Expr_Value_R (E1))); + if Is_Floating_Point_Type (P_Type) then + Fold_Ureal (N, + Eval_Fat.Pred (P_Root_Type, Expr_Value_R (E1)), Static); - -- Fixed-point case + -- Fixed-point case - elsif Is_Fixed_Point_Type (P_Type) then - Fold_Ureal (N, - Expr_Value_R (E1) - Small_Value (P_Type)); + elsif Is_Fixed_Point_Type (P_Type) then + Fold_Ureal (N, + Expr_Value_R (E1) - Small_Value (P_Type), True); - -- Modular integer case (wraps) + -- Modular integer case (wraps) - elsif Is_Modular_Integer_Type (P_Type) then - Fold_Uint (N, (Expr_Value (E1) - 1) mod Modulus (P_Type)); + elsif Is_Modular_Integer_Type (P_Type) then + Fold_Uint (N, (Expr_Value (E1) - 1) mod Modulus (P_Type), Static); - -- Other scalar cases + -- Other scalar cases - else - pragma Assert (Is_Scalar_Type (P_Type)); + else + pragma Assert (Is_Scalar_Type (P_Type)); - if Is_Enumeration_Type (P_Type) - and then Expr_Value (E1) = - Expr_Value (Type_Low_Bound (P_Base_Type)) - then - Apply_Compile_Time_Constraint_Error - (N, "Pred of type''First", CE_Overflow_Check_Failed); - Check_Expressions; - return; - end if; + if Is_Enumeration_Type (P_Type) + and then Expr_Value (E1) = + Expr_Value (Type_Low_Bound (P_Base_Type)) + then + Apply_Compile_Time_Constraint_Error + (N, "Pred of `&''First`", + CE_Overflow_Check_Failed, + Ent => P_Base_Type, + Warn => not Static); - Fold_Uint (N, Expr_Value (E1) - 1); + Check_Expressions; + return; end if; + + Fold_Uint (N, Expr_Value (E1) - 1, Static); end if; end Pred; @@ -5270,7 +5548,8 @@ package body Sem_Attr is then Fold_Uint (N, UI_Max - (0, Expr_Value (Hi_Bound) - Expr_Value (Lo_Bound) + 1)); + (0, Expr_Value (Hi_Bound) - Expr_Value (Lo_Bound) + 1), + Static); end if; --------------- @@ -5278,11 +5557,10 @@ package body Sem_Attr is --------------- when Attribute_Remainder => - if Static then - Fold_Ureal (N, - Eval_Fat.Remainder - (P_Root_Type, Expr_Value_R (E1), Expr_Value_R (E2))); - end if; + Fold_Ureal (N, + Eval_Fat.Remainder + (P_Root_Type, Expr_Value_R (E1), Expr_Value_R (E2)), + Static); ----------- -- Round -- @@ -5294,19 +5572,17 @@ package body Sem_Attr is Si : Uint; begin - if Static then - -- First we get the (exact result) in units of small + -- First we get the (exact result) in units of small - Sr := Expr_Value_R (E1) / Small_Value (C_Type); + Sr := Expr_Value_R (E1) / Small_Value (C_Type); - -- Now round that exactly to an integer + -- Now round that exactly to an integer - Si := UR_To_Uint (Sr); + Si := UR_To_Uint (Sr); - -- Finally the result is obtained by converting back to real + -- Finally the result is obtained by converting back to real - Fold_Ureal (N, Si * Small_Value (C_Type)); - end if; + Fold_Ureal (N, Si * Small_Value (C_Type), Static); end Round; -------------- @@ -5314,10 +5590,8 @@ package body Sem_Attr is -------------- when Attribute_Rounding => - if Static then - Fold_Ureal (N, - Eval_Fat.Rounding (P_Root_Type, Expr_Value_R (E1))); - end if; + Fold_Ureal (N, + Eval_Fat.Rounding (P_Root_Type, Expr_Value_R (E1)), Static); --------------- -- Safe_Emax -- @@ -5330,7 +5604,9 @@ package body Sem_Attr is IEEEX_Safe_Emax, VAXFF_Safe_Emax, VAXDF_Safe_Emax, - VAXGF_Safe_Emax); + VAXGF_Safe_Emax, + AAMPS_Safe_Emax, + AAMPL_Safe_Emax); ---------------- -- Safe_First -- @@ -5343,7 +5619,9 @@ package body Sem_Attr is IEEEX_Safe_First'Universal_Literal_String, VAXFF_Safe_First'Universal_Literal_String, VAXDF_Safe_First'Universal_Literal_String, - VAXGF_Safe_First'Universal_Literal_String); + VAXGF_Safe_First'Universal_Literal_String, + AAMPS_Safe_First'Universal_Literal_String, + AAMPL_Safe_First'Universal_Literal_String); ---------------- -- Safe_Large -- @@ -5351,7 +5629,8 @@ package body Sem_Attr is when Attribute_Safe_Large => if Is_Fixed_Point_Type (P_Type) then - Fold_Ureal (N, Expr_Value_R (Type_High_Bound (P_Base_Type))); + Fold_Ureal + (N, Expr_Value_R (Type_High_Bound (P_Base_Type)), Static); else Float_Attribute_Universal_Real ( IEEES_Safe_Large'Universal_Literal_String, @@ -5359,7 +5638,9 @@ package body Sem_Attr is IEEEX_Safe_Large'Universal_Literal_String, VAXFF_Safe_Large'Universal_Literal_String, VAXDF_Safe_Large'Universal_Literal_String, - VAXGF_Safe_Large'Universal_Literal_String); + VAXGF_Safe_Large'Universal_Literal_String, + AAMPS_Safe_Large'Universal_Literal_String, + AAMPL_Safe_Large'Universal_Literal_String); end if; --------------- @@ -5373,7 +5654,9 @@ package body Sem_Attr is IEEEX_Safe_Last'Universal_Literal_String, VAXFF_Safe_Last'Universal_Literal_String, VAXDF_Safe_Last'Universal_Literal_String, - VAXGF_Safe_Last'Universal_Literal_String); + VAXGF_Safe_Last'Universal_Literal_String, + AAMPS_Safe_Last'Universal_Literal_String, + AAMPL_Safe_Last'Universal_Literal_String); ---------------- -- Safe_Small -- @@ -5386,7 +5669,7 @@ package body Sem_Attr is -- it for backwards compatibility. if Is_Fixed_Point_Type (P_Type) then - Fold_Ureal (N, Small_Value (P_Type)); + Fold_Ureal (N, Small_Value (P_Type), Static); -- Ada 83 Safe_Small for floating-point cases @@ -5397,7 +5680,9 @@ package body Sem_Attr is IEEEX_Safe_Small'Universal_Literal_String, VAXFF_Safe_Small'Universal_Literal_String, VAXDF_Safe_Small'Universal_Literal_String, - VAXGF_Safe_Small'Universal_Literal_String); + VAXGF_Safe_Small'Universal_Literal_String, + AAMPS_Safe_Small'Universal_Literal_String, + AAMPL_Safe_Small'Universal_Literal_String); end if; ----------- @@ -5405,18 +5690,16 @@ package body Sem_Attr is ----------- when Attribute_Scale => - Fold_Uint (N, Scale_Value (P_Type)); + Fold_Uint (N, Scale_Value (P_Type), True); ------------- -- Scaling -- ------------- when Attribute_Scaling => - if Static then - Fold_Ureal (N, - Eval_Fat.Scaling - (P_Root_Type, Expr_Value_R (E1), Expr_Value (E2))); - end if; + Fold_Ureal (N, + Eval_Fat.Scaling + (P_Root_Type, Expr_Value_R (E1), Expr_Value (E2)), Static); ------------------ -- Signed_Zeros -- @@ -5424,7 +5707,7 @@ package body Sem_Attr is when Attribute_Signed_Zeros => Fold_Uint - (N, UI_From_Int (Boolean'Pos (Signed_Zeros_On_Target))); + (N, UI_From_Int (Boolean'Pos (Signed_Zeros_On_Target)), Static); ---------- -- Size -- @@ -5442,8 +5725,7 @@ package body Sem_Attr is -- VADS_Size case - if (Id = Attribute_VADS_Size or else Use_VADS_Size) then - + if Id = Attribute_VADS_Size or else Use_VADS_Size then declare S : constant Node_Id := Size_Clause (P_TypeA); @@ -5453,7 +5735,7 @@ package body Sem_Attr is -- Size_Clause field for a subtype when Has_Size_Clause -- is False. Consider: - -- type x is range 1 .. 64; + -- type x is range 1 .. 64; g -- for x'size use 12; -- subtype y is x range 0 .. 3; @@ -5464,21 +5746,23 @@ package body Sem_Attr is if Present (S) and then Is_OK_Static_Expression (Expression (S)) then - Fold_Uint (N, Expr_Value (Expression (S))); + Fold_Uint (N, Expr_Value (Expression (S)), True); -- If no size is specified, then we simply use the object -- size in the VADS_Size case (e.g. Natural'Size is equal -- to Integer'Size, not one less). else - Fold_Uint (N, Esize (P_TypeA)); + Fold_Uint (N, Esize (P_TypeA), True); end if; end; -- Normal case (Size) in which case we want the RM_Size else - Fold_Uint (N, RM_Size (P_TypeA)); + Fold_Uint (N, + RM_Size (P_TypeA), + Static and then Is_Discrete_Type (P_TypeA)); end if; end if; end Size; @@ -5489,7 +5773,7 @@ package body Sem_Attr is when Attribute_Small => - -- The floating-point case is present only for Ada 83 compatibility. + -- The floating-point case is present only for Ada 83 compatability. -- Note that strictly this is an illegal addition, since we are -- extending an Ada 95 defined attribute, but we anticipate an -- ARG ruling that will permit this. @@ -5504,12 +5788,12 @@ package body Sem_Attr is -- T'Emax = 4 * T'Mantissa - Fold_Ureal (N, Ureal_2 ** ((-(4 * Mantissa)) - 1)); + Fold_Ureal (N, Ureal_2 ** ((-(4 * Mantissa)) - 1), Static); -- Normal Ada 95 fixed-point case else - Fold_Ureal (N, Small_Value (P_Type)); + Fold_Ureal (N, Small_Value (P_Type), True); end if; ---------- @@ -5518,42 +5802,42 @@ package body Sem_Attr is when Attribute_Succ => Succ : begin - if Static then + -- Floating-point case - -- Floating-point case. For now, do not fold this, since we - -- don't know how to do it right (see fixed bug 3512-001 ???) + if Is_Floating_Point_Type (P_Type) then + Fold_Ureal (N, + Eval_Fat.Succ (P_Root_Type, Expr_Value_R (E1)), Static); - if Is_Floating_Point_Type (P_Type) then - Fold_Ureal (N, - Eval_Fat.Succ (P_Root_Type, Expr_Value_R (E1))); + -- Fixed-point case - -- Fixed-point case + elsif Is_Fixed_Point_Type (P_Type) then + Fold_Ureal (N, + Expr_Value_R (E1) + Small_Value (P_Type), Static); - elsif Is_Fixed_Point_Type (P_Type) then - Fold_Ureal (N, - Expr_Value_R (E1) + Small_Value (P_Type)); + -- Modular integer case (wraps) - -- Modular integer case (wraps) + elsif Is_Modular_Integer_Type (P_Type) then + Fold_Uint (N, (Expr_Value (E1) + 1) mod Modulus (P_Type), Static); - elsif Is_Modular_Integer_Type (P_Type) then - Fold_Uint (N, (Expr_Value (E1) + 1) mod Modulus (P_Type)); + -- Other scalar cases - -- Other scalar cases + else + pragma Assert (Is_Scalar_Type (P_Type)); - else - pragma Assert (Is_Scalar_Type (P_Type)); + if Is_Enumeration_Type (P_Type) + and then Expr_Value (E1) = + Expr_Value (Type_High_Bound (P_Base_Type)) + then + Apply_Compile_Time_Constraint_Error + (N, "Succ of `&''Last`", + CE_Overflow_Check_Failed, + Ent => P_Base_Type, + Warn => not Static); - if Is_Enumeration_Type (P_Type) - and then Expr_Value (E1) = - Expr_Value (Type_High_Bound (P_Base_Type)) - then - Apply_Compile_Time_Constraint_Error - (N, "Succ of type''Last", CE_Overflow_Check_Failed); - Check_Expressions; - return; - else - Fold_Uint (N, Expr_Value (E1) + 1); - end if; + Check_Expressions; + return; + else + Fold_Uint (N, Expr_Value (E1) + 1, Static); end if; end if; end Succ; @@ -5563,10 +5847,8 @@ package body Sem_Attr is ---------------- when Attribute_Truncation => - if Static then - Fold_Ureal (N, - Eval_Fat.Truncation (P_Root_Type, Expr_Value_R (E1))); - end if; + Fold_Ureal (N, + Eval_Fat.Truncation (P_Root_Type, Expr_Value_R (E1)), Static); ---------------- -- Type_Class -- @@ -5631,11 +5913,33 @@ package body Sem_Attr is ----------------------- when Attribute_Unbiased_Rounding => - if Static then - Fold_Ureal (N, - Eval_Fat.Unbiased_Rounding (P_Root_Type, Expr_Value_R (E1))); + Fold_Ureal (N, + Eval_Fat.Unbiased_Rounding (P_Root_Type, Expr_Value_R (E1)), + Static); + + ------------------------- + -- Unconstrained_Array -- + ------------------------- + + when Attribute_Unconstrained_Array => Unconstrained_Array : declare + Typ : constant Entity_Id := Underlying_Type (P_Type); + + begin + if Is_Array_Type (P_Type) + and then not Is_Constrained (Typ) + then + Rewrite (N, New_Occurrence_Of (Standard_True, Loc)); + else + Rewrite (N, New_Occurrence_Of (Standard_False, Loc)); end if; + -- Analyze and resolve as boolean, note that this attribute is + -- a static attribute in GNAT. + + Analyze_And_Resolve (N, Standard_Boolean); + Static := True; + end Unconstrained_Array; + --------------- -- VADS_Size -- --------------- @@ -5648,18 +5952,20 @@ package body Sem_Attr is when Attribute_Val => Val : begin - if Static then - if Expr_Value (E1) < Expr_Value (Type_Low_Bound (P_Base_Type)) - or else - Expr_Value (E1) > Expr_Value (Type_High_Bound (P_Base_Type)) - then - Apply_Compile_Time_Constraint_Error - (N, "Val expression out of range", CE_Range_Check_Failed); - Check_Expressions; - return; - else - Fold_Uint (N, Expr_Value (E1)); - end if; + if Expr_Value (E1) < Expr_Value (Type_Low_Bound (P_Base_Type)) + or else + Expr_Value (E1) > Expr_Value (Type_High_Bound (P_Base_Type)) + then + Apply_Compile_Time_Constraint_Error + (N, "Val expression out of range", + CE_Range_Check_Failed, + Warn => not Static); + + Check_Expressions; + return; + + else + Fold_Uint (N, Expr_Value (E1), Static); end if; end Val; @@ -5676,7 +5982,7 @@ package body Sem_Attr is begin if RM_Size (P_TypeA) /= Uint_0 then - Fold_Uint (N, RM_Size (P_TypeA)); + Fold_Uint (N, RM_Size (P_TypeA), True); end if; end Value_Size; @@ -5714,7 +6020,7 @@ package body Sem_Attr is when Attribute_Width | Attribute_Wide_Width => Width : begin - if Static then + if Compile_Time_Known_Bounds (P_Type) then -- Floating-point types @@ -5725,7 +6031,7 @@ package body Sem_Attr is if Expr_Value_R (Type_High_Bound (P_Type)) < Expr_Value_R (Type_Low_Bound (P_Type)) then - Fold_Uint (N, Uint_0); + Fold_Uint (N, Uint_0, True); else -- For floating-point, we have +N.dddE+nnn where length @@ -5747,7 +6053,7 @@ package body Sem_Attr is Len := Len + 7; end if; - Fold_Uint (N, UI_From_Int (Len)); + Fold_Uint (N, UI_From_Int (Len), True); end; end if; @@ -5760,14 +6066,15 @@ package body Sem_Attr is if Expr_Value (Type_High_Bound (P_Type)) < Expr_Value (Type_Low_Bound (P_Type)) then - Fold_Uint (N, Uint_0); + Fold_Uint (N, Uint_0, True); -- The non-null case depends on the specific real type else -- For fixed-point type width is Fore + 1 + Aft (RM 3.5(34)) - Fold_Uint (N, UI_From_Int (Fore_Value + 1 + Aft_Value)); + Fold_Uint + (N, UI_From_Int (Fore_Value + 1 + Aft_Value), True); end if; -- Discrete types @@ -5851,7 +6158,6 @@ package body Sem_Attr is No_Break_Space .. LC_Y_Diaeresis => Wt := 3; - end case; W := Int'Max (W, Wt); @@ -5932,7 +6238,7 @@ package body Sem_Attr is end loop; end if; - Fold_Uint (N, UI_From_Int (W)); + Fold_Uint (N, UI_From_Int (W), True); end; end if; end if; @@ -5968,12 +6274,14 @@ package body Sem_Attr is Attribute_Maximum_Alignment | Attribute_Output | Attribute_Partition_ID | + Attribute_Pool_Address | Attribute_Position | Attribute_Read | Attribute_Storage_Pool | Attribute_Storage_Size | Attribute_Storage_Unit | Attribute_Tag | + Attribute_Target_Name | Attribute_Terminated | Attribute_To_Address | Attribute_UET_Address | @@ -5996,6 +6304,9 @@ package body Sem_Attr is -- in the constant only if the prefix type is a static subtype. For -- non-static subtypes, the folding is still OK, but not static. + -- An exception is the GNAT attribute Constrained_Array which is + -- defined to be a static attribute in all cases. + if Nkind (N) = N_Integer_Literal or else Nkind (N) = N_Real_Literal or else Nkind (N) = N_Character_Literal @@ -6046,9 +6357,9 @@ package body Sem_Attr is P : constant Node_Id := Prefix (N); Aname : constant Name_Id := Attribute_Name (N); Attr_Id : constant Attribute_Id := Get_Attribute_Id (Aname); + Btyp : constant Entity_Id := Base_Type (Typ); Index : Interp_Index; It : Interp; - Btyp : Entity_Id := Base_Type (Typ); Nom_Subt : Entity_Id; begin @@ -6123,7 +6434,7 @@ package body Sem_Attr is elsif not Is_Overloadable (Entity (P)) and then not Is_Type (Entity (P)) then - Resolve (P, Etype (P)); + Resolve (P); end if; if not Is_Entity_Name (P) then @@ -6188,14 +6499,12 @@ package body Sem_Attr is ("subprogram must not be deeper than access type", P); else - Warn_On_Instance := True; Error_Msg_N ("subprogram must not be deeper than access type?", P); Error_Msg_N ("Constraint_Error will be raised ?", P); Set_Raises_Constraint_Error (N); - Warn_On_Instance := False; end if; -- Check the restriction of 3.10.2(32) that disallows @@ -6235,7 +6544,7 @@ package body Sem_Attr is ("attribute% cannot be applied to protected operation", P); end if; - Resolve (Prefix (P), Etype (Prefix (P))); + Resolve (Prefix (P)); Generate_Reference (Entity (Selector_Name (P)), P); elsif Is_Overloaded (P) then @@ -6257,7 +6566,7 @@ package body Sem_Attr is end loop; end; else - Resolve (P, Etype (P)); + Resolve (P); end if; -- X'Access is illegal if X denotes a constant and the access @@ -6355,10 +6664,12 @@ package body Sem_Attr is end if; elsif not Subtypes_Statically_Match - (Designated_Type (Typ), Nom_Subt) + (Designated_Type (Base_Type (Typ)), Nom_Subt) and then not (Has_Discriminants (Designated_Type (Typ)) - and then not Is_Constrained (Designated_Type (Typ))) + and then + not Is_Constrained + (Designated_Type (Base_Type (Typ)))) then Error_Msg_N ("object subtype must statically match " @@ -6516,7 +6827,7 @@ package body Sem_Attr is if not Is_Task_Type (Etype (P)) or else Nkind (P) = N_Explicit_Dereference then - Resolve (P, Etype (P)); + Resolve (P); end if; end if; @@ -6571,11 +6882,23 @@ package body Sem_Attr is -- Count -- ----------- - -- Prefix of the Count attribute is an entry name which must not - -- be resolved, since this is definitely not an entry call. + -- If the prefix of the Count attribute is an entry name it must not + -- be resolved, since this is definitely not an entry call. However, + -- if it is an element of an entry family, the index itself may + -- have to be resolved because it can be a general expression. when Attribute_Count => - null; + if Nkind (P) = N_Indexed_Component + and then Is_Entity_Name (Prefix (P)) + then + declare + Indx : constant Node_Id := First (Expressions (P)); + Fam : constant Entity_Id := Entity (Prefix (P)); + begin + Resolve (Indx, Entry_Index_Type (Fam)); + Apply_Range_Check (Indx, Entry_Index_Type (Fam)); + end; + end if; ---------------- -- Elaborated -- @@ -6609,6 +6932,9 @@ package body Sem_Attr is Process_Partition_Id (N); return; + when Attribute_Pool_Address => + Resolve (P); + ----------- -- Range -- ----------- @@ -6635,6 +6961,10 @@ package body Sem_Attr is -- explicit. This solves some complex visibility problems -- related to the use of privals. + -------------------------------- + -- Check_Discriminated_Prival -- + -------------------------------- + function Check_Discriminated_Prival (N : Node_Id) return Node_Id @@ -6656,7 +6986,7 @@ package body Sem_Attr is if not Is_Entity_Name (P) or else not Is_Type (Entity (P)) then - Resolve (P, Etype (P)); + Resolve (P); end if; -- Check whether prefix is (renaming of) private component @@ -6671,11 +7001,13 @@ package body Sem_Attr is Ekind (Scope (Scope (Entity (P)))) = E_Protected_Type) then - LB := Check_Discriminated_Prival ( - Type_Low_Bound (Etype (First_Index (Etype (P))))); + LB := + Check_Discriminated_Prival + (Type_Low_Bound (Etype (First_Index (Etype (P))))); - HB := Check_Discriminated_Prival ( - Type_High_Bound (Etype (First_Index (Etype (P))))); + HB := + Check_Discriminated_Prival + (Type_High_Bound (Etype (First_Index (Etype (P))))); else HB := @@ -6797,7 +7129,7 @@ package body Sem_Attr is if not Is_Entity_Name (P) or else not Is_Type (Entity (P)) then - Resolve (P, Etype (P)); + Resolve (P); end if; -- If the attribute reference itself is a type name ('Base, |