diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-15 13:51:09 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-15 13:51:09 +0000 |
commit | 38f5559fd6bb31438a619828fe363fea2e34d17b (patch) | |
tree | 0efbfab4fb3d55403546ebeaa30ac64cbc05ef81 /gcc/ada/exp_ch4.adb | |
parent | 02747205c562d60e12b1c96b8cd6d3ee6eedea3a (diff) | |
download | gcc-38f5559fd6bb31438a619828fe363fea2e34d17b.tar.gz |
2005-11-14 Robert Dewar <dewar@adacore.com>
Ed Schonberg <schonberg@adacore.com>
PR ada/18434
* types.ads: Include All_Checks in Suppress_Array
* checks.adb (Check_Needed): Remove kludge for a/=b rewritten as
not(a=b), since we no longer do this rewriting, and hence it is not
needed.
(Elaboration_Checks_Suppressed): Add special casing to
deal with different cases of static and dynamic elaboration checks (all
checks does not count in the first case, but does in the second).
(Expr_Known_Valid): Do not assume that the result of any arbitrary
function call is valid, since this is not the case.
(Ensure_Valid): Do not apply validity check to a real literal
in a universal or fixed context
* exp_ch4.adb (Expand_N_Op_Ne): Don't expand a/=b to not(a=b) for
elementary types using the operator in standard. It is cleaner not to
modify the programmers intent, especially in the case of floating-point.
(Rewrite_Comparison): Fix handling of /= (this was always wrong, but
it did not matter because we always rewrote a/=b to not(a=b).
(Expand_Allocator_Expression): For an allocator expression whose nominal
subtype is an unconstrained packed type, convert the expression to its
actual constrained subtype.
Implement warning for <= or >= where < or > not possible
Fix to Vax_Float tests (too early in many routines, causing premature
Vax_Float expansions.
* sem_prag.adb (Analyze_Pragma, case Obsolescent): Allow this pragma
to be used with packages and generic packages as well as with
subprograms.
(Suppress): Set All_Checks, but not Elaboration_Check, for case
of pragma Suppress (All_Checks)
(Analyze_Pragma, case Warnings): Implement first argument allowed to be
a string literal for precise control over warnings.
Avoid raise of pragma in case of unrecognized pragma and just return
instead.
* sem_prag.ads: Minor reformatting
* switch-c.adb (Scan_Front_End_Switches): Replace "raise Bad_Switch;"
with call to new procedure Bad_Switch. Call Scan_Pos with new parameter
Switch. Do not handle any exception.
Include -gnatwx as part of -gnatg (warn on redundant parens)
Allow optional = after -gnatm
(Scan_Front_End_Switches): The -gnatp switch sets All_Checks, but no
longer sets Elaboration_Checks.
Code to set warning mode moved to Sem_Warn
so that it can be shared by pragma processing.
* s-mastop-tru64.adb (Pop_Frame): Remove redundant parentheses in if
statement.
* s-taprop-solaris.adb:
Change some <= to =, to avoid new warning
* a-exexda.adb, prj-proc.adb:
Fix obvious typo (Num_Tracebacks compared <= 0 instead of < 0)
Fix obvious typo (Total_Errors_Detected <= 0 should be = 0)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@106950 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_ch4.adb')
-rw-r--r-- | gcc/ada/exp_ch4.adb | 322 |
1 files changed, 208 insertions, 114 deletions
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index fbdb701550a..2e1f38f88e4 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2005 Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2005, 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- -- @@ -38,6 +38,7 @@ with Exp_Pakd; use Exp_Pakd; with Exp_Tss; use Exp_Tss; with Exp_Util; use Exp_Util; with Exp_VFpt; use Exp_VFpt; +with Freeze; use Freeze; with Hostparm; use Hostparm; with Inline; use Inline; with Nlists; use Nlists; @@ -361,14 +362,15 @@ package body Exp_Ch4 is --------------------------------- procedure Expand_Allocator_Expression (N : Node_Id) is - Loc : constant Source_Ptr := Sloc (N); - Exp : constant Node_Id := Expression (Expression (N)); - Indic : constant Node_Id := Subtype_Mark (Expression (N)); - PtrT : constant Entity_Id := Etype (N); - T : constant Entity_Id := Entity (Indic); - Flist : Node_Id; - Node : Node_Id; - Temp : Entity_Id; + Loc : constant Source_Ptr := Sloc (N); + Exp : constant Node_Id := Expression (Expression (N)); + Indic : constant Node_Id := Subtype_Mark (Expression (N)); + PtrT : constant Entity_Id := Etype (N); + DesigT : constant Entity_Id := Designated_Type (PtrT); + T : constant Entity_Id := Entity (Indic); + Flist : Node_Id; + Node : Node_Id; + Temp : Entity_Id; Aggr_In_Place : constant Boolean := Is_Delayed_Aggregate (Exp); @@ -456,7 +458,7 @@ package body Exp_Ch4 is -- body, so a run-time check is needed in general. if Ada_Version >= Ada_05 - and then Is_Class_Wide_Type (Designated_Type (PtrT)) + and then Is_Class_Wide_Type (DesigT) and then not Scope_Suppress (Accessibility_Check) and then (Is_Class_Wide_Type (Etype (Exp)) @@ -539,7 +541,7 @@ package body Exp_Ch4 is end; end if; - if Controlled_Type (Designated_Type (PtrT)) + if Controlled_Type (DesigT) and then Controlled_Type (T) then declare @@ -629,14 +631,14 @@ package body Exp_Ch4 is Rewrite (N, New_Reference_To (Temp, Loc)); Analyze_And_Resolve (N, PtrT); - elsif Is_Access_Type (Designated_Type (PtrT)) + elsif Is_Access_Type (DesigT) and then Nkind (Exp) = N_Allocator and then Nkind (Expression (Exp)) /= N_Qualified_Expression then -- Apply constraint to designated subtype indication Apply_Constraint_Check (Expression (Exp), - Designated_Type (Designated_Type (PtrT)), + Designated_Type (DesigT), No_Sliding => True); if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then @@ -663,12 +665,12 @@ package body Exp_Ch4 is -- on the qualified expression does not allow sliding, -- but this check does (a relaxation from Ada 83). - if Is_Constrained (Designated_Type (PtrT)) + if Is_Constrained (DesigT) and then not Subtypes_Statically_Match - (T, Designated_Type (PtrT)) + (T, DesigT) then Apply_Constraint_Check - (Exp, Designated_Type (PtrT), No_Sliding => False); + (Exp, DesigT, No_Sliding => False); -- The nonsliding check should really be performed -- (unconditionally) against the subtype of the @@ -677,8 +679,33 @@ package body Exp_Ch4 is else Apply_Constraint_Check - (Exp, Designated_Type (PtrT), No_Sliding => True); + (Exp, DesigT, No_Sliding => True); + end if; + + -- For an access to unconstrained packed array, GIGI needs + -- to see an expression with a constrained subtype in order + -- to compute the proper size for the allocator. + + if Is_Array_Type (T) + and then not Is_Constrained (T) + and then Is_Packed (T) + then + declare + ConstrT : constant Entity_Id := + Make_Defining_Identifier (Loc, + Chars => New_Internal_Name ('A')); + Internal_Exp : constant Node_Id := Relocate_Node (Exp); + begin + Insert_Action (Exp, + Make_Subtype_Declaration (Loc, + Defining_Identifier => ConstrT, + Subtype_Indication => + Make_Subtype_From_Expr (Exp, T))); + Freeze_Itype (ConstrT, Exp); + Rewrite (Exp, OK_Convert_To (ConstrT, Internal_Exp)); + end; end if; + end if; exception @@ -3854,13 +3881,6 @@ package body Exp_Ch4 is begin Binary_Op_Validity_Checks (N); - -- Vax_Float is a special case - - if Vax_Float (Typ) then - Expand_Vax_Arith (N); - return; - end if; - -- N / 1 = N for integer types if Is_Integer_Type (Typ) @@ -3951,7 +3971,7 @@ package body Exp_Ch4 is Analyze_And_Resolve (Left_Opnd (N), Universal_Real); - -- Non-fixed point cases, do zero divide and overflow checks + -- Non-fixed point cases, do integer zero divide and overflow checks elsif Is_Integer_Type (Typ) then Apply_Divide_Check (N); @@ -3963,6 +3983,12 @@ package body Exp_Ch4 is then Error_Msg_CRT ("64-bit division", N); end if; + + -- Deal with Vax_Float + + elsif Vax_Float (Typ) then + Expand_Vax_Arith (N); + return; end if; end Expand_N_Op_Divide; @@ -4023,7 +4049,7 @@ package body Exp_Ch4 is begin -- Per-object constrained selected components require special -- attention. If the enclosing scope of the component is an - -- Unchecked_Union, we can not reference its discriminants + -- Unchecked_Union, we cannot reference its discriminants -- directly. This is why we use the two extra parameters of -- the equality function of the enclosing Unchecked_Union. @@ -4239,14 +4265,13 @@ package body Exp_Ch4 is return False; end if; + -- We only need to test one component + declare Comp : Node_Id := First (Component_Items (Clist)); begin while Present (Comp) loop - - -- One component is sufficent - if Component_Is_Unconstrained_UU (Comp) then return True; end if; @@ -4324,9 +4349,10 @@ package body Exp_Ch4 is if Ekind (Typl) = E_Private_Type then Typl := Underlying_Type (Typl); - elsif Ekind (Typl) = E_Private_Subtype then Typl := Underlying_Type (Base_Type (Typl)); + else + null; end if; -- It may happen in error situations that the underlying type is not @@ -4339,15 +4365,9 @@ package body Exp_Ch4 is Typl := Base_Type (Typl); - -- Vax float types - - if Vax_Float (Typl) then - Expand_Vax_Comparison (N); - return; - -- Boolean types (requiring handling of non-standard case) - elsif Is_Boolean_Type (Typl) then + if Is_Boolean_Type (Typl) then Adjust_Condition (Left_Opnd (N)); Adjust_Condition (Right_Opnd (N)); Set_Etype (N, Standard_Boolean); @@ -4551,11 +4571,18 @@ package body Exp_Ch4 is end if; -- If we still have an equality comparison (i.e. it was not rewritten - -- in some way), then we can test if result is needed at compile time). + -- in some way), then we can test if result is known at compile time). if Nkind (N) = N_Op_Eq then Rewrite_Comparison (N); end if; + + -- If we still have comparison for Vax_Float, process it + + if Vax_Float (Typl) and then Nkind (N) in N_Op_Compare then + Expand_Vax_Comparison (N); + return; + end if; end Expand_N_Op_Eq; ----------------------- @@ -4870,11 +4897,7 @@ package body Exp_Ch4 is begin Binary_Op_Validity_Checks (N); - if Vax_Float (Typ1) then - Expand_Vax_Comparison (N); - return; - - elsif Is_Array_Type (Typ1) then + if Is_Array_Type (Typ1) then Expand_Array_Comparison (N); return; end if; @@ -4887,6 +4910,13 @@ package body Exp_Ch4 is end if; Rewrite_Comparison (N); + + -- If we still have comparison, and Vax_Float type, process it + + if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then + Expand_Vax_Comparison (N); + return; + end if; end Expand_N_Op_Ge; -------------------- @@ -4902,11 +4932,7 @@ package body Exp_Ch4 is begin Binary_Op_Validity_Checks (N); - if Vax_Float (Typ1) then - Expand_Vax_Comparison (N); - return; - - elsif Is_Array_Type (Typ1) then + if Is_Array_Type (Typ1) then Expand_Array_Comparison (N); return; end if; @@ -4919,6 +4945,13 @@ package body Exp_Ch4 is end if; Rewrite_Comparison (N); + + -- If we still have comparison, and Vax_Float type, process it + + if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then + Expand_Vax_Comparison (N); + return; + end if; end Expand_N_Op_Gt; -------------------- @@ -4934,11 +4967,7 @@ package body Exp_Ch4 is begin Binary_Op_Validity_Checks (N); - if Vax_Float (Typ1) then - Expand_Vax_Comparison (N); - return; - - elsif Is_Array_Type (Typ1) then + if Is_Array_Type (Typ1) then Expand_Array_Comparison (N); return; end if; @@ -4951,6 +4980,13 @@ package body Exp_Ch4 is end if; Rewrite_Comparison (N); + + -- If we still have comparison, and Vax_Float type, process it + + if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then + Expand_Vax_Comparison (N); + return; + end if; end Expand_N_Op_Le; -------------------- @@ -4966,11 +5002,7 @@ package body Exp_Ch4 is begin Binary_Op_Validity_Checks (N); - if Vax_Float (Typ1) then - Expand_Vax_Comparison (N); - return; - - elsif Is_Array_Type (Typ1) then + if Is_Array_Type (Typ1) then Expand_Array_Comparison (N); return; end if; @@ -4983,6 +5015,13 @@ package body Exp_Ch4 is end if; Rewrite_Comparison (N); + + -- If we still have comparison, and Vax_Float type, process it + + if Vax_Float (Typ1) and then Nkind (N) in N_Op_Compare then + Expand_Vax_Comparison (N); + return; + end if; end Expand_N_Op_Lt; ----------------------- @@ -5187,13 +5226,6 @@ package body Exp_Ch4 is end if; end if; - -- Deal with VAX float case - - if Vax_Float (Typ) then - Expand_Vax_Arith (N); - return; - end if; - -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that -- Is_Power_Of_2_For_Shift is set means that we know that our left -- operand is an integer, as required for this to work. @@ -5304,6 +5336,12 @@ package body Exp_Ch4 is elsif Is_Signed_Integer_Type (Etype (N)) then Apply_Arithmetic_Overflow_Check (N); + + -- Deal with VAX float case + + elsif Vax_Float (Typ) then + Expand_Vax_Arith (N); + return; end if; end Expand_N_Op_Multiply; @@ -5311,39 +5349,74 @@ package body Exp_Ch4 is -- Expand_N_Op_Ne -- -------------------- - -- Rewrite node as the negation of an equality operation, and reanalyze. - -- The equality to be used is defined in the same scope and has the same - -- signature. It must be set explicitly because in an instance it may not - -- have the same visibility as in the generic unit. - procedure Expand_N_Op_Ne (N : Node_Id) is - Loc : constant Source_Ptr := Sloc (N); - Neg : Node_Id; - Ne : constant Entity_Id := Entity (N); + Typ : constant Entity_Id := Etype (Left_Opnd (N)); begin - Binary_Op_Validity_Checks (N); + -- Case of elementary type with standard operator - Neg := - Make_Op_Not (Loc, - Right_Opnd => - Make_Op_Eq (Loc, - Left_Opnd => Left_Opnd (N), - Right_Opnd => Right_Opnd (N))); - Set_Paren_Count (Right_Opnd (Neg), 1); + if Is_Elementary_Type (Typ) + and then Sloc (Entity (N)) = Standard_Location + then + Binary_Op_Validity_Checks (N); - if Scope (Ne) /= Standard_Standard then - Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne)); - end if; + -- Boolean types (requiring handling of non-standard case) - -- For navigation purposes, the inequality is treated as an implicit - -- reference to the corresponding equality. Preserve the Comes_From_ - -- source flag so that the proper Xref entry is generated. + if Is_Boolean_Type (Typ) then + Adjust_Condition (Left_Opnd (N)); + Adjust_Condition (Right_Opnd (N)); + Set_Etype (N, Standard_Boolean); + Adjust_Result_Type (N, Typ); + end if; - Preserve_Comes_From_Source (Neg, N); - Preserve_Comes_From_Source (Right_Opnd (Neg), N); - Rewrite (N, Neg); - Analyze_And_Resolve (N, Standard_Boolean); + Rewrite_Comparison (N); + + -- If we still have comparison for Vax_Float, process it + + if Vax_Float (Typ) and then Nkind (N) in N_Op_Compare then + Expand_Vax_Comparison (N); + return; + end if; + + -- For all cases other than elementary types, we rewrite node as the + -- negation of an equality operation, and reanalyze. The equality to be + -- used is defined in the same scope and has the same signature. This + -- signature must be set explicitly since in an instance it may not have + -- the same visibility as in the generic unit. This avoids duplicating + -- or factoring the complex code for record/array equality tests etc. + + else + declare + Loc : constant Source_Ptr := Sloc (N); + Neg : Node_Id; + Ne : constant Entity_Id := Entity (N); + + begin + Binary_Op_Validity_Checks (N); + + Neg := + Make_Op_Not (Loc, + Right_Opnd => + Make_Op_Eq (Loc, + Left_Opnd => Left_Opnd (N), + Right_Opnd => Right_Opnd (N))); + Set_Paren_Count (Right_Opnd (Neg), 1); + + if Scope (Ne) /= Standard_Standard then + Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne)); + end if; + + -- For navigation purposes, the inequality is treated as an + -- implicit reference to the corresponding equality. Preserve the + -- Comes_From_ source flag so that the proper Xref entry is + -- generated. + + Preserve_Comes_From_Source (Neg, N); + Preserve_Comes_From_Source (Right_Opnd (Neg), N); + Rewrite (N, Neg); + Analyze_And_Resolve (N, Standard_Boolean); + end; + end if; end Expand_N_Op_Ne; --------------------- @@ -6480,8 +6553,8 @@ package body Exp_Ch4 is -- then we do not trust it to be in range (might be infinite) declare - S_Lo : constant Node_Id := Type_Low_Bound (Xtyp); - S_Hi : constant Node_Id := Type_High_Bound (Xtyp); + S_Lo : constant Node_Id := Type_Low_Bound (Xtyp); + S_Hi : constant Node_Id := Type_High_Bound (Xtyp); begin if (not Is_Floating_Point_Type (Xtyp) @@ -6533,9 +6606,9 @@ package body Exp_Ch4 is (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc)); Set_Etype (Conv, Btyp); - -- Enable overflow except in the case of integer to float - -- conversions, where it is never required, since we can - -- never have overflow in this case. + -- Enable overflow except for case of integer to float conversions, + -- where it is never required, since we can never have overflow in + -- this case. if not Is_Integer_Type (Etype (Operand)) then Enable_Overflow_Check (Conv); @@ -6588,13 +6661,6 @@ package body Exp_Ch4 is return; end if; - -- Deal with Vax floating-point cases - - if Vax_Float (Operand_Type) or else Vax_Float (Target_Type) then - Expand_Vax_Conversion (N); - return; - end if; - -- Nothing to do if this is the second argument of read. This -- is a "backwards" conversion that will be handled by the -- specialized code in attribute processing. @@ -6881,7 +6947,7 @@ package body Exp_Ch4 is -- this type with proper overflow checking, and so gigi is doing an -- approximation of what is required by doing floating-point compares -- with the end-point. But that can lose precision in some cases, and - -- give a wrong result. Converting the operand to Long_Long_Float is + -- give a wrong result. Converting the operand to Universal_Real is -- helpful, but still does not catch all cases with 64-bit integers -- on targets with only 64-bit floats ??? @@ -6889,11 +6955,11 @@ package body Exp_Ch4 is Rewrite (Operand, Make_Type_Conversion (Loc, Subtype_Mark => - New_Occurrence_Of (Standard_Long_Long_Float, Loc), + New_Occurrence_Of (Universal_Real, Loc), Expression => Relocate_Node (Operand))); - Set_Etype (Operand, Standard_Long_Long_Float); + Set_Etype (Operand, Universal_Real); Enable_Range_Check (Operand); Set_Do_Range_Check (Expression (Operand), False); end if; @@ -6986,11 +7052,6 @@ package body Exp_Ch4 is elsif Is_Floating_Point_Type (Target_Type) then Real_Range_Check; - - -- The remaining cases require no front end processing - - else - null; end if; -- At this stage, either the conversion node has been transformed @@ -7065,6 +7126,16 @@ package body Exp_Ch4 is end if; end; end if; + + -- Final step, if the result is a type conversion involving Vax_Float + -- types, then it is subject for further special processing. + + if Nkind (N) = N_Type_Conversion + and then (Vax_Float (Operand_Type) or else Vax_Float (Target_Type)) + then + Expand_Vax_Conversion (N); + return; + end if; end Expand_N_Type_Conversion; ----------------------------------- @@ -7803,7 +7874,6 @@ package body Exp_Ch4 is Statements => New_List (If_Stat))); return Func_Body; - end Make_Array_Comparison_Op; --------------------------- @@ -7960,6 +8030,18 @@ package body Exp_Ch4 is True_Result := Res in Compare_GE; False_Result := Res = LT; + if Res = LE + and then Constant_Condition_Warnings + and then Comes_From_Source (Original_Node (N)) + and then Nkind (Original_Node (N)) = N_Op_Ge + and then not In_Instance + and then not Warnings_Off (Etype (Left_Opnd (N))) + and then Is_Integer_Type (Etype (Left_Opnd (N))) + then + Error_Msg_N + ("can never be greater than, could replace by ""'=""?", N); + end if; + when N_Op_Gt => True_Result := Res = GT; False_Result := Res in Compare_LE; @@ -7972,9 +8054,21 @@ package body Exp_Ch4 is True_Result := Res in Compare_LE; False_Result := Res = GT; + if Res = GE + and then Constant_Condition_Warnings + and then Comes_From_Source (Original_Node (N)) + and then Nkind (Original_Node (N)) = N_Op_Le + and then not In_Instance + and then not Warnings_Off (Etype (Left_Opnd (N))) + and then Is_Integer_Type (Etype (Left_Opnd (N))) + then + Error_Msg_N + ("can never be less than, could replace by ""'=""?", N); + end if; + when N_Op_Ne => - True_Result := Res = NE; - False_Result := Res = LT or else Res = GT or else Res = EQ; + True_Result := Res = NE or else Res = GT or else Res = LT; + False_Result := Res = EQ; end case; if True_Result then |