From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6781 invoked by alias); 13 Jan 2012 08:38:31 -0000 Received: (qmail 6643 invoked by uid 22791); 13 Jan 2012 08:38:30 -0000 X-SWARE-Spam-Status: No, hits=-2.9 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 13 Jan 2012 08:38:17 +0000 From: "ebotcazou at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/8081] ICE with variably sized types returned from nested functions Date: Fri, 13 Jan 2012 08:55:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Keywords: accepts-invalid, ice-on-invalid-code X-Bugzilla-Severity: normal X-Bugzilla-Who: ebotcazou at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: CC Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2012-01/txt/msg01476.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8081 Eric Botcazou changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ebotcazou at gcc dot | |gnu.org --- Comment #25 from Eric Botcazou 2012-01-13 08:36:56 UTC --- > It's of course not that easy as we gimplify before un-nesting. The frontend > would be responsible to arrange things that way, similar to how we pass > a return slot in the C++ frontend (DECL_BY_REFERENCE on the DECL_RESULT > variable). Like for the attached patch. Passes > > extern void abort (void); > int > main (int argc, char **argv) > { > int size = 10; > typedef struct > { > char val[size]; > } > block; > block a, b; > block __attribute__((noinline)) > retframe_block () > { > return *(block *) &b; > } > b.val[0] = -1; > b.val[1] = -2; > a=retframe_block (); > if (a.val[0] != -1 > || a.val[1] != -2) > abort (); > return 0; > } > > I'm not sure if one can construct a testcase where using return-slot > optimization causes wrong-code generation. Alternatively checking > DECL_BY_REFERENCE on the callees DECL_RESULT instead of applying it to > all VLA types could work (though not for indirect calls). You should ask specialists. :-) In Ada, we do this routinely and the strategy used is that of the "forced RSO": we generate INIT_EXPR instead of MODIFY_EXPR and we create an explicit temporary if we detect potential overlap. Btw, I don't understand why you're mixing DECL_BY_REFERENCE and RSO here, just Index: gimplify.c =================================================================== --- gimplify.c (revision 183104) +++ gimplify.c (working copy) @@ -4417,6 +4417,9 @@ 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)) + /* Always use the target for variable-sized types. */ + use_target = true; else if (TREE_CODE (*to_p) != SSA_NAME && (!is_gimple_variable (*to_p) || needs_to_live_in_memory (*to_p))) works for me on the testcase.