aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_eval.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_eval.adb')
-rw-r--r--gcc/ada/sem_eval.adb429
1 files changed, 274 insertions, 155 deletions
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 8d47589..a3a2864 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2021, 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- --
@@ -23,39 +23,43 @@
-- --
------------------------------------------------------------------------------
-with Aspects; use Aspects;
-with Atree; use Atree;
-with Checks; use Checks;
-with Debug; use Debug;
-with Einfo; use Einfo;
-with Elists; use Elists;
-with Errout; use Errout;
-with Eval_Fat; use Eval_Fat;
-with Exp_Util; use Exp_Util;
-with Freeze; use Freeze;
-with Lib; use Lib;
-with Namet; use Namet;
-with Nmake; use Nmake;
-with Nlists; use Nlists;
-with Opt; use Opt;
-with Par_SCO; use Par_SCO;
-with Rtsfind; use Rtsfind;
-with Sem; use Sem;
-with Sem_Aux; use Sem_Aux;
-with Sem_Cat; use Sem_Cat;
-with Sem_Ch3; use Sem_Ch3;
-with Sem_Ch6; use Sem_Ch6;
-with Sem_Ch8; use Sem_Ch8;
-with Sem_Elab; use Sem_Elab;
-with Sem_Res; use Sem_Res;
-with Sem_Util; use Sem_Util;
-with Sem_Type; use Sem_Type;
-with Sem_Warn; use Sem_Warn;
-with Sinfo; use Sinfo;
-with Snames; use Snames;
-with Stand; use Stand;
-with Stringt; use Stringt;
-with Tbuild; use Tbuild;
+with Aspects; use Aspects;
+with Atree; use Atree;
+with Checks; use Checks;
+with Debug; use Debug;
+with Einfo; use Einfo;
+with Einfo.Entities; use Einfo.Entities;
+with Einfo.Utils; use Einfo.Utils;
+with Elists; use Elists;
+with Errout; use Errout;
+with Eval_Fat; use Eval_Fat;
+with Exp_Util; use Exp_Util;
+with Freeze; use Freeze;
+with Lib; use Lib;
+with Namet; use Namet;
+with Nmake; use Nmake;
+with Nlists; use Nlists;
+with Opt; use Opt;
+with Par_SCO; use Par_SCO;
+with Rtsfind; use Rtsfind;
+with Sem; use Sem;
+with Sem_Aux; use Sem_Aux;
+with Sem_Cat; use Sem_Cat;
+with Sem_Ch3; use Sem_Ch3;
+with Sem_Ch6; use Sem_Ch6;
+with Sem_Ch8; use Sem_Ch8;
+with Sem_Elab; use Sem_Elab;
+with Sem_Res; use Sem_Res;
+with Sem_Util; use Sem_Util;
+with Sem_Type; use Sem_Type;
+with Sem_Warn; use Sem_Warn;
+with Sinfo; use Sinfo;
+with Sinfo.Nodes; use Sinfo.Nodes;
+with Sinfo.Utils; use Sinfo.Utils;
+with Snames; use Snames;
+with Stand; use Stand;
+with Stringt; use Stringt;
+with Tbuild; use Tbuild;
package body Sem_Eval is
@@ -136,12 +140,22 @@ package body Sem_Eval is
Checking_For_Potentially_Static_Expression : Boolean := False;
-- Global flag that is set True during Analyze_Static_Expression_Function
-- in order to verify that the result expression of a static expression
- -- function is a potentially static function (see RM202x 6.8(5.3)).
+ -- function is a potentially static function (see RM2022 6.8(5.3)).
-----------------------
-- Local Subprograms --
-----------------------
+ procedure Check_Non_Static_Context_For_Overflow
+ (N : Node_Id;
+ Stat : Boolean;
+ Result : Uint);
+ -- For a signed integer type, check non-static overflow in Result when
+ -- Stat is False. This applies also inside inlined code, where the static
+ -- property may be an effect of the inlining, which should not be allowed
+ -- to remove run-time checks (whether during compilation, or even more
+ -- crucially in the special inlining-for-proof in GNATprove mode).
+
function Choice_Matches
(Expr : Node_Id;
Choice : Node_Id) return Match_Result;
@@ -649,6 +663,34 @@ package body Sem_Eval is
end if;
end Check_Non_Static_Context;
+ -------------------------------------------
+ -- Check_Non_Static_Context_For_Overflow --
+ -------------------------------------------
+
+ procedure Check_Non_Static_Context_For_Overflow
+ (N : Node_Id;
+ Stat : Boolean;
+ Result : Uint)
+ is
+ begin
+ if (not Stat or else In_Inlined_Body)
+ and then Is_Signed_Integer_Type (Etype (N))
+ then
+ declare
+ BT : constant Entity_Id := Base_Type (Etype (N));
+ Lo : constant Uint := Expr_Value (Type_Low_Bound (BT));
+ Hi : constant Uint := Expr_Value (Type_High_Bound (BT));
+ begin
+ if Result < Lo or else Result > Hi then
+ Apply_Compile_Time_Constraint_Error
+ (N, "value not in range of }??",
+ CE_Overflow_Check_Failed,
+ Ent => BT);
+ end if;
+ end;
+ end if;
+ end Check_Non_Static_Context_For_Overflow;
+
---------------------------------
-- Check_String_Literal_Length --
---------------------------------
@@ -2086,7 +2128,6 @@ package body Sem_Eval is
Apply_Compile_Time_Constraint_Error
(N, "division by zero", CE_Divide_By_Zero,
Warn => not Stat or SPARK_Mode = On);
- Set_Raises_Constraint_Error (N);
return;
-- Otherwise we can do the division
@@ -2143,25 +2184,10 @@ package body Sem_Eval is
if Is_Modular_Integer_Type (Ltype) then
Result := Result mod Modulus (Ltype);
-
- -- For a signed integer type, check non-static overflow
-
- elsif (not Stat) and then Is_Signed_Integer_Type (Ltype) then
- declare
- BT : constant Entity_Id := Base_Type (Ltype);
- Lo : constant Uint := Expr_Value (Type_Low_Bound (BT));
- Hi : constant Uint := Expr_Value (Type_High_Bound (BT));
- begin
- if Result < Lo or else Result > Hi then
- Apply_Compile_Time_Constraint_Error
- (N, "value not in range of }??",
- CE_Overflow_Check_Failed,
- Ent => BT);
- return;
- end if;
- end;
end if;
+ Check_Non_Static_Context_For_Overflow (N, Stat, Result);
+
-- If we get here we can fold the result
Fold_Uint (N, Result, Stat);
@@ -2277,7 +2303,7 @@ package body Sem_Eval is
then
Eval_Intrinsic_Call (N, Entity (Name (N)));
- -- Ada 202x (AI12-0075): If checking for potentially static expressions
+ -- Ada 2022 (AI12-0075): If checking for potentially static expressions
-- is enabled and we have a call to a static function, substitute a
-- static value for the call, to allow folding the expression. This
-- supports checking the requirement of RM 6.8(5.3/5) in
@@ -2568,7 +2594,7 @@ package body Sem_Eval is
return;
end if;
- -- Ada 202x (AI12-0075): If checking for potentially static expressions
+ -- Ada 2022 (AI12-0075): If checking for potentially static expressions
-- is enabled and we have a reference to a formal parameter of mode in,
-- substitute a static value for the reference, to allow folding the
-- expression. This supports checking the requirement of RM 6.8(5.3/5)
@@ -2969,10 +2995,12 @@ package body Sem_Eval is
-- static if both operands are potentially static (RM 4.9(7), 4.9(20)).
procedure Eval_Logical_Op (N : Node_Id) is
- Left : constant Node_Id := Left_Opnd (N);
- Right : constant Node_Id := Right_Opnd (N);
- Stat : Boolean;
- Fold : Boolean;
+ Left : constant Node_Id := Left_Opnd (N);
+ Right : constant Node_Id := Right_Opnd (N);
+ Left_Int : Uint := No_Uint;
+ Right_Int : Uint := No_Uint;
+ Stat : Boolean;
+ Fold : Boolean;
begin
-- If not foldable we are done
@@ -2985,64 +3013,88 @@ package body Sem_Eval is
-- Compile time evaluation of logical operation
- declare
- Left_Int : constant Uint := Expr_Value (Left);
- Right_Int : constant Uint := Expr_Value (Right);
+ if Is_Modular_Integer_Type (Etype (N)) then
+ Left_Int := Expr_Value (Left);
+ Right_Int := Expr_Value (Right);
- begin
- if Is_Modular_Integer_Type (Etype (N)) then
- declare
- Left_Bits : Bits (0 .. UI_To_Int (Esize (Etype (N))) - 1);
- Right_Bits : Bits (0 .. UI_To_Int (Esize (Etype (N))) - 1);
+ declare
+ Left_Bits : Bits (0 .. UI_To_Int (Esize (Etype (N))) - 1);
+ Right_Bits : Bits (0 .. UI_To_Int (Esize (Etype (N))) - 1);
- begin
- To_Bits (Left_Int, Left_Bits);
- To_Bits (Right_Int, Right_Bits);
+ begin
+ To_Bits (Left_Int, Left_Bits);
+ To_Bits (Right_Int, Right_Bits);
- -- Note: should really be able to use array ops instead of
- -- these loops, but they break the build with a cryptic error
- -- during the bind of gnat1 likely due to a wrong computation
- -- of a date or checksum.
+ -- Note: should really be able to use array ops instead of
+ -- these loops, but they break the build with a cryptic error
+ -- during the bind of gnat1 likely due to a wrong computation
+ -- of a date or checksum.
- if Nkind (N) = N_Op_And then
- for J in Left_Bits'Range loop
- Left_Bits (J) := Left_Bits (J) and Right_Bits (J);
- end loop;
+ if Nkind (N) = N_Op_And then
+ for J in Left_Bits'Range loop
+ Left_Bits (J) := Left_Bits (J) and Right_Bits (J);
+ end loop;
- elsif Nkind (N) = N_Op_Or then
- for J in Left_Bits'Range loop
- Left_Bits (J) := Left_Bits (J) or Right_Bits (J);
- end loop;
+ elsif Nkind (N) = N_Op_Or then
+ for J in Left_Bits'Range loop
+ Left_Bits (J) := Left_Bits (J) or Right_Bits (J);
+ end loop;
- else
- pragma Assert (Nkind (N) = N_Op_Xor);
+ else
+ pragma Assert (Nkind (N) = N_Op_Xor);
- for J in Left_Bits'Range loop
- Left_Bits (J) := Left_Bits (J) xor Right_Bits (J);
- end loop;
- end if;
+ for J in Left_Bits'Range loop
+ Left_Bits (J) := Left_Bits (J) xor Right_Bits (J);
+ end loop;
+ end if;
- Fold_Uint (N, From_Bits (Left_Bits, Etype (N)), Stat);
- end;
+ Fold_Uint (N, From_Bits (Left_Bits, Etype (N)), Stat);
+ end;
- else
- pragma Assert (Is_Boolean_Type (Etype (N)));
+ else
+ pragma Assert (Is_Boolean_Type (Etype (N)));
- if Nkind (N) = N_Op_And then
+ if Compile_Time_Known_Value (Left)
+ and then Compile_Time_Known_Value (Right)
+ then
+ Right_Int := Expr_Value (Right);
+ Left_Int := Expr_Value (Left);
+ end if;
+
+ if Nkind (N) = N_Op_And then
+
+ -- If Left or Right are not compile time known values it means
+ -- that the result is always False as per
+ -- Test_Expression_Is_Foldable.
+ -- Note that in this case, both Right_Int and Left_Int are set
+ -- to No_Uint, so need to test for both.
+
+ if Right_Int = No_Uint then
+ Fold_Uint (N, Uint_0, Stat);
+ else
Fold_Uint (N,
Test (Is_True (Left_Int) and then Is_True (Right_Int)), Stat);
+ end if;
+ elsif Nkind (N) = N_Op_Or then
- elsif Nkind (N) = N_Op_Or then
- Fold_Uint (N,
- Test (Is_True (Left_Int) or else Is_True (Right_Int)), Stat);
+ -- If Left or Right are not compile time known values it means
+ -- that the result is always True. as per
+ -- Test_Expression_Is_Foldable.
+ -- Note that in this case, both Right_Int and Left_Int are set
+ -- to No_Uint, so need to test for both.
+ if Right_Int = No_Uint then
+ Fold_Uint (N, Uint_1, Stat);
else
- pragma Assert (Nkind (N) = N_Op_Xor);
Fold_Uint (N,
- Test (Is_True (Left_Int) xor Is_True (Right_Int)), Stat);
+ Test (Is_True (Left_Int) or else Is_True (Right_Int)), Stat);
end if;
+ else
+ pragma Assert (Nkind (N) = N_Op_Xor);
+ Fold_Uint (N,
+ Test (Is_True (Left_Int) xor Is_True (Right_Int)), Stat);
end if;
- end;
+ end if;
end Eval_Logical_Op;
------------------------
@@ -3202,6 +3254,8 @@ package body Sem_Eval is
Result := Result mod Modulus (Etype (N));
end if;
+ Check_Non_Static_Context_For_Overflow (N, Stat, Result);
+
Fold_Uint (N, Result, Stat);
end if;
end;
@@ -3408,7 +3462,7 @@ package body Sem_Eval is
-- Relational operations are static functions, so the result is static if
-- both operands are static (RM 4.9(7), 4.9(20)), except that up to Ada
-- 2012, for strings the result is never static, even if the operands are.
- -- The string case was relaxed in Ada 2020, see AI12-0201.
+ -- The string case was relaxed in Ada 2022, see AI12-0201.
-- However, for internally generated nodes, we allow string equality and
-- inequality to be static. This is because we rewrite A in "ABC" as an
@@ -3749,12 +3803,12 @@ package body Sem_Eval is
and then Right_Len /= Uint_Minus_1
and then Left_Len /= Right_Len
then
- -- AI12-0201: comparison of string is static in Ada 202x
+ -- AI12-0201: comparison of string is static in Ada 2022
Fold_Uint
(N,
Test (Nkind (N) = N_Op_Ne),
- Static => Ada_Version >= Ada_2020
+ Static => Ada_Version >= Ada_2022
and then Is_String_Type (Left_Typ));
Warn_On_Known_Condition (N);
return;
@@ -3774,16 +3828,16 @@ package body Sem_Eval is
(N, Left, Right, Is_Static_Expression, Fold);
-- Comparisons of scalars can give static results.
- -- In addition starting with Ada 202x (AI12-0201), comparison of strings
+ -- In addition starting with Ada 2022 (AI12-0201), comparison of strings
-- can also give static results, and as noted above, we also allow for
-- earlier Ada versions internally generated equality and inequality for
-- strings.
- -- ??? The Comes_From_Source test below isn't correct and will accept
- -- some cases that are illegal in Ada 2012. and before. Now that Ada
- -- 202x has relaxed the rules, this doesn't really matter.
+ -- The Comes_From_Source test below isn't correct and will accept
+ -- some cases that are illegal in Ada 2012 and before. Now that Ada
+ -- 2022 has relaxed the rules, this doesn't really matter.
if Is_String_Type (Left_Typ) then
- if Ada_Version < Ada_2020
+ if Ada_Version < Ada_2022
and then (Comes_From_Source (N)
or else Nkind (N) not in N_Op_Eq | N_Op_Ne)
then
@@ -3830,6 +3884,11 @@ package body Sem_Eval is
-----------------------------
procedure Eval_Selected_Component (N : Node_Id) is
+ Node : Node_Id;
+ Comp : Node_Id;
+ C : Node_Id;
+ Nam : Name_Id;
+
begin
-- If an attribute reference or a LHS, nothing to do.
-- Also do not fold if N is an [in] out subprogram parameter.
@@ -3839,7 +3898,34 @@ package body Sem_Eval is
and then Is_LHS (N) = No
and then not Is_Actual_Out_Or_In_Out_Parameter (N)
then
- Fold (N);
+ -- Simplify a selected_component on an aggregate by extracting
+ -- the field directly.
+
+ Node := Unqualify (Prefix (N));
+
+ if Nkind (Node) = N_Aggregate
+ and then Compile_Time_Known_Aggregate (Node)
+ then
+ Comp := First (Component_Associations (Node));
+ Nam := Chars (Selector_Name (N));
+
+ while Present (Comp) loop
+ C := First (Choices (Comp));
+
+ while Present (C) loop
+ if Chars (C) = Nam then
+ Rewrite (N, Relocate_Node (Expression (Comp)));
+ return;
+ end if;
+
+ Next (C);
+ end loop;
+
+ Next (Comp);
+ end loop;
+ else
+ Fold (N);
+ end if;
end if;
end Eval_Selected_Component;
@@ -4047,7 +4133,7 @@ package body Sem_Eval is
end if;
-- If original node was a type conversion, then result if non-static
- -- up to Ada 2012. AI12-0201 changes that with Ada 202x.
+ -- up to Ada 2012. AI12-0201 changes that with Ada 2022.
if Nkind (Original_Node (N)) = N_Type_Conversion
and then Ada_Version <= Ada_2012
@@ -4079,7 +4165,7 @@ package body Sem_Eval is
Len := String_Length (Strval (N));
- if UI_From_Int (Len) > String_Type_Len (Bas) then
+ if Len > String_Type_Len (Bas) then
-- Issue message. Note that this message is a warning if the
-- string literal is not marked as static (happens in some cases
@@ -4209,13 +4295,13 @@ package body Sem_Eval is
-- Conversion_OK is set, in which case it counts as integer.
-- Fold conversion, case of string type. The result is static starting
- -- with Ada 202x (AI12-0201).
+ -- with Ada 2022 (AI12-0201).
if Is_String_Type (Target_Type) then
Fold_Str
(N,
Strval (Get_String_Val (Operand)),
- Static => Ada_Version >= Ada_2020);
+ Static => Ada_Version >= Ada_2022);
return;
-- Fold conversion, case of integer target type
@@ -4306,10 +4392,7 @@ package body Sem_Eval is
return;
end if;
- if Etype (Right) = Universal_Integer
- or else
- Etype (Right) = Universal_Real
- then
+ if Is_Universal_Numeric_Type (Etype (Right)) then
Otype := Find_Universal_Operator_Type (N);
end if;
@@ -4343,6 +4426,8 @@ package body Sem_Eval is
Result := abs Rint;
end if;
+ Check_Non_Static_Context_For_Overflow (N, Stat, Result);
+
Fold_Uint (N, Result, Stat);
end;
@@ -4928,7 +5013,7 @@ package body Sem_Eval is
end if;
end Check_Elab_Call;
- Modulus : Uint;
+ Modulus, Val : Uint;
begin
if Compile_Time_Known_Value (Left)
@@ -4939,23 +5024,25 @@ package body Sem_Eval is
if Op = N_Op_Shift_Left then
Check_Elab_Call;
- declare
- Modulus : Uint;
- begin
- if Is_Modular_Integer_Type (Typ) then
- Modulus := Einfo.Modulus (Typ);
- else
- Modulus := Uint_2 ** RM_Size (Typ);
- end if;
+ if Is_Modular_Integer_Type (Typ) then
+ Modulus := Einfo.Entities.Modulus (Typ);
+ else
+ Modulus := Uint_2 ** RM_Size (Typ);
+ end if;
- -- Fold Shift_Left (X, Y) by computing (X * 2**Y) rem modulus
+ -- Fold Shift_Left (X, Y) by computing
+ -- (X * 2**Y) rem modulus [- Modulus]
- Fold_Uint
- (N,
- (Expr_Value (Left) * (Uint_2 ** Expr_Value (Right)))
- rem Modulus,
- Static => Static);
- end;
+ Val := (Expr_Value (Left) * (Uint_2 ** Expr_Value (Right)))
+ rem Modulus;
+
+ if Is_Modular_Integer_Type (Typ)
+ or else Val < Modulus / Uint_2
+ then
+ Fold_Uint (N, Val, Static => Static);
+ else
+ Fold_Uint (N, Val - Modulus, Static => Static);
+ end if;
elsif Op = N_Op_Shift_Right then
Check_Elab_Call;
@@ -4966,7 +5053,7 @@ package body Sem_Eval is
Fold_Uint (N, Expr_Value (Left), Static => Static);
else
if Is_Modular_Integer_Type (Typ) then
- Modulus := Einfo.Modulus (Typ);
+ Modulus := Einfo.Entities.Modulus (Typ);
else
Modulus := Uint_2 ** RM_Size (Typ);
end if;
@@ -4987,10 +5074,10 @@ package body Sem_Eval is
Check_Elab_Call;
declare
- Two_Y : constant Uint := Uint_2 ** Expr_Value (Right);
+ Two_Y : constant Uint := Uint_2 ** Expr_Value (Right);
begin
if Is_Modular_Integer_Type (Typ) then
- Modulus := Einfo.Modulus (Typ);
+ Modulus := Einfo.Entities.Modulus (Typ);
else
Modulus := Uint_2 ** RM_Size (Typ);
end if;
@@ -5494,23 +5581,16 @@ package body Sem_Eval is
return False;
end if;
- Anc_Subt := Ancestor_Subtype (Typ);
-
- if Anc_Subt = Empty then
- Anc_Subt := Base_T;
- end if;
-
- if Is_Generic_Type (Root_Type (Base_T))
- or else Is_Generic_Actual_Type (Base_T)
- then
- return False;
+ -- Then, check if the subtype is strictly static. This takes care of
+ -- checking for generics and predicates.
- elsif Has_Dynamic_Predicate_Aspect (Typ) then
+ if not Is_Static_Subtype (Typ) then
return False;
+ end if;
-- String types
- elsif Is_String_Type (Typ) then
+ if Is_String_Type (Typ) then
return
Ekind (Typ) = E_String_Literal_Subtype
or else
@@ -5524,6 +5604,12 @@ package body Sem_Eval is
return True;
else
+ Anc_Subt := Ancestor_Subtype (Typ);
+
+ if No (Anc_Subt) then
+ Anc_Subt := Base_T;
+ end if;
+
-- Scalar_Range (Typ) might be an N_Subtype_Indication, so use
-- Get_Type_{Low,High}_Bound.
@@ -6045,7 +6131,9 @@ package body Sem_Eval is
-- No message if we are dealing with System.Priority values in
-- CodePeer mode where the target runtime may have more priorities.
- elsif not CodePeer_Mode or else Etype (N) /= RTE (RE_Priority) then
+ elsif not CodePeer_Mode
+ or else not Is_RTE (Etype (N), RE_Priority)
+ then
-- Determine if the out-of-range violation constitutes a warning
-- or an error based on context, according to RM 4.9 (34/3).
@@ -6135,7 +6223,7 @@ package body Sem_Eval is
end;
else
- -- TBD: Implement Interval_Lists for real types
+ -- ??? Need to implement Interval_Lists for real types
return False;
end if;
@@ -6393,11 +6481,10 @@ package body Sem_Eval is
procedure Set_Checking_Potentially_Static_Expression (Value : Boolean) is
begin
- -- Verify that we're not currently checking for a potentially static
- -- expression unless we're disabling such checking.
+ -- Verify that we only start/stop checking for a potentially static
+ -- expression and do not start or stop it twice in a row.
- pragma Assert
- (not Checking_For_Potentially_Static_Expression or else not Value);
+ pragma Assert (Checking_For_Potentially_Static_Expression /= Value);
Checking_For_Potentially_Static_Expression := Value;
end Set_Checking_Potentially_Static_Expression;
@@ -6535,7 +6622,7 @@ package body Sem_Eval is
-- match if they are set (unless checking an actual for a formal derived
-- type). The use of 'Object_Size can cause this to be false even if the
-- types would otherwise match in the Ada 95 RM sense, but this deviation
- -- is adopted by AI12-059 which introduces Object_Size in Ada 2020.
+ -- is adopted by AI12-059 which introduces Object_Size in Ada 2022.
function Subtypes_Statically_Match
(T1 : Entity_Id;
@@ -7131,6 +7218,38 @@ package body Sem_Eval is
and then Compile_Time_Known_Value (Op2);
end if;
+ if not Fold
+ and then not Is_Modular_Integer_Type (Etype (N))
+ then
+ case Nkind (N) is
+ when N_Op_And =>
+
+ -- (False and XXX) = (XXX and False) = False
+
+ Fold :=
+ (Compile_Time_Known_Value (Op1)
+ and then Is_False (Expr_Value (Op1))
+ and then Side_Effect_Free (Op2))
+ or else (Compile_Time_Known_Value (Op2)
+ and then Is_False (Expr_Value (Op2))
+ and then Side_Effect_Free (Op1));
+
+ when N_Op_Or =>
+
+ -- (True and XXX) = (XXX and True) = True
+
+ Fold :=
+ (Compile_Time_Known_Value (Op1)
+ and then Is_True (Expr_Value (Op1))
+ and then Side_Effect_Free (Op2))
+ or else (Compile_Time_Known_Value (Op2)
+ and then Is_True (Expr_Value (Op2))
+ and then Side_Effect_Free (Op1));
+
+ when others => null;
+ end case;
+ end if;
+
return;
-- Else result is static and foldable. Both operands are static, and
@@ -7182,7 +7301,7 @@ package body Sem_Eval is
-- Universal types have no range limits, so always in range
- elsif Typ = Universal_Integer or else Typ = Universal_Real then
+ elsif Is_Universal_Numeric_Type (Typ) then
return In_Range;
-- Never known if not scalar type. Don't know if this can actually