From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 67906 invoked by alias); 1 Jun 2015 10:45:09 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 67868 invoked by uid 89); 1 Jun 2015 10:45:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.0 required=5.0 tests=AWL,BAYES_50,KAM_ASCII_DIVIDERS,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 01 Jun 2015 10:45:04 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 38E6D2852C9F for ; Mon, 1 Jun 2015 12:45:01 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cCAI8Psi7hX1 for ; Mon, 1 Jun 2015 12:45:01 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 0D0D52852C93 for ; Mon, 1 Jun 2015 12:45:01 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Fix ICE on function [not] returning variable size Date: Mon, 01 Jun 2015 10:45:00 -0000 Message-ID: <2953955.A7ElB1Yu05@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.29-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart18862383.ymGmru731N" Content-Transfer-Encoding: 7Bit X-SW-Source: 2015-06/txt/msg00036.txt.bz2 --nextPart18862383.ymGmru731N Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Content-length: 1386 Hi, this fixes an ICE on a function returning a variable-sized record type but discovered to be no-return by the optimizer. In this case, the LHS of the GIMPLE call statement is removed so the RTL expander attempts to allocate a temporary and fails: eric@polaris:~/build/gcc/native> gcc/gnat1 -quiet varsize_return2.ads -O +===========================GNAT BUG DETECTED==============================+ | 6.0.0 20150531 (experimental) [trunk revision 223897] (x86_64-suse-linux) GCC error:| | in assign_stack_temp_for_type, at function.c:793 because it too cannot create temporaries of variable size. The attached patch simply preserves the LHS throughout the GIMPLE pipeline. It also simplifies the relevant test in gimplify_modify_expr_rhs, which was overly broad. Tested on x86_64-suse-linux, OK for the mainline? 2015-06-01 Eric Botcazou * gimplify.c (gimplify_modify_expr_rhs): Use simple test on the size. * cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Do not remove the LHS of a no-return call if its type has variable size. * tree-cfgcleanup.c (fixup_noreturn_call): Likewise. * tree-cfg.c (verify_gimple_call): Accept these no-return calls. 2015-06-01 Eric Botcazou * gnat.dg/specs/varsize_return2.ads: New test. * gnat.dg/specs/varsize_return2_pkg.ad[sb]: New helper. -- Eric Botcazou --nextPart18862383.ymGmru731N Content-Disposition: attachment; filename="p.diff" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="utf-8"; name="p.diff" Content-length: 3916 Index: cgraph.c =================================================================== --- cgraph.c (revision 223897) +++ cgraph.c (working copy) @@ -1449,8 +1449,10 @@ cgraph_edge::redirect_call_stmt_to_calle update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt); } - /* If the call becomes noreturn, remove the lhs. */ - if (lhs && (gimple_call_flags (new_stmt) & ECF_NORETURN)) + /* If the call becomes noreturn, remove the LHS if possible. */ + if (lhs + && (gimple_call_flags (new_stmt) & ECF_NORETURN) + && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST) { if (TREE_CODE (lhs) == SSA_NAME) { Index: gimplify.c =================================================================== --- gimplify.c (revision 223897) +++ gimplify.c (working copy) @@ -4341,7 +4341,8 @@ gimplify_modify_expr_rhs (tree *expr_p, /* It's OK to use the target directly if it's being initialized. */ use_target = true; - else if (variably_modified_type_p (TREE_TYPE (*to_p), NULL_TREE)) + else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) + != INTEGER_CST) /* Always use the target and thus RSO for variable-sized types. GIMPLE cannot deal with a variable-sized assignment embedded in a call statement. */ Index: tree-cfgcleanup.c =================================================================== --- tree-cfgcleanup.c (revision 223897) +++ tree-cfgcleanup.c (working copy) @@ -612,9 +612,11 @@ fixup_noreturn_call (gimple stmt) } } - /* If there is an LHS, remove it. */ + /* If there is an LHS, remove it, but only if its type has fixed size. + The LHS will need to be recreated during RTL expansion and creating + temporaries of variable-sized types is not supported. */ tree lhs = gimple_call_lhs (stmt); - if (lhs) + if (lhs && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST) { gimple_call_set_lhs (stmt, NULL_TREE); Index: tree-cfg.c =================================================================== --- tree-cfg.c (revision 223897) +++ tree-cfg.c (working copy) @@ -3391,17 +3391,19 @@ verify_gimple_call (gcall *stmt) return true; } - if (gimple_call_lhs (stmt) - && (!is_gimple_lvalue (gimple_call_lhs (stmt)) - || verify_types_in_gimple_reference (gimple_call_lhs (stmt), true))) + tree lhs = gimple_call_lhs (stmt); + if (lhs + && (!is_gimple_lvalue (lhs) + || verify_types_in_gimple_reference (lhs, true))) { error ("invalid LHS in gimple call"); return true; } - if (gimple_call_ctrl_altering_p (stmt) - && gimple_call_lhs (stmt) - && gimple_call_noreturn_p (stmt)) + if (lhs + && gimple_call_ctrl_altering_p (stmt) + && gimple_call_noreturn_p (stmt) + && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST) { error ("LHS in noreturn call"); return true; @@ -3409,19 +3411,18 @@ verify_gimple_call (gcall *stmt) fntype = gimple_call_fntype (stmt); if (fntype - && gimple_call_lhs (stmt) - && !useless_type_conversion_p (TREE_TYPE (gimple_call_lhs (stmt)), - TREE_TYPE (fntype)) + && lhs + && !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (fntype)) /* ??? At least C++ misses conversions at assignments from void * call results. ??? Java is completely off. Especially with functions returning java.lang.Object. For now simply allow arbitrary pointer type conversions. */ - && !(POINTER_TYPE_P (TREE_TYPE (gimple_call_lhs (stmt))) + && !(POINTER_TYPE_P (TREE_TYPE (lhs)) && POINTER_TYPE_P (TREE_TYPE (fntype)))) { error ("invalid conversion in gimple call"); - debug_generic_stmt (TREE_TYPE (gimple_call_lhs (stmt))); + debug_generic_stmt (TREE_TYPE (lhs)); debug_generic_stmt (TREE_TYPE (fntype)); return true; } --nextPart18862383.ymGmru731N Content-Disposition: attachment; filename="varsize_return2.ads" Content-Transfer-Encoding: 7Bit Content-Type: text/x-adasrc; charset="utf-8"; name="varsize_return2.ads" Content-length: 213 -- { dg-do compile } -- { dg-options "-O" } with Varsize_Return2_Pkg; use Varsize_Return2_Pkg; package Varsize_Return2 is package My_G is new G (0); Result : constant T := My_G.Get; end Varsize_Return2; --nextPart18862383.ymGmru731N Content-Disposition: attachment; filename="varsize_return2_pkg.adb" Content-Transfer-Encoding: quoted-printable Content-Type: text/x-adasrc; charset="utf-8"; name="varsize_return2_pkg.adb" Content-length: 331 package body Varsize_Return2_Pkg is=0D =0D function Len return Positive is=0D begin=0D return 4;=0D end;=0D =0D package body G is=0D =0D function Get return Small_T is=0D begin=0D raise Program_Error;=0D return Get;=0D end;=0D =0D end G;=0D =0D end Varsize_Return2_Pkg;=0D= --nextPart18862383.ymGmru731N Content-Disposition: attachment; filename="varsize_return2_pkg.ads" Content-Transfer-Encoding: 7Bit Content-Type: text/x-adasrc; charset="utf-8"; name="varsize_return2_pkg.ads" Content-length: 341 -- { dg-excess-errors "no code generated" } package Varsize_Return2_Pkg is type T (D: Positive) is record Data: String (1 .. D); end record; function Len return Positive; generic I : Integer; package G is subtype Small_T is T(Len); function Get return Small_T; end G; end Varsize_Return2_Pkg; --nextPart18862383.ymGmru731N--