From patchwork Wed Nov 3 00:15:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 69938 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 6494AB70AF for ; Wed, 3 Nov 2010 11:16:42 +1100 (EST) Received: (qmail 16987 invoked by alias); 3 Nov 2010 00:16:39 -0000 Received: (qmail 16978 invoked by uid 22791); 3 Nov 2010 00:16:38 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,TW_TM X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 03 Nov 2010 00:16:31 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id DC4E6CB0230 for ; Wed, 3 Nov 2010 01:16:28 +0100 (CET) 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 T808c5+iY5zP for ; Wed, 3 Nov 2010 01:16:28 +0100 (CET) Received: from [192.168.1.2] (bon31-9-83-155-120-49.fbx.proxad.net [83.155.120.49]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id AB4FACB01EB for ; Wed, 3 Nov 2010 01:16:28 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [Ada] Fix wrong code for size computation Date: Wed, 3 Nov 2010 01:15:40 +0100 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Message-Id: <201011030115.40151.ebotcazou@adacore.com> 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 Another installment in the long-running series of glitches involving a size computation in Ada, with an interesting twist: it only happens at -O0, as it stems from a bad interaction between the constant folder and the parameter attribute cache we use at -O0 exclusively. Tested on i586-suse-linux, applied on the mainline. 2010-11-02 Eric Botcazou * gcc-interface/gigi.h (add_stmt_force): Declare. (add_stmt_with_node_force): Likewise. * gcc-interface/trans.c (Attribute_to_gnu): Don't set TREE_SIDE_EFFECTS on the SAVE_EXPR built for cached expressions of parameter attributes. (Subprogram_Body_to_gnu): Force evaluation of the SAVE_EXPR built for cached expressions of parameter attributes. (add_stmt_force): New function. (add_stmt_with_node_force): Likewise. 2010-11-02 Eric Botcazou * gnat.dg/sizetype4.adb: New test. Index: gcc-interface/gigi.h =================================================================== --- gcc-interface/gigi.h (revision 166172) +++ gcc-interface/gigi.h (working copy) @@ -57,12 +57,19 @@ extern void rest_of_type_decl_compilatio /* Start a new statement group chained to the previous group. */ extern void start_stmt_group (void); -/* Add GNU_STMT to the current BLOCK_STMT node. */ +/* Add GNU_STMT to the current statement group. If it is an expression with + no effects, it is ignored. */ extern void add_stmt (tree gnu_stmt); -/* Similar, but set the location of GNU_STMT to that of GNAT_NODE. */ +/* Similar, but the statement is always added, regardless of side-effects. */ +extern void add_stmt_force (tree gnu_stmt); + +/* Like add_stmt, but set the location of GNU_STMT to that of GNAT_NODE. */ extern void add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node); +/* Similar, but the statement is always added, regardless of side-effects. */ +extern void add_stmt_with_node_force (tree gnu_stmt, Node_Id gnat_node); + /* Return code corresponding to the current code group. It is normally a STATEMENT_LIST, but may also be a BIND_EXPR or TRY_FINALLY_EXPR if BLOCK or cleanups were set. */ Index: gcc-interface/trans.c =================================================================== --- gcc-interface/trans.c (revision 166172) +++ gcc-interface/trans.c (working copy) @@ -1739,12 +1739,13 @@ Attribute_to_gnu (Node_Id gnat_node, tre /* Cache the expression we have just computed. Since we want to do it at run time, we force the use of a SAVE_EXPR and let the gimplifier - create the temporary. */ + create the temporary in the outermost binding level. We will make + sure in Subprogram_Body_to_gnu that it is evaluated on all possible + paths by forcing its evaluation on entry of the function. */ if (pa) { gnu_result = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result); - TREE_SIDE_EFFECTS (gnu_result) = 1; if (attribute == Attr_First) pa->first = gnu_result; else if (attribute == Attr_Last) @@ -2634,8 +2635,9 @@ Subprogram_Body_to_gnu (Node_Id gnat_nod VEC_pop (tree, gnu_return_label_stack); - /* If we populated the parameter attributes cache, we need to make sure - that the cached expressions are evaluated on all possible paths. */ + /* If we populated the parameter attributes cache, we need to make sure that + the cached expressions are evaluated on all the possible paths leading to + their uses. So we force their evaluation on entry of the function. */ cache = DECL_STRUCT_FUNCTION (gnu_subprog_decl)->language->parm_attr_cache; if (cache) { @@ -2647,11 +2649,11 @@ Subprogram_Body_to_gnu (Node_Id gnat_nod FOR_EACH_VEC_ELT (parm_attr, cache, i, pa) { if (pa->first) - add_stmt_with_node (pa->first, gnat_node); + add_stmt_with_node_force (pa->first, gnat_node); if (pa->last) - add_stmt_with_node (pa->last, gnat_node); + add_stmt_with_node_force (pa->last, gnat_node); if (pa->length) - add_stmt_with_node (pa->length, gnat_node); + add_stmt_with_node_force (pa->length, gnat_node); } add_stmt (gnu_result); @@ -5969,7 +5971,8 @@ start_stmt_group (void) current_stmt_group = group; } -/* Add GNU_STMT to the current statement group. */ +/* Add GNU_STMT to the current statement group. If it is an expression with + no effects, it is ignored. */ void add_stmt (tree gnu_stmt) @@ -5977,7 +5980,15 @@ add_stmt (tree gnu_stmt) append_to_statement_list (gnu_stmt, ¤t_stmt_group->stmt_list); } -/* Similar, but set the location of GNU_STMT to that of GNAT_NODE. */ +/* Similar, but the statement is always added, regardless of side-effects. */ + +void +add_stmt_force (tree gnu_stmt) +{ + append_to_statement_list_force (gnu_stmt, ¤t_stmt_group->stmt_list); +} + +/* Like add_stmt, but set the location of GNU_STMT to that of GNAT_NODE. */ void add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node) @@ -5987,6 +5998,16 @@ add_stmt_with_node (tree gnu_stmt, Node_ add_stmt (gnu_stmt); } +/* Similar, but the statement is always added, regardless of side-effects. */ + +void +add_stmt_with_node_force (tree gnu_stmt, Node_Id gnat_node) +{ + if (Present (gnat_node)) + set_expr_location_from_node (gnu_stmt, gnat_node); + add_stmt_force (gnu_stmt); +} + /* Add a declaration statement for GNU_DECL to the current statement group. Get SLOC from Entity_Id. */