From patchwork Wed Mar 30 16:21:41 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Matz X-Patchwork-Id: 88938 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 CCEBDB6F14 for ; Thu, 31 Mar 2011 03:22:19 +1100 (EST) Received: (qmail 31908 invoked by alias); 30 Mar 2011 16:21:53 -0000 Received: (qmail 31683 invoked by uid 22791); 30 Mar 2011 16:21:48 -0000 X-SWARE-Spam-Status: No, hits=-5.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor.suse.de (HELO mx1.suse.de) (195.135.220.2) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 30 Mar 2011 16:21:42 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id 988B35362F; Wed, 30 Mar 2011 18:21:41 +0200 (CEST) Date: Wed, 30 Mar 2011 18:21:41 +0200 (CEST) From: Michael Matz To: gcc-patches@gcc.gnu.org Cc: fortran@gcc.gnu.org Subject: Fix realloc_on_assign_2.f03, random segfaults/ICEs Message-ID: MIME-Version: 1.0 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 Hello, I noticed this some time ago already, but it went away. Now it reoccured and made me suspicious. "It" being random ICEs in fold_convert_loc, or segfaults, sometimes reproducable, sometimes not, on the realloc_on_assign_2.f03 testcase. The issue is that the frontend leaks the address of a local variable to outside its containing scope. Depending on the phase of moon, optimization factor and the like this stack space then is or is not overwritten at the use site. For me loop->to[0] was overwritten with a type node, ultimately ICEing in fold_convert when it tries to convert a type to a, well, type :) I haven't audited all users of gfc_copy_loopinfo_to_se, many seem to store the address of a local variable into the se structure. But those I looked at seem to be safe, in the sense of not using the se structure outside places where loop is also defined. Except for this one use I'm patching below, by moving the loop variable to the place that contains also the se structure. Okay for trunk? (regstrapping on x86_64-linux in progress) Ciao, Michael. Index: fortran/trans-expr.c =================================================================== --- fortran/trans-expr.c (revision 171734) +++ fortran/trans-expr.c (working copy) @@ -5510,20 +5512,20 @@ arrayfunc_assign_needs_temporary (gfc_ex reallocatable assignments from extrinsic function calls. */ static void -realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss) +realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss, + gfc_loopinfo *loop) { - gfc_loopinfo loop; /* Signal that the function call should not be made by gfc_conv_loop_setup. */ se->ss->is_alloc_lhs = 1; - gfc_init_loopinfo (&loop); - gfc_add_ss_to_loop (&loop, *ss); - gfc_add_ss_to_loop (&loop, se->ss); - gfc_conv_ss_startstride (&loop); - gfc_conv_loop_setup (&loop, where); - gfc_copy_loopinfo_to_se (se, &loop); - gfc_add_block_to_block (&se->pre, &loop.pre); - gfc_add_block_to_block (&se->pre, &loop.post); + gfc_init_loopinfo (loop); + gfc_add_ss_to_loop (loop, *ss); + gfc_add_ss_to_loop (loop, se->ss); + gfc_conv_ss_startstride (loop); + gfc_conv_loop_setup (loop, where); + gfc_copy_loopinfo_to_se (se, loop); + gfc_add_block_to_block (&se->pre, &loop->pre); + gfc_add_block_to_block (&se->pre, &loop->post); se->ss->is_alloc_lhs = 0; } @@ -5591,6 +5593,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * e gfc_se se; gfc_ss *ss; gfc_component *comp = NULL; + gfc_loopinfo loop; if (arrayfunc_assign_needs_temporary (expr1, expr2)) return NULL; @@ -5641,7 +5644,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * e { if (!expr2->value.function.isym) { - realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss); + realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop); ss->is_alloc_lhs = 1; } else