From patchwork Thu Apr 11 16:16:02 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 235824 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 376602C00CB for ; Fri, 12 Apr 2013 02:16:33 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=TgzGgTg5/tEEqorH lMQb4mt3wcqCB9z/lPsIyY+CmKfr/SfG+oe9lS8BJkwyGkqQfHR8TzY5WezDmWhZ TugCqYOPoVzBM56Ztw5zzCedmmN2bMMNckMMYczDZz79u5Jigg06oX3oMo8nKxq3 YwgQMSMO7KhjTYKraCYHK56nM74= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=32fRgB1jKadQnYBqWaqoUD zoXKc=; b=KC+0dMKr7FKKqdNQHMzS2V1Kf8HOTKOMRnCE9cpLdLIicWf752vwU9 +vijZZJxAS7Qw6LXcHEX01JPfICEu/ISmzJTsUexJNNAPMm8x4c9tGJptAzwnAdo +mpLDrhSU69TIvMRMsrAKaucZGq+KWumh6kVohDD+XIYBJurmXmeQ= Received: (qmail 1914 invoked by alias); 11 Apr 2013 16:16:26 -0000 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 Received: (qmail 1779 invoked by uid 89); 11 Apr 2013 16:16:24 -0000 X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.1 Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Thu, 11 Apr 2013 16:16:23 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 210262900B5 for ; Thu, 11 Apr 2013 18:16:21 +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 HrNzWksyB4Qk for ; Thu, 11 Apr 2013 18:16:21 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id D951A290012 for ; Thu, 11 Apr 2013 18:16:20 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [Ada] Fix undefined reference at link time for array size symbol Date: Thu, 11 Apr 2013 18:16:02 +0200 Message-ID: <1944203.yTIFH4uSEa@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.19-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 X-Virus-Found: No This fixes a link failure for an array object declared with an array of array type under very specific circumstances, as the compiler doesn't consistently consider that the size of the array type is constant, depending on the unit which is being compiled. I need to export the skip_simple_constant_arithmetic function I wrote a few years ago, so I've moving it next to its model skip_simple_arithmetic and tidying up the implementation of the latter (but no functional changes). Tested on x86_64-suse-linux, applied on mainline. 2013-04-11 Eric Botcazou * stor-layout.c (skip_simple_constant_arithmetic): Move to... * tree.c (skip_simple_constant_arithmetic): ...here and make public. (skip_simple_arithmetic): Tidy up. * tree.h (skip_simple_constant_arithmetic): Declare. 2013-04-11 Eric Botcazou * gcc-interface/decl.c (elaborate_expression_1): Skip only constant arithmetics when looking for a read-only variable in the expression. 2013-04-11 Eric Botcazou * gnat.dg/array23.adb: New test. * gnat.dg/array23_pkg[123].ads: New helpers. Index: stor-layout.c =================================================================== --- stor-layout.c (revision 197617) +++ stor-layout.c (working copy) @@ -98,32 +98,6 @@ variable_size (tree size) /* An array of functions used for self-referential size computation. */ static GTY(()) vec *size_functions; -/* Look inside EXPR into simple arithmetic operations involving constants. - Return the outermost non-arithmetic or non-constant node. */ - -static tree -skip_simple_constant_arithmetic (tree expr) -{ - while (true) - { - if (UNARY_CLASS_P (expr)) - expr = TREE_OPERAND (expr, 0); - else if (BINARY_CLASS_P (expr)) - { - if (TREE_CONSTANT (TREE_OPERAND (expr, 1))) - expr = TREE_OPERAND (expr, 0); - else if (TREE_CONSTANT (TREE_OPERAND (expr, 0))) - expr = TREE_OPERAND (expr, 1); - else - break; - } - else - break; - } - - return expr; -} - /* Similar to copy_tree_r but do not copy component references involving PLACEHOLDER_EXPRs. These nodes are spotted in find_placeholder_in_expr and substituted in substitute_in_expr. */ Index: tree.c =================================================================== --- tree.c (revision 197617) +++ tree.c (working copy) @@ -2830,14 +2830,12 @@ save_expr (tree expr) return t; } -/* Look inside EXPR and into any simple arithmetic operations. Return - the innermost non-arithmetic node. */ +/* Look inside EXPR into any simple arithmetic operations. Return the + outermost non-arithmetic or non-invariant node. */ tree skip_simple_arithmetic (tree expr) { - tree inner; - /* We don't care about whether this can be used as an lvalue in this context. */ while (TREE_CODE (expr) == NON_LVALUE_EXPR) @@ -2847,17 +2845,16 @@ skip_simple_arithmetic (tree expr) a constant, it will be more efficient to not make another SAVE_EXPR since it will allow better simplification and GCSE will be able to merge the computations if they actually occur. */ - inner = expr; - while (1) + while (true) { - if (UNARY_CLASS_P (inner)) - inner = TREE_OPERAND (inner, 0); - else if (BINARY_CLASS_P (inner)) + if (UNARY_CLASS_P (expr)) + expr = TREE_OPERAND (expr, 0); + else if (BINARY_CLASS_P (expr)) { - if (tree_invariant_p (TREE_OPERAND (inner, 1))) - inner = TREE_OPERAND (inner, 0); - else if (tree_invariant_p (TREE_OPERAND (inner, 0))) - inner = TREE_OPERAND (inner, 1); + if (tree_invariant_p (TREE_OPERAND (expr, 1))) + expr = TREE_OPERAND (expr, 0); + else if (tree_invariant_p (TREE_OPERAND (expr, 0))) + expr = TREE_OPERAND (expr, 1); else break; } @@ -2865,9 +2862,37 @@ skip_simple_arithmetic (tree expr) break; } - return inner; + return expr; } +/* Look inside EXPR into simple arithmetic operations involving constants. + Return the outermost non-arithmetic or non-constant node. */ + +tree +skip_simple_constant_arithmetic (tree expr) +{ + while (TREE_CODE (expr) == NON_LVALUE_EXPR) + expr = TREE_OPERAND (expr, 0); + + while (true) + { + if (UNARY_CLASS_P (expr)) + expr = TREE_OPERAND (expr, 0); + else if (BINARY_CLASS_P (expr)) + { + if (TREE_CONSTANT (TREE_OPERAND (expr, 1))) + expr = TREE_OPERAND (expr, 0); + else if (TREE_CONSTANT (TREE_OPERAND (expr, 0))) + expr = TREE_OPERAND (expr, 1); + else + break; + } + else + break; + } + + return expr; +} /* Return which tree structure is used by T. */ Index: tree.h =================================================================== --- tree.h (revision 197617) +++ tree.h (working copy) @@ -5339,11 +5339,16 @@ extern tree staticp (tree); extern tree save_expr (tree); -/* Look inside EXPR and into any simple arithmetic operations. Return - the innermost non-arithmetic node. */ +/* Look inside EXPR into any simple arithmetic operations. Return the + outermost non-arithmetic or non-invariant node. */ extern tree skip_simple_arithmetic (tree); +/* Look inside EXPR into simple arithmetic operations involving constants. + Return the outermost non-arithmetic or non-constant node. */ + +extern tree skip_simple_constant_arithmetic (tree); + /* Return which tree structure is used by T. */ enum tree_node_structure_enum tree_node_structure (const_tree); Index: ada/gcc-interface/decl.c =================================================================== --- ada/gcc-interface/decl.c (revision 197617) +++ ada/gcc-interface/decl.c (working copy) @@ -6186,12 +6186,13 @@ elaborate_expression_1 (tree gnu_expr, E expr_variable_p = false; else { - /* Skip any conversions and simple arithmetics to see if the expression - is based on a read-only variable. + /* Skip any conversions and simple constant arithmetics to see if the + expression is based on a read-only variable. ??? This really should remain read-only, but we have to think about the typing of the tree here. */ - tree inner - = skip_simple_arithmetic (remove_conversions (gnu_expr, true)); + tree inner = remove_conversions (gnu_expr, true); + + inner = skip_simple_constant_arithmetic (inner); if (handled_component_p (inner)) {