From patchwork Tue Jan 4 21:41:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janus Weil X-Patchwork-Id: 77539 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 1502BB70D4 for ; Wed, 5 Jan 2011 08:41:32 +1100 (EST) Received: (qmail 22559 invoked by alias); 4 Jan 2011 21:41:24 -0000 Received: (qmail 22525 invoked by uid 22791); 4 Jan 2011 21:41:23 -0000 X-SWARE-Spam-Status: No, hits=-0.4 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RFC_ABUSE_POST, TW_TM, TW_VP X-Spam-Check-By: sourceware.org Received: from mail-bw0-f47.google.com (HELO mail-bw0-f47.google.com) (209.85.214.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 04 Jan 2011 21:41:16 +0000 Received: by bwz10 with SMTP id 10so14823494bwz.20 for ; Tue, 04 Jan 2011 13:41:13 -0800 (PST) MIME-Version: 1.0 Received: by 10.204.119.75 with SMTP id y11mr17009535bkq.18.1294177273563; Tue, 04 Jan 2011 13:41:13 -0800 (PST) Received: by 10.204.7.13 with HTTP; Tue, 4 Jan 2011 13:41:13 -0800 (PST) Date: Tue, 4 Jan 2011 22:41:13 +0100 Message-ID: Subject: [Patch, Fortran, OOP] PR 467024: STORAGE_SIZE (for polymorphic types): Segfault at run time From: Janus Weil To: gfortran , gcc-patches 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 all, here's the fix for a wrong-code OOP problem: Calling the intrinsic STORAGE_SIZE on an unallocated polymorphic allocatable would produce a segfault. The reason for this is that the implementation of STORAGE_SIZE queries the _size field of the vtab which corresponds the the variable's dynamic type (being pointed to by the _vptr component of the class container), where the _vptr was not being initialized. The F08 standard states in section 4.3.1.3 that the dynamic type of an unallocated allocatable is given by its declared type. What the patch does is to add an initialization statement for the _vptr component (according to the declared type). Up to now we only initialized the _data component of polymorphic allocatables. The patch was regtested on x86_64-unknown-linux-gnu. Ok for trunk? Cheers, Janus 2011-01-04 Janus Weil PR fortran/47024 * trans-decl.c (gfc_trans_deferred_vars): Initialize the _vpr component of polymorphic allocatables according to their declared type. 2011-01-04 Janus Weil PR fortran/47024 * gfortran.dg/storage_size_3.f08: New. Index: gcc/fortran/trans-decl.c =================================================================== --- gcc/fortran/trans-decl.c (revision 168479) +++ gcc/fortran/trans-decl.c (working copy) @@ -3312,7 +3312,7 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gf { /* Nullify and automatic deallocation of allocatable scalars. */ - tree tmp; + tree tmp = NULL; gfc_expr *e; gfc_se se; stmtblock_t init; @@ -3337,8 +3337,23 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gf if (!sym->attr.result) tmp = gfc_deallocate_scalar_with_status (se.expr, NULL, true, NULL, sym->ts); - else - tmp = NULL; + + if (sym->ts.type == BT_CLASS) + { + /* Initialize _vptr to declared type. */ + gfc_symbol *vtab = gfc_find_derived_vtab (sym->ts.u.derived); + tree rhs; + e = gfc_lval_expr_from_sym (sym); + gfc_add_vptr_component (e); + gfc_init_se (&se, NULL); + se.want_pointer = 1; + gfc_conv_expr (&se, e); + gfc_free_expr (e); + rhs = gfc_build_addr_expr (TREE_TYPE (se.expr), + gfc_get_symbol_decl (vtab)); + gfc_add_modify (&init, se.expr, rhs); + } + gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp); } }