Comments
Patch
===================================================================
@@ -2826,9 +2826,9 @@ package body Exp_Ch4 is
Insert_Actions (Cnode, Actions, Suppress => All_Checks);
- -- Now we construct an array object with appropriate bounds
- -- The target is marked as internal, to prevent useless initialization
- -- when Initialize_Scalars is enabled.
+ -- Now we construct an array object with appropriate bounds. We mark
+ -- the target as internal to prevent useless initialization when
+ -- Initialize_Scalars is enabled.
Ent := Make_Temporary (Loc, 'S');
Set_Is_Internal (Ent);
@@ -4025,13 +4025,44 @@ package body Exp_Ch4 is
Elsex : constant Node_Id := Next (Thenx);
Typ : constant Entity_Id := Etype (N);
- Cnn : Entity_Id;
- Decl : Node_Id;
- New_If : Node_Id;
- New_N : Node_Id;
- P_Decl : Node_Id;
+ Cnn : Entity_Id;
+ Decl : Node_Id;
+ New_If : Node_Id;
+ New_N : Node_Id;
+ P_Decl : Node_Id;
+ Expr : Node_Id;
+ Actions : List_Id;
begin
+ -- Fold at compile time if condition known. We have already folded
+ -- static conditional expressions, but it is possible to fold any
+ -- case in which the condition is known at compile time, even though
+ -- the result is non-static.
+
+ -- Note that we don't do the fold of such cases in Sem_Elab because
+ -- it can cause infinite loops with the expander adding a conditional
+ -- expression, and Sem_Elab circuitry removing it repeatedly.
+
+ if Compile_Time_Known_Value (Cond) then
+ if Is_True (Expr_Value (Cond)) then
+ Expr := Thenx;
+ Actions := Then_Actions (N);
+ else
+ Expr := Elsex;
+ Actions := Else_Actions (N);
+ end if;
+
+ Remove (Expr);
+ Insert_Actions (N, Actions);
+ Rewrite (N, Relocate_Node (Expr));
+
+ -- Note that the result is never static (legitimate cases of static
+ -- conditional expressions were folded in Sem_Eval).
+
+ Set_Is_Static_Expression (N, False);
+ return;
+ end if;
+
-- If the type is limited or unconstrained, we expand as follows to
-- avoid any possibility of improper copies.
In Sem_Elab we fold static conditional expressions, but there are other cases that can be folded even if they are not static, namely any case in which the value of the condition is known at compile time. This patch adds that capability. The following program: function foldifexpr (x : integer) return integer is begin return (if x > x then 0 else x); end; Generates the following compiled with -gnatG -gnatX Source recreated from tree for foldifexpr (body) function foldifexpr (x : integer) return integer is begin return x; end foldifexpr; Tested on x86_64-pc-linux-gnu, committed on trunk 2010-06-21 Robert Dewar <dewar@adacore.com> * exp_ch4.adb (Expand_N_Conditional_Expression): Fold if condition known at compile time.