From patchwork Tue Nov 27 16:39:33 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 202260 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 1A0DE2C008F for ; Wed, 28 Nov 2012 03:45:57 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1354639558; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Subject:Date:Message-ID:User-Agent:MIME-Version: Content-Type:Content-Transfer-Encoding:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=6LOpKV3bVWB1Da0R2q9s35UUzh4=; b=nOTorwwH8KBNgXc 7Rc6Fe54j1bWsu1JBgoAIpKqSEXXCLWr0lhAG88FDWAN6ssIHikA9TkPMS2cyTdM nkcePjweNq6D3ljXQokaayNHTNG/5I1WGJ5m7oj5SZat0fBikyghkvZddekJ7GVF kOykwvp7YGF0+PrdOx3KVNAgCDYY= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:From:To:Subject:Date:Message-ID:User-Agent:MIME-Version:Content-Type:Content-Transfer-Encoding:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=pInklKr1C660+TcwVUDTvcw62iU2wTINPAQ6HzidRVGCqYacxZLAwhIflDtnCH AU7JRYS4r5CAzWWWkksIIbLxO2sIkbwNGRAVqx4WHjNutcdLj8IpQsJ/3zZbw5sI 0oQWGRHSof/NOoNCjwxRNfMnFhSsZjYwOyIpNPfAuFg04=; Received: (qmail 7535 invoked by alias); 27 Nov 2012 16:45:50 -0000 Received: (qmail 7523 invoked by uid 22791); 27 Nov 2012 16:45:49 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00 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; Tue, 27 Nov 2012 16:45:40 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 8F45CCB1CA0 for ; Tue, 27 Nov 2012 17:45:42 +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 tWC3bekP7DXh for ; Tue, 27 Nov 2012 17:45:42 +0100 (CET) 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 4BAE3CB1C96 for ; Tue, 27 Nov 2012 17:45:42 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Fix gnat.dg regressions and sizetype change fallouts Date: Tue, 27 Nov 2012 17:39:33 +0100 Message-ID: <2973671.gMgZJMRTIz@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.16-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 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 Hi, this fixes the couple of gnat.dg regressions on all platforms introduced by the sizetype changes, as well as finishes the conversion of the Ada compiler to the new scheme by invoking valid_constant_size_p and size_binop in the appropriate places. The 2 regressions were introduced by the kludge added to layout_type to deal with overflowed zeroes. As such, the kludge is wrong, since something like: type Arr is array(Long_Integer) of Boolean; in Ada already yields a really overflowed zero. So the patch adds a kludge to the kludge, with the appropriate ??? comment this time. Tested on i586-suse-linux and x86-64-suse-linux, OK for the mainline? 2012-11-27 Eric Botcazou * stor-layout.c (layout_type) : Do not clear TREE_OVERFLOW on overflowed zeroes, except in one specific case. ada/ * gcc-interface/decl.c (gnat_to_gnu_entity) : Use valid_constant_size_p to detect too large objects. : Likewise for too large return types. (allocatable_size_p): Call valid_constant_size_p in the fixed case. (annotate_value) : Adjust to sizetype changes. * gcc-interface/trans.c (gnat_to_gnu) : Use valid_constant_size_p to detect too large objects on the LHS. * gcc-interface/misc.c (default_pass_by_ref): Likewise for large types. And use TYPE_SIZE_UNIT throughout. (must_pass_by_ref): Likewise. * gcc-interface/utils.c (max_size) : Split from common case. : Likewise. Call size_binop instead of fold_build2. : Simplify. * gcc-interface/utils2.c (build_allocator): Use valid_constant_size_p to detect too large allocations. 2012-11-27 Eric Botcazou * gnat.dg/object_overflow.adb: Rename to... * gnat.dg/object_overflow1.adb: ...this. * gnat.dg/object_overflow2.adb: New test. * gnat.dg/object_overflow3.adb: Likewise. * gnat.dg/object_overflow4.adb: Likewise. Index: stor-layout.c =================================================================== --- stor-layout.c (revision 193837) +++ stor-layout.c (working copy) @@ -2233,12 +2233,12 @@ layout_type (tree type) size_binop (MINUS_EXPR, ub, lb))); } - /* If we arrived at a length of zero ignore any overflow - that occurred as part of the calculation. There exists - an association of the plus one where that overflow would - not happen. */ + /* ??? We have no way to distinguish a null-sized array from an + array spanning the whole sizetype range, so we arbitrarily + decide that [0, -1] is the only valid representation. */ if (integer_zerop (length) - && TREE_OVERFLOW (length)) + && TREE_OVERFLOW (length) + && integer_zerop (lb)) length = size_zero_node; TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size, Index: ada/gcc-interface/utils.c =================================================================== --- ada/gcc-interface/utils.c (revision 193837) +++ ada/gcc-interface/utils.c (working copy) @@ -3024,59 +3024,67 @@ max_size (tree exp, bool max_p) return max_p ? size_one_node : size_zero_node; case tcc_unary: + if (code == NON_LVALUE_EXPR) + return max_size (TREE_OPERAND (exp, 0), max_p); + + return fold_build1 (code, type, + max_size (TREE_OPERAND (exp, 0), + code == NEGATE_EXPR ? !max_p : max_p)); + case tcc_binary: + { + tree lhs = max_size (TREE_OPERAND (exp, 0), max_p); + tree rhs = max_size (TREE_OPERAND (exp, 1), + code == MINUS_EXPR ? !max_p : max_p); + + /* Special-case wanting the maximum value of a MIN_EXPR. + In that case, if one side overflows, return the other. */ + if (max_p && code == MIN_EXPR) + { + if (TREE_CODE (rhs) == INTEGER_CST && TREE_OVERFLOW (rhs)) + return lhs; + + if (TREE_CODE (lhs) == INTEGER_CST && TREE_OVERFLOW (lhs)) + return rhs; + } + + /* Likewise, handle a MINUS_EXPR or PLUS_EXPR with the LHS + overflowing and the RHS a variable. */ + if ((code == MINUS_EXPR || code == PLUS_EXPR) + && TREE_CODE (lhs) == INTEGER_CST + && TREE_OVERFLOW (lhs) + && !TREE_CONSTANT (rhs)) + return lhs; + + return size_binop (code, lhs, rhs); + } + case tcc_expression: switch (TREE_CODE_LENGTH (code)) { case 1: if (code == SAVE_EXPR) return exp; - else if (code == NON_LVALUE_EXPR) - return max_size (TREE_OPERAND (exp, 0), max_p); - else - return - fold_build1 (code, type, - max_size (TREE_OPERAND (exp, 0), - code == NEGATE_EXPR ? !max_p : max_p)); + + return fold_build1 (code, type, + max_size (TREE_OPERAND (exp, 0), max_p)); case 2: if (code == COMPOUND_EXPR) return max_size (TREE_OPERAND (exp, 1), max_p); - { - tree lhs = max_size (TREE_OPERAND (exp, 0), max_p); - tree rhs = max_size (TREE_OPERAND (exp, 1), - code == MINUS_EXPR ? !max_p : max_p); - - /* Special-case wanting the maximum value of a MIN_EXPR. - In that case, if one side overflows, return the other. - sizetype is signed, but we know sizes are non-negative. - Likewise, handle a MINUS_EXPR or PLUS_EXPR with the LHS - overflowing and the RHS a variable. */ - if (max_p - && code == MIN_EXPR - && TREE_CODE (rhs) == INTEGER_CST - && TREE_OVERFLOW (rhs)) - return lhs; - else if (max_p - && code == MIN_EXPR - && TREE_CODE (lhs) == INTEGER_CST - && TREE_OVERFLOW (lhs)) - return rhs; - else if ((code == MINUS_EXPR || code == PLUS_EXPR) - && TREE_CODE (lhs) == INTEGER_CST - && TREE_OVERFLOW (lhs) - && !TREE_CONSTANT (rhs)) - return lhs; - else - return fold_build2 (code, type, lhs, rhs); - } + return fold_build2 (code, type, + max_size (TREE_OPERAND (exp, 0), max_p), + max_size (TREE_OPERAND (exp, 1), max_p)); case 3: if (code == COND_EXPR) return fold_build2 (max_p ? MAX_EXPR : MIN_EXPR, type, max_size (TREE_OPERAND (exp, 1), max_p), max_size (TREE_OPERAND (exp, 2), max_p)); + + default: + break; } /* Other tree classes cannot happen. */ Index: ada/gcc-interface/decl.c =================================================================== --- ada/gcc-interface/decl.c (revision 193837) +++ ada/gcc-interface/decl.c (working copy) @@ -1337,7 +1337,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entit } if (TREE_CODE (TYPE_SIZE_UNIT (gnu_alloc_type)) == INTEGER_CST - && TREE_OVERFLOW (TYPE_SIZE_UNIT (gnu_alloc_type))) + && !valid_constant_size_p (TYPE_SIZE_UNIT (gnu_alloc_type))) post_error ("?`Storage_Error` will be raised at run time!", gnat_entity); @@ -4240,8 +4240,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entit a function that returns that type. This usage doesn't make sense anyway, so give an error here. */ if (TYPE_SIZE_UNIT (gnu_return_type) - && TREE_CONSTANT (TYPE_SIZE_UNIT (gnu_return_type)) - && TREE_OVERFLOW (TYPE_SIZE_UNIT (gnu_return_type))) + && TREE_CODE (TYPE_SIZE_UNIT (gnu_return_type)) == INTEGER_CST + && !valid_constant_size_p (TYPE_SIZE_UNIT (gnu_return_type))) { post_error ("cannot return type whose size overflows", gnat_entity); @@ -5989,10 +5989,9 @@ elaborate_entity (Entity_Id gnat_entity) static bool allocatable_size_p (tree gnu_size, bool static_p) { - /* We can allocate a fixed size if it hasn't overflowed and can be handled - (efficiently) on the host. */ + /* We can allocate a fixed size if it is a valid for the middle-end. */ if (TREE_CODE (gnu_size) == INTEGER_CST) - return !TREE_OVERFLOW (gnu_size) && host_integerp (gnu_size, 1); + return valid_constant_size_p (gnu_size); /* We can allocate a variable size if this isn't a static allocation. */ else @@ -7285,22 +7284,22 @@ annotate_value (tree gnu_size) case INTEGER_CST: if (TREE_OVERFLOW (gnu_size)) return No_Uint; - - /* This may come from a conversion from some smaller type, so ensure - this is in bitsizetype. */ - gnu_size = convert (bitsizetype, gnu_size); - - /* For a negative value, build NEGATE_EXPR of the opposite. Such values - appear in expressions containing aligning patterns. Note that, since - sizetype is sign-extended but nonetheless unsigned, we don't directly - use tree_int_cst_sgn. */ - if (TREE_INT_CST_HIGH (gnu_size) < 0) + else { - tree op_size = fold_build1 (NEGATE_EXPR, bitsizetype, gnu_size); - return annotate_value (build1 (NEGATE_EXPR, bitsizetype, op_size)); - } + /* For negative values, build NEGATE_EXPR of the opposite. Such + values appear in expressions containing aligning patterns. Note + that, since sizetype is unsigned, we jump through some hoops. */ + double_int signed_size + = tree_to_double_int (gnu_size).sext (TYPE_PRECISION (sizetype)); + if (signed_size.is_negative ()) + { + tree op_size = double_int_to_tree (sizetype, -signed_size); + if (op_size != gnu_size) + return annotate_value (build1 (NEGATE_EXPR, sizetype, op_size)); + } - return UI_From_gnu (gnu_size); + return UI_From_gnu (gnu_size); + } case COMPONENT_REF: /* The only case we handle here is a simple discriminant reference. */ Index: ada/gcc-interface/utils2.c =================================================================== --- ada/gcc-interface/utils2.c (revision 193837) +++ ada/gcc-interface/utils2.c (working copy) @@ -2286,7 +2286,7 @@ build_allocator (tree type, tree init, t init); /* If the size overflows, pass -1 so Storage_Error will be raised. */ - if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size)) + if (TREE_CODE (size) == INTEGER_CST && !valid_constant_size_p (size)) size = size_int (-1); storage = build_call_alloc_dealloc (NULL_TREE, size, storage_type, @@ -2345,7 +2345,7 @@ build_allocator (tree type, tree init, t } /* If the size overflows, pass -1 so Storage_Error will be raised. */ - if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size)) + if (TREE_CODE (size) == INTEGER_CST && !valid_constant_size_p (size)) size = size_int (-1); storage = convert (result_type, Index: ada/gcc-interface/trans.c =================================================================== --- ada/gcc-interface/trans.c (revision 193837) +++ ada/gcc-interface/trans.c (working copy) @@ -6115,7 +6115,7 @@ gnat_to_gnu (Node_Id gnat_node) /* If the type has a size that overflows, convert this into raise of Storage_Error: execution shouldn't have gotten here anyway. */ if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs))) == INTEGER_CST - && TREE_OVERFLOW (TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs)))) + && !valid_constant_size_p (TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs)))) gnu_result = build_call_raise (SE_Object_Too_Large, gnat_node, N_Raise_Storage_Error); else if (Nkind (Expression (gnat_node)) == N_Function_Call) Index: ada/gcc-interface/misc.c =================================================================== --- ada/gcc-interface/misc.c (revision 193837) +++ ada/gcc-interface/misc.c (working copy) @@ -604,8 +604,8 @@ gnat_get_subrange_bounds (const_tree gnu bool default_pass_by_ref (tree gnu_type) { - /* We pass aggregates by reference if they are sufficiently large. The - choice of constant here is somewhat arbitrary. We also pass by + /* We pass aggregates by reference if they are sufficiently large for + their alignment. The ratio is somewhat arbitrary. We also pass by reference if the target machine would either pass or return by reference. Strictly speaking, we need only check the return if this is an In Out parameter, but it's probably best to err on the side of @@ -618,9 +618,9 @@ default_pass_by_ref (tree gnu_type) return true; if (AGGREGATE_TYPE_P (gnu_type) - && (!host_integerp (TYPE_SIZE (gnu_type), 1) - || 0 < compare_tree_int (TYPE_SIZE (gnu_type), - 8 * TYPE_ALIGN (gnu_type)))) + && (!valid_constant_size_p (TYPE_SIZE_UNIT (gnu_type)) + || 0 < compare_tree_int (TYPE_SIZE_UNIT (gnu_type), + TYPE_ALIGN (gnu_type)))) return true; return false; @@ -639,8 +639,8 @@ must_pass_by_ref (tree gnu_type) not have such objects. */ return (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE || TYPE_IS_BY_REFERENCE_P (gnu_type) - || (TYPE_SIZE (gnu_type) - && TREE_CODE (TYPE_SIZE (gnu_type)) != INTEGER_CST)); + || (TYPE_SIZE_UNIT (gnu_type) + && TREE_CODE (TYPE_SIZE_UNIT (gnu_type)) != INTEGER_CST)); } /* This function is called by the front-end to enumerate all the supported