summaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch4.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-15 13:51:09 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-15 13:51:09 +0000
commit38f5559fd6bb31438a619828fe363fea2e34d17b (patch)
tree0efbfab4fb3d55403546ebeaa30ac64cbc05ef81 /gcc/ada/exp_ch4.adb
parent02747205c562d60e12b1c96b8cd6d3ee6eedea3a (diff)
downloadgcc-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.adb322
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