From patchwork Thu Oct 4 17:06:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 189210 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 AF5AF2C03B1 for ; Fri, 5 Oct 2012 03:07:10 +1000 (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=1349975231; h=Comment: DomainKey-Signature:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=6sctYEG Tg/rno+DljLakMtsZ3T4=; b=pbO8jdvhEN22U1sb2VckN3fWUuM+u+A6Rs4EgCI LPeboDtyNwoqbRI19LjjLRX9QrMb40eOXn2JOCd9ZzUVH/jqNzCdyjjfxpPE4clG 3Px7IwbjZfFku2tbvJl6JrEcJrQrV/Pgxk4xMYa0QnyRRlUY4n9kyFjbRDHv0rXz 37VA= 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:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=NKyPuRGUdPQFjT37mYy/4H8f2m7WvkSyCpfbuq5tHYV6uTz0YC98/XRg5ssLo1 6nK7mRJ8wZ5iHSLhZwRebHFvjQFv37QR9+RYytEvCu3kvqkxds7POoTdLfsdIZ/H uTF5ngWHpUXz4DrBzCpJ1atuZ9TjwZjTh+CBOXRwi43H0=; Received: (qmail 10876 invoked by alias); 4 Oct 2012 17:06:42 -0000 Received: (qmail 10661 invoked by uid 22791); 4 Oct 2012 17:06:30 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from mx02.qsc.de (HELO mx02.qsc.de) (213.148.130.14) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 04 Oct 2012 17:06:24 +0000 Received: from [192.168.178.22] (port-92-204-33-183.dynamic.qsc.de [92.204.33.183]) by mx02.qsc.de (Postfix) with ESMTP id 0FA0A27A4E; Thu, 4 Oct 2012 19:06:21 +0200 (CEST) Message-ID: <506DC20C.20807@net-b.de> Date: Thu, 04 Oct 2012 19:06:20 +0200 From: Tobias Burnus User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120825 Thunderbird/15.0 MIME-Version: 1.0 To: gcc patches , gfortran Subject: [Patch, Fortran] Fix some memory leaks 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 This patch fixes some memory leaks and other issues found by http://scan5.coverity.com. Build and regtested on x86-64-linux. OK for the trunk? Tobias 2012-10-04 Tobias Burnus * expr.c (scalarize_intrinsic_call): Plug memory leak. * frontend-passes.c (gcc_assert): Extend assert. * interface.c (gfc_compare_derived_types): Fix comparison. (gfc_check_operator_interface): Move up to make this error message reachable. (get_sym_storage_size): Remove always-true checks. * io.c (format_lex): Add comment. (gfc_free_wait): Free memory. * match.c (gfc_match_select_type): Ditto. * matchexpr.c (match_level_3): Ditto. * primary.c (match_string_constant): Ditto. (match_actual_arg): Check return value. * resolve.c (gfc_resolve_substring_charlen, resolve_typebound_generic_call, resolve_typebound_function, resolve_typebound_subroutine): Free memory. * trans-types.c (gfc_get_derived_type): Remove always-true check. diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 4bba438..9ac0fc6 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -2059,6 +2059,8 @@ scalarize_intrinsic_call (gfc_expr *e) free_expr0 (e); *e = *expr; + /* Free "expr" but not the pointers it contains. */ + free (expr); gfc_free_expr (old); return SUCCESS; diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 437ed7e..0cba911 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -1177,7 +1177,7 @@ optimize_trim (gfc_expr *e) /* Set the end of the reference to the call to len_trim. */ ref->u.ss.end = fcn; - gcc_assert (*rr == NULL); + gcc_assert (rr != NULL && *rr == NULL); *rr = ref; return true; } diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 6bcd607..fb3da1f 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -449,7 +449,7 @@ gfc_compare_derived_types (gfc_symbol *derived1, gfc_symbol *derived2) /* Make sure that link lists do not put this function into an endless recursive loop! */ if (!(dt1->ts.type == BT_DERIVED && derived1 == dt1->ts.u.derived) - && !(dt1->ts.type == BT_DERIVED && derived1 == dt1->ts.u.derived) + && !(dt2->ts.type == BT_DERIVED && derived2 == dt2->ts.u.derived) && gfc_compare_types (&dt1->ts, &dt2->ts) == 0) return 0; @@ -641,8 +641,12 @@ gfc_check_operator_interface (gfc_symbol *sym, gfc_intrinsic_op op, && op != INTRINSIC_NOT) || (args == 2 && op == INTRINSIC_NOT)) { - gfc_error ("Operator interface at %L has the wrong number of arguments", - &sym->declared_at); + if (op == INTRINSIC_ASSIGN) + gfc_error ("Assignment operator interface at %L must have " + "two arguments", &sym->declared_at); + else + gfc_error ("Operator interface at %L has the wrong number of arguments", + &sym->declared_at); return false; } @@ -656,12 +660,6 @@ gfc_check_operator_interface (gfc_symbol *sym, gfc_intrinsic_op op, "a SUBROUTINE", &sym->declared_at); return false; } - if (args != 2) - { - gfc_error ("Assignment operator interface at %L must have " - "two arguments", &sym->declared_at); - return false; - } /* Allowed are (per F2003, 12.3.2.1.2 Defined assignments): - First argument an array with different rank than second, @@ -2149,7 +2147,7 @@ get_sym_storage_size (gfc_symbol *sym) return 0; for (i = 0; i < sym->as->rank; i++) { - if (!sym->as || sym->as->upper[i]->expr_type != EXPR_CONSTANT + if (sym->as->upper[i]->expr_type != EXPR_CONSTANT || sym->as->lower[i]->expr_type != EXPR_CONSTANT) return 0; @@ -2224,9 +2222,7 @@ get_expr_storage_size (gfc_expr *e) continue; } - if (ref->type == REF_ARRAY && ref->u.ar.type == AR_SECTION - && ref->u.ar.start && ref->u.ar.end && ref->u.ar.stride - && ref->u.ar.as->upper) + if (ref->type == REF_ARRAY && ref->u.ar.type == AR_SECTION) for (i = 0; i < ref->u.ar.dimen; i++) { long int start, end, stride; diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index 428799c..447d03f 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -243,6 +243,8 @@ format_lex (void) { case '-': negative_flag = 1; + /* Falls through. */ + case '+': c = next_char_not_space (&error); if (!ISDIGIT (c)) @@ -4117,6 +4119,7 @@ gfc_free_wait (gfc_wait *wait) gfc_free_expr (wait->iostat); gfc_free_expr (wait->iomsg); gfc_free_expr (wait->id); + free (wait); } diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index d46a495..06585af 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -5325,6 +5325,7 @@ gfc_match_select_type (void) char name[GFC_MAX_SYMBOL_LEN]; bool class_array; gfc_symbol *sym; + gfc_namespace *parent_ns; m = gfc_match_label (); if (m == MATCH_ERROR) @@ -5404,7 +5405,9 @@ gfc_match_select_type (void) return MATCH_YES; cleanup: - gfc_current_ns = gfc_current_ns->parent; + parent_ns = gfc_current_ns->parent; + gfc_free_namespace (gfc_current_ns); + gfc_current_ns = parent_ns; return m; } diff --git a/gcc/fortran/matchexp.c b/gcc/fortran/matchexp.c index 12d5b2d..c1196a8 100644 --- a/gcc/fortran/matchexp.c +++ b/gcc/fortran/matchexp.c @@ -543,7 +543,7 @@ match_level_2 (gfc_expr **result) static match match_level_3 (gfc_expr **result) { - gfc_expr *all, *e, *total; + gfc_expr *all, *e, *total = NULL; locus where; match m; @@ -560,12 +560,12 @@ match_level_3 (gfc_expr **result) m = match_level_2 (&e); if (m == MATCH_NO) + gfc_error (expression_syntax); + if (m != MATCH_YES) { - gfc_error (expression_syntax); gfc_free_expr (all); + return MATCH_ERROR; } - if (m != MATCH_YES) - return MATCH_ERROR; total = gfc_concat (all, e); if (total == NULL) diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c index f362f75..7b64a3c 100644 --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -1087,6 +1087,7 @@ got_delim: if (!gfc_check_character_range (c, kind)) { + gfc_free_expr (e); gfc_error ("Character '%s' in string at %C is not representable " "in character kind %d", gfc_print_wide_char (c), kind); return MATCH_ERROR; @@ -1507,8 +1508,9 @@ match_actual_arg (gfc_expr **result) if (sym->attr.in_common && !sym->attr.proc_pointer) { - gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name, - &sym->declared_at); + if (gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name, + &sym->declared_at) == FAILURE) + return MATCH_ERROR; break; } diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 3e23ca2..7c30cba 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -4964,7 +4964,11 @@ gfc_resolve_substring_charlen (gfc_expr *e) end = NULL; if (!start || !end) - return; + { + gfc_free_expr (start); + gfc_free_expr (end); + return; + } /* Length = (end - start +1). */ e->ts.u.cl->length = gfc_subtract (end, start); @@ -6004,7 +6008,10 @@ resolve_typebound_generic_call (gfc_expr* e, const char **name) gfc_expr* po; po = extract_compcall_passed_object (e); if (!po) - return FAILURE; + { + gfc_free_actual_arglist (args); + return FAILURE; + } gcc_assert (g->specific->pass_arg_num > 0); gcc_assert (!g->specific->error); @@ -6253,7 +6260,10 @@ resolve_typebound_function (gfc_expr* e) /* Treat the call as if it is a typebound procedure, in order to roll out the correct name for the specific function. */ if (resolve_compcall (e, &name) == FAILURE) - return FAILURE; + { + gfc_free_ref_list (new_ref); + return FAILURE; + } ts = e->ts; if (overridable) @@ -6374,7 +6384,10 @@ resolve_typebound_subroutine (gfc_code *code) } if (resolve_typebound_call (code, &name) == FAILURE) - return FAILURE; + { + gfc_free_ref_list (new_ref); + return FAILURE; + } ts = code->expr1->ts; if (overridable) diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 3286a5a..81b7fa5 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -2445,7 +2445,7 @@ gfc_get_derived_type (gfc_symbol * derived) || c->ts.u.derived->backend_decl == NULL) c->ts.u.derived->backend_decl = gfc_get_derived_type (c->ts.u.derived); - if (c->ts.u.derived && c->ts.u.derived->attr.is_iso_c) + if (c->ts.u.derived->attr.is_iso_c) { /* Need to copy the modified ts from the derived type. The typespec was modified because C_PTR/C_FUNPTR are translated