From patchwork Tue Jun 28 21:50:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Koenig X-Patchwork-Id: 102489 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 CD7CBB6EDF for ; Wed, 29 Jun 2011 07:50:38 +1000 (EST) Received: (qmail 20811 invoked by alias); 28 Jun 2011 21:50:35 -0000 Received: (qmail 20790 invoked by uid 22791); 28 Jun 2011 21:50:32 -0000 X-SWARE-Spam-Status: No, hits=-1.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cc-smtpout3.netcologne.de (HELO cc-smtpout3.netcologne.de) (89.1.8.213) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 28 Jun 2011 21:50:16 +0000 Received: from cc-smtpin1.netcologne.de (cc-smtpin1.netcologne.de [89.1.8.201]) by cc-smtpout3.netcologne.de (Postfix) with ESMTP id 2761A125EA; Tue, 28 Jun 2011 23:50:14 +0200 (CEST) Received: from [192.168.0.197] (xdsl-78-35-180-190.netcologne.de [78.35.180.190]) by cc-smtpin1.netcologne.de (Postfix) with ESMTPSA id A810511E75; Tue, 28 Jun 2011 23:50:12 +0200 (CEST) Message-ID: <4E0A4C94.7030602@netcologne.de> Date: Tue, 28 Jun 2011 23:50:12 +0200 From: Thomas Koenig User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.17) Gecko/20110414 SUSE/3.1.10 Thunderbird/3.1.10 MIME-Version: 1.0 To: "fortran@gcc.gnu.org" , gcc-patches Subject: [patch, fortran] Always return malloc(1) for empty arrays in the library 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 world, looking at PR 49479 and other functions in the library made me realize there are lots of places where we don't malloc one byte for empty arrays. This patch is an attempt at fixing the ton of regressions likely caused by this (like in the PR) which haven't been found yet. No test cases, as they haven't been found yet :-) I also noticed two places where we had a memory leak (in eoshift1 and eoshift3), which I also fixed. Regression-tested. OK for trunk and, after a few days, for 4.6? Thomas 2011-06-28 Thomas Koenig * m4/in_pack.m4 (internal_pack_'rtype_ccode`): If size is less than one, allocate a single byte. * m4/transpose.m4 (transpose_'rtype_code`): Likewise. * m4/cshift1.m4 (cshift1): Likewise. * m4/matmull.m4 (matmul_'rtype_code`): Likewise. * m4/unpack.m4 (unpack0_'rtype_code`): Likewise. * m4/ifunction_logical.m4 (name`'rtype_qual`_'atype_code): Likewise. * m4/matmul.m4 (name`'rtype_qual`_'atype_code): Likewise. * intrinics/transpose_generic.c (transpose_internal): Likewise. * intrinsics/unpack_generic.c (unpack_internal): Likewise. * m4/eoshift1.m4 (eoshift1): Remove double allocation. * m4/eoshift3.m4 (eoshift3): Likewise. * generated/all_l16.c: Regenerated. * generated/all_l1.c: Regenerated. * generated/all_l2.c: Regenerated. * generated/all_l4.c: Regenerated. * generated/all_l8.c: Regenerated. * generated/any_l16.c: Regenerated. * generated/any_l1.c: Regenerated. * generated/any_l2.c: Regenerated. * generated/any_l4.c: Regenerated. * generated/any_l8.c: Regenerated. * generated/count_16_l.c: Regenerated. * generated/count_1_l.c: Regenerated. * generated/count_2_l.c: Regenerated. * generated/count_4_l.c: Regenerated. * generated/count_8_l.c: Regenerated. * generated/cshift1_16.c: Regenerated. * generated/cshift1_4.c: Regenerated. * generated/cshift1_8.c: Regenerated. * generated/eoshift1_16.c: Regenerated. * generated/eoshift1_4.c: Regenerated. * generated/eoshift1_8.c: Regenerated. * generated/eoshift3_16.c: Regenerated. * generated/eoshift3_4.c: Regenerated. * generated/eoshift3_8.c: Regenerated. * generated/in_pack_c10.c: Regenerated. * generated/in_pack_c16.c: Regenerated. * generated/in_pack_c4.c: Regenerated. * generated/in_pack_c8.c: Regenerated. * generated/in_pack_i16.c: Regenerated. * generated/in_pack_i1.c: Regenerated. * generated/in_pack_i2.c: Regenerated. * generated/in_pack_i4.c: Regenerated. * generated/in_pack_i8.c: Regenerated. * generated/in_pack_r10.c: Regenerated. * generated/in_pack_r16.c: Regenerated. * generated/in_pack_r4.c: Regenerated. * generated/in_pack_r8.c: Regenerated. * generated/matmul_c10.c: Regenerated. * generated/matmul_c16.c: Regenerated. * generated/matmul_c4.c: Regenerated. * generated/matmul_c8.c: Regenerated. * generated/matmul_i16.c: Regenerated. * generated/matmul_i1.c: Regenerated. * generated/matmul_i2.c: Regenerated. * generated/matmul_i4.c: Regenerated. * generated/matmul_i8.c: Regenerated. * generated/matmul_l16.c: Regenerated. * generated/matmul_l4.c: Regenerated. * generated/matmul_l8.c: Regenerated. * generated/matmul_r10.c: Regenerated. * generated/matmul_r16.c: Regenerated. * generated/matmul_r4.c: Regenerated. * generated/matmul_r8.c: Regenerated. * generated/maxloc1_16_i16.c: Regenerated. * generated/maxloc1_16_i1.c: Regenerated. * generated/maxloc1_16_i2.c: Regenerated. * generated/maxloc1_16_i4.c: Regenerated. * generated/maxloc1_16_i8.c: Regenerated. * generated/maxloc1_16_r10.c: Regenerated. * generated/maxloc1_16_r16.c: Regenerated. * generated/maxloc1_16_r4.c: Regenerated. * generated/maxloc1_16_r8.c: Regenerated. * generated/maxloc1_4_i16.c: Regenerated. * generated/maxloc1_4_i1.c: Regenerated. * generated/maxloc1_4_i2.c: Regenerated. * generated/maxloc1_4_i4.c: Regenerated. * generated/maxloc1_4_i8.c: Regenerated. * generated/maxloc1_4_r10.c: Regenerated. * generated/maxloc1_4_r16.c: Regenerated. * generated/maxloc1_4_r4.c: Regenerated. * generated/maxloc1_4_r8.c: Regenerated. * generated/maxloc1_8_i16.c: Regenerated. * generated/maxloc1_8_i1.c: Regenerated. * generated/maxloc1_8_i2.c: Regenerated. * generated/maxloc1_8_i4.c: Regenerated. * generated/maxloc1_8_i8.c: Regenerated. * generated/maxloc1_8_r10.c: Regenerated. * generated/maxloc1_8_r16.c: Regenerated. * generated/maxloc1_8_r4.c: Regenerated. * generated/maxloc1_8_r8.c: Regenerated. * generated/maxval_i16.c: Regenerated. * generated/maxval_i1.c: Regenerated. * generated/maxval_i2.c: Regenerated. * generated/maxval_i4.c: Regenerated. * generated/maxval_i8.c: Regenerated. * generated/maxval_r10.c: Regenerated. * generated/maxval_r16.c: Regenerated. * generated/maxval_r4.c: Regenerated. * generated/maxval_r8.c: Regenerated. * generated/minloc1_16_i16.c: Regenerated. * generated/minloc1_16_i1.c: Regenerated. * generated/minloc1_16_i2.c: Regenerated. * generated/minloc1_16_i4.c: Regenerated. * generated/minloc1_16_i8.c: Regenerated. * generated/minloc1_16_r10.c: Regenerated. * generated/minloc1_16_r16.c: Regenerated. * generated/minloc1_16_r4.c: Regenerated. * generated/minloc1_16_r8.c: Regenerated. * generated/minloc1_4_i16.c: Regenerated. * generated/minloc1_4_i1.c: Regenerated. * generated/minloc1_4_i2.c: Regenerated. * generated/minloc1_4_i4.c: Regenerated. * generated/minloc1_4_i8.c: Regenerated. * generated/minloc1_4_r10.c: Regenerated. * generated/minloc1_4_r16.c: Regenerated. * generated/minloc1_4_r4.c: Regenerated. * generated/minloc1_4_r8.c: Regenerated. * generated/minloc1_8_i16.c: Regenerated. * generated/minloc1_8_i1.c: Regenerated. * generated/minloc1_8_i2.c: Regenerated. * generated/minloc1_8_i4.c: Regenerated. * generated/minloc1_8_i8.c: Regenerated. * generated/minloc1_8_r10.c: Regenerated. * generated/minloc1_8_r16.c: Regenerated. * generated/minloc1_8_r4.c: Regenerated. * generated/minloc1_8_r8.c: Regenerated. * generated/minval_i16.c: Regenerated. * generated/minval_i1.c: Regenerated. * generated/minval_i2.c: Regenerated. * generated/minval_i4.c: Regenerated. * generated/minval_i8.c: Regenerated. * generated/minval_r10.c: Regenerated. * generated/minval_r16.c: Regenerated. * generated/minval_r4.c: Regenerated. * generated/minval_r8.c: Regenerated. * generated/product_c10.c: Regenerated. * generated/product_c16.c: Regenerated. * generated/product_c4.c: Regenerated. * generated/product_c8.c: Regenerated. * generated/product_i16.c: Regenerated. * generated/product_i1.c: Regenerated. * generated/product_i2.c: Regenerated. * generated/product_i4.c: Regenerated. * generated/product_i8.c: Regenerated. * generated/product_r10.c: Regenerated. * generated/product_r16.c: Regenerated. * generated/product_r4.c: Regenerated. * generated/product_r8.c: Regenerated. * generated/sum_c10.c: Regenerated. * generated/sum_c16.c: Regenerated. * generated/sum_c4.c: Regenerated. * generated/sum_c8.c: Regenerated. * generated/sum_i16.c: Regenerated. * generated/sum_i1.c: Regenerated. * generated/sum_i2.c: Regenerated. * generated/sum_i4.c: Regenerated. * generated/sum_i8.c: Regenerated. * generated/sum_r10.c: Regenerated. * generated/sum_r16.c: Regenerated. * generated/sum_r4.c: Regenerated. * generated/sum_r8.c: Regenerated. * generated/transpose_c10.c: Regenerated. * generated/transpose_c16.c: Regenerated. * generated/transpose_c4.c: Regenerated. * generated/transpose_c8.c: Regenerated. * generated/transpose_i16.c: Regenerated. * generated/transpose_i4.c: Regenerated. * generated/transpose_i8.c: Regenerated. * generated/transpose_r10.c: Regenerated. * generated/transpose_r16.c: Regenerated. * generated/transpose_r4.c: Regenerated. * generated/transpose_r8.c: Regenerated. * generated/unpack_c10.c: Regenerated. * generated/unpack_c16.c: Regenerated. * generated/unpack_c4.c: Regenerated. * generated/unpack_c8.c: Regenerated. * generated/unpack_i16.c: Regenerated. * generated/unpack_i1.c: Regenerated. * generated/unpack_i2.c: Regenerated. * generated/unpack_i4.c: Regenerated. * generated/unpack_i8.c: Regenerated. * generated/unpack_r10.c: Regenerated. * generated/unpack_r16.c: Regenerated. * generated/unpack_r4.c: Regenerated. * generated/unpack_r8.c: Regenerated. Index: m4/in_pack.m4 =================================================================== --- m4/in_pack.m4 (Revision 175598) +++ m4/in_pack.m4 (Arbeitskopie) @@ -45,6 +45,7 @@ internal_pack_'rtype_ccode` ('rtype` * source) index_type stride0; index_type dim; index_type ssize; + index_type alloc_size; const 'rtype_name` *src; 'rtype_name` * restrict dest; 'rtype_name` *destptr; @@ -79,7 +80,12 @@ internal_pack_'rtype_ccode` ('rtype` * source) return source->data; /* Allocate storage for the destination. */ - destptr = ('rtype_name` *)internal_malloc_size (ssize * sizeof ('rtype_name`)); + if (unlikely (ssize < 1)) + alloc_size = 1; + else + alloc_size = ssize * sizeof ('rtype_name`); + + destptr = ('rtype_name` *)internal_malloc_size (alloc_size); dest = destptr; src = source->data; stride0 = stride[0]; Index: m4/transpose.m4 =================================================================== --- m4/transpose.m4 (Revision 175598) +++ m4/transpose.m4 (Arbeitskopie) @@ -52,6 +52,8 @@ transpose_'rtype_code` ('rtype` * const restrict r if (ret->data == NULL) { + index_type alloc_size, array_size; + assert (GFC_DESCRIPTOR_RANK (ret) == 2); assert (ret->dtype == source->dtype); @@ -61,7 +63,13 @@ transpose_'rtype_code` ('rtype` * const restrict r GFC_DIMENSION_SET(ret->dim[1], 0, GFC_DESCRIPTOR_EXTENT(source,0) - 1, GFC_DESCRIPTOR_EXTENT(source, 1)); - ret->data = internal_malloc_size (sizeof ('rtype_name`) * size0 ((array_t *) ret)); + array_size = size0 ((array_t *) ret); + if (unlikely (array_size < 1)) + alloc_size = 1; + else + alloc_size = sizeof ('rtype_name`) * array_size; + + ret->data = internal_malloc_size (alloc_size); ret->offset = 0; } else if (unlikely (compile_options.bounds_check)) { Index: m4/eoshift1.m4 =================================================================== --- m4/eoshift1.m4 (Revision 175598) +++ m4/eoshift1.m4 (Arbeitskopie) @@ -89,7 +89,6 @@ eoshift1 (gfc_array_char * const restrict ret, { int i; - ret->data = internal_malloc_size (size * arraysize); ret->offset = 0; ret->dtype = array->dtype; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) @@ -107,7 +106,7 @@ eoshift1 (gfc_array_char * const restrict ret, GFC_DIMENSION_SET(ret->dim[i], 0, ub, str); } - if (arraysize > 0) + if (likely (arraysize > 0)) ret->data = internal_malloc_size (size * arraysize); else ret->data = internal_malloc_size (1); Index: m4/eoshift3.m4 =================================================================== --- m4/eoshift3.m4 (Revision 175598) +++ m4/eoshift3.m4 (Arbeitskopie) @@ -90,7 +90,6 @@ eoshift3 (gfc_array_char * const restrict ret, { int i; - ret->data = internal_malloc_size (size * arraysize); ret->offset = 0; ret->dtype = array->dtype; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) Index: m4/cshift1.m4 =================================================================== --- m4/cshift1.m4 (Revision 175598) +++ m4/cshift1.m4 (Arbeitskopie) @@ -81,7 +81,6 @@ cshift1 (gfc_array_char * const restrict ret, { int i; - ret->data = internal_malloc_size (size * arraysize); ret->offset = 0; ret->dtype = array->dtype; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) @@ -98,6 +97,11 @@ cshift1 (gfc_array_char * const restrict ret, GFC_DIMENSION_SET(ret->dim[i], 0, ub, str); } + if (likely (arraysize > 0)) + ret->data = internal_malloc_size (size * arraysize); + else + ret->data = internal_malloc_size (1); + } else if (unlikely (compile_options.bounds_check)) { Index: m4/matmull.m4 =================================================================== --- m4/matmull.m4 (Revision 175598) +++ m4/matmull.m4 (Arbeitskopie) @@ -68,6 +68,8 @@ matmul_'rtype_code` ('rtype` * const restrict reta if (retarray->data == NULL) { + index_type array_size, alloc_size; + if (GFC_DESCRIPTOR_RANK (a) == 1) { GFC_DIMENSION_SET(retarray->dim[0], 0, @@ -87,9 +89,15 @@ matmul_'rtype_code` ('rtype` * const restrict reta GFC_DESCRIPTOR_EXTENT(b,1) - 1, GFC_DESCRIPTOR_EXTENT(retarray,0)); } - - retarray->data - = internal_malloc_size (sizeof ('rtype_name`) * size0 ((array_t *) retarray)); + + array_size = size0 ((array_t *) retarray); + + if (unlikely (array_size < 1)) + alloc_size = 1; + else + alloc_size = sizeof ('rtype_name`) * alloc_size; + + retarray->data = internal_malloc_size ( alloc_size ); retarray->offset = 0; } else if (unlikely (compile_options.bounds_check)) Index: m4/unpack.m4 =================================================================== --- m4/unpack.m4 (Revision 175598) +++ m4/unpack.m4 (Arbeitskopie) @@ -86,6 +86,9 @@ unpack0_'rtype_code` ('rtype` *ret, const 'rtype` { /* The front end has signalled that we need to populate the return array descriptor. */ + + index_type alloc_size; + dim = GFC_DESCRIPTOR_RANK (mask); rs = 1; for (n = 0; n < dim; n++) @@ -100,7 +103,13 @@ unpack0_'rtype_code` ('rtype` *ret, const 'rtype` rs *= extent[n]; } ret->offset = 0; - ret->data = internal_malloc_size (rs * sizeof ('rtype_name`)); + + if (unlikely (rs < 1)) + alloc_size = 1; + else + alloc_size = rs * sizeof ('rtype_name`); + + ret->data = internal_malloc_size (alloc_size); } else { Index: m4/ifunction_logical.m4 =================================================================== --- m4/ifunction_logical.m4 (Revision 175598) +++ m4/ifunction_logical.m4 (Arbeitskopie) @@ -94,6 +94,7 @@ name`'rtype_qual`_'atype_code (rtype * const restr if (alloc_size == 0) { + retarray->data = internal_malloc_size (1); /* Make sure we have a zero-sized array. */ GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); return; Index: m4/ifunction.m4 =================================================================== --- m4/ifunction.m4 (Revision 175598) +++ m4/ifunction.m4 (Arbeitskopie) @@ -90,6 +90,7 @@ name`'rtype_qual`_'atype_code (rtype * const restr if (alloc_size == 0) { + retarray->data = internal_malloc_size (1); /* Make sure we have a zero-sized array. */ GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); return; @@ -269,6 +270,7 @@ void if (alloc_size == 0) { + retarray->data = internal_malloc_size (1); /* Make sure we have a zero-sized array. */ GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1); return; Index: m4/matmul.m4 =================================================================== --- m4/matmul.m4 (Revision 175598) +++ m4/matmul.m4 (Arbeitskopie) @@ -104,6 +104,8 @@ matmul_'rtype_code` ('rtype` * const restrict reta if (retarray->data == NULL) { + index_type array_size, alloc_size; + if (GFC_DESCRIPTOR_RANK (a) == 1) { GFC_DIMENSION_SET(retarray->dim[0], 0, @@ -124,8 +126,14 @@ matmul_'rtype_code` ('rtype` * const restrict reta GFC_DESCRIPTOR_EXTENT(retarray,0)); } + array_size = size0 ((array_t *) retarray); + + if (unlikely (array_size < 1)) + alloc_size = 1; + else + alloc_size = sizeof ('rtype_name`) * array_size; retarray->data - = internal_malloc_size (sizeof ('rtype_name`) * size0 ((array_t *) retarray)); + = internal_malloc_size (alloc_size); retarray->offset = 0; } else if (unlikely (compile_options.bounds_check)) Index: intrinsics/transpose_generic.c =================================================================== --- intrinsics/transpose_generic.c (Revision 175598) +++ intrinsics/transpose_generic.c (Arbeitskopie) @@ -52,6 +52,8 @@ transpose_internal (gfc_array_char *ret, gfc_array if (ret->data == NULL) { + index_type alloc_size, array_size; + assert (ret->dtype == source->dtype); GFC_DIMENSION_SET(ret->dim[0], 0, GFC_DESCRIPTOR_EXTENT(source,1) - 1, @@ -60,7 +62,14 @@ transpose_internal (gfc_array_char *ret, gfc_array GFC_DIMENSION_SET(ret->dim[1], 0, GFC_DESCRIPTOR_EXTENT(source,0) - 1, GFC_DESCRIPTOR_EXTENT(source, 1)); - ret->data = internal_malloc_size (size * size0 ((array_t*)ret)); + + array_size = size0 ((array_t*)ret); + if (unlikely (array_size < 1)) + alloc_size = 1; + else + alloc_size = size * array_size; + + ret->data = internal_malloc_size (alloc_size); ret->offset = 0; } else if (unlikely (compile_options.bounds_check)) Index: intrinsics/unpack_generic.c =================================================================== --- intrinsics/unpack_generic.c (Revision 175598) +++ intrinsics/unpack_generic.c (Arbeitskopie) @@ -111,6 +111,8 @@ unpack_internal (gfc_array_char *ret, const gfc_ar { /* The front end has signalled that we need to populate the return array descriptor. */ + index_type alloc_size; + dim = GFC_DESCRIPTOR_RANK (mask); rs = 1; for (n = 0; n < dim; n++) @@ -126,7 +128,13 @@ unpack_internal (gfc_array_char *ret, const gfc_ar rs *= extent[n]; } ret->offset = 0; - ret->data = internal_malloc_size (rs * size); + + if (unlikely (rs < 1)) + alloc_size = 1; + else + alloc_size = rs * size; + + ret->data = internal_malloc_size (alloc_size); } else {