From patchwork Fri Jun 18 13:10:56 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 56179 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 2D2DDB7D85 for ; Fri, 18 Jun 2010 23:10:53 +1000 (EST) Received: (qmail 23842 invoked by alias); 18 Jun 2010 13:10:48 -0000 Received: (qmail 23819 invoked by uid 22791); 18 Jun 2010 13:10:44 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (212.99.106.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 18 Jun 2010 13:10:39 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 28D52290007; Fri, 18 Jun 2010 15:10:46 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 00GSvlAwJkXG; Fri, 18 Jun 2010 15:10:46 +0200 (CEST) Received: from saumur.act-europe.fr (saumur.act-europe.fr [10.10.0.183]) by mel.act-europe.fr (Postfix) with ESMTP id 12A19290006; Fri, 18 Jun 2010 15:10:46 +0200 (CEST) Received: by saumur.act-europe.fr (Postfix, from userid 525) id 45735D9B31; Fri, 18 Jun 2010 15:10:56 +0200 (CEST) Date: Fri, 18 Jun 2010 15:10:56 +0200 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Robert Dewar Subject: [Ada] Conditional expression is static if all expression are static Message-ID: <20100618131056.GA30096@adacore.com> Mime-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.9i X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch corrects an oversight in the initial implementation of conditional expressions. The result is static if condition and both sub-expressios are static (and result is selected expression). The following test must compile silently with -gnatX. function StaticCexpr (X : Long_Long_Float) return Long_Long_Float is Link_Prefix : constant String := "__builtin_"; Link_Suffix : constant String := (if Long_Long_Float'Size > Long_Float'Size then "l" else ""); function C_Sin (X : Long_Long_Float) return Long_Long_Float; pragma Import (Intrinsic, C_Sin, Link_Prefix & "sin" & Link_Suffix); begin return C_Sin (X); end StaticCexpr; Tested on x86_64-pc-linux-gnu, committed on trunk 2010-06-18 Robert Dewar * sem_eval.adb (Eval_Conditional_Expression): Result is static if condition and both sub-expressions are static (and result is selected expression). Index: sem_eval.adb =================================================================== --- sem_eval.adb (revision 160979) +++ sem_eval.adb (working copy) @@ -1804,17 +1804,79 @@ package body Sem_Eval is -- Eval_Conditional_Expression -- --------------------------------- - -- We never attempt folding of conditional expressions (and the language) - -- does not require it, so the only required processing is to do the check - -- for non-static context for the then and else expressions. + -- We can fold to a static expression if the condition and both constituent + -- expressions are static. Othewise the only required processing is to do + -- the check for non-static context for the then and else expressions. procedure Eval_Conditional_Expression (N : Node_Id) is - Condition : constant Node_Id := First (Expressions (N)); - Then_Expr : constant Node_Id := Next (Condition); - Else_Expr : constant Node_Id := Next (Then_Expr); - begin - Check_Non_Static_Context (Then_Expr); - Check_Non_Static_Context (Else_Expr); + Condition : constant Node_Id := First (Expressions (N)); + Then_Expr : constant Node_Id := Next (Condition); + Else_Expr : constant Node_Id := Next (Then_Expr); + Result : Node_Id; + Non_Result : Node_Id; + + Rstat : constant Boolean := + Is_Static_Expression (Condition) + and then + Is_Static_Expression (Then_Expr) + and then + Is_Static_Expression (Else_Expr); + + begin + -- If any operand is Any_Type, just propagate to result and do not try + -- to fold, this prevents cascaded errors. + + if Etype (Condition) = Any_Type or else + Etype (Then_Expr) = Any_Type or else + Etype (Else_Expr) = Any_Type + then + Set_Etype (N, Any_Type); + Set_Is_Static_Expression (N, False); + return; + + -- Static case where we can fold. Note that we don't try to fold cases + -- where the condition is known at compile time, but the result is + -- non-static. This avoids possible cases of infinite recursion where + -- the expander puts in a redundant test and we remove it. Instead we + -- deal with these cases in the expander. + + elsif Rstat then + + -- Select result operand + + if Is_True (Expr_Value (Condition)) then + Result := Then_Expr; + Non_Result := Else_Expr; + else + Result := Else_Expr; + Non_Result := Then_Expr; + end if; + + -- Note that it does not matter if the non-result operand raises a + -- Constraint_Error, but if the result raises constraint error then + -- we replace the node with a raise constraint error. This will + -- properly propagate Raises_Constraint_Error since this flag is + -- set in Result. + + if Raises_Constraint_Error (Result) then + Rewrite_In_Raise_CE (N, Result); + Check_Non_Static_Context (Non_Result); + + -- Otherwise the result operand replaces the original node + + else + Rewrite (N, Relocate_Node (Result)); + end if; + + -- Case of condition not known at compile time + + else + Check_Non_Static_Context (Condition); + Check_Non_Static_Context (Then_Expr); + Check_Non_Static_Context (Else_Expr); + end if; + + Set_Is_Static_Expression (N, Rstat); end Eval_Conditional_Expression; ---------------------- @@ -2937,9 +2999,11 @@ package body Sem_Eval is Left : constant Node_Id := Left_Opnd (N); Right : constant Node_Id := Right_Opnd (N); Left_Int : Uint; - Rstat : constant Boolean := - Is_Static_Expression (Left) - and then Is_Static_Expression (Right); + + Rstat : constant Boolean := + Is_Static_Expression (Left) + and then + Is_Static_Expression (Right); begin -- Short circuit operations are never static in Ada 83 @@ -3001,7 +3065,7 @@ package body Sem_Eval is if (Kind = N_And_Then and then Is_False (Left_Int)) or else - (Kind = N_Or_Else and then Is_True (Left_Int)) + (Kind = N_Or_Else and then Is_True (Left_Int)) then Fold_Uint (N, Left_Int, Rstat); return;