diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a8880ad5a34..ef2a4be73d8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-05-04 Thomas Koenig + + PR libfortran/35990 + * gfortran.dg/intrinsic_pack_4.f90: New test case. + 2008-05-03 Eric Botcazou * gnat.dg/discr6_pkg.ads: New helper. diff --git a/gcc/testsuite/gfortran.dg/intrinsic_pack_4.f90 b/gcc/testsuite/gfortran.dg/intrinsic_pack_4.f90 new file mode 100644 index 00000000000..691036817df --- /dev/null +++ b/gcc/testsuite/gfortran.dg/intrinsic_pack_4.f90 @@ -0,0 +1,72 @@ +! { dg-do run } +! PR 35990 - some empty array sections caused pack to crash. +! Test case contributed by Dick Hendrickson, adjusted and +! extended by Thomas Koenig. + program try_gf1048 + + call gf1048a( 10, 8, 7, 1, 0, .true.) + call gf1048b( 10, 8, 7, 1, 0, .true.) + call gf1048c( 10, 8, 7, 1, 0, .true.) + call gf1048d( 10, 8, 7, 1, 0, .true.) + call P_inta ( 10, 8, 7, 1, 0, .true.) + call P_intb ( 10, 8, 7, 1, 0, .true.) + call P_intc ( 10, 8, 7, 1, 0, .true.) + call P_intd ( 10, 8, 7, 1, 0, .true.) + end program + + SUBROUTINE GF1048a(nf10,nf8,nf7,nf1,nf0,nf_true) + logical nf_true + CHARACTER(9) BDA(10) + CHARACTER(9) BDA1(10) + BDA( 8:7) = PACK(BDA1( 10: 1), NF_TRUE) + END SUBROUTINE + + SUBROUTINE GF1048b(nf10,nf8,nf7,nf1,nf0,nf_true) + logical nf_true + CHARACTER(9) BDA(10) + CHARACTER(9) BDA1(nf10) + BDA(NF8:NF7) = PACK(BDA1(NF8:NF7), NF_TRUE) + END SUBROUTINE + + SUBROUTINE GF1048c(nf10,nf8,nf7,nf1,nf0,nf_true) + logical nf_true + CHARACTER(9) BDA(10) + CHARACTER(9) BDA1(10) + BDA(NF8:NF7) = PACK(BDA1(NF10:NF1), NF_TRUE) + END SUBROUTINE + + SUBROUTINE GF1048d(nf10,nf8,nf7,nf1,nf0,nf_true) + logical nf_true + CHARACTER(9) BDA(10) + CHARACTER(9) BDA1(nf10) + BDA(NF8:NF7) = PACK(BDA1(NF10:NF1), NF_TRUE) + END SUBROUTINE + + SUBROUTINE P_INTa(nf10,nf8,nf7,nf1,nf0,nf_true) + logical nf_true + INTEGER BDA(10) + INTEGER BDA1(10) + BDA( 8:7) = PACK(BDA1( 10: 1), NF_TRUE) + END SUBROUTINE + + SUBROUTINE P_INTb(nf10,nf8,nf7,nf1,nf0,nf_true) + logical nf_true + INTEGER BDA(10) + INTEGER BDA1(nf10) + BDA(NF8:NF7) = PACK(BDA1(NF8:NF7), NF_TRUE) + END SUBROUTINE + + SUBROUTINE P_INTc(nf10,nf8,nf7,nf1,nf0,nf_true) + logical nf_true + INTEGER BDA(10) + INTEGER BDA1(10) + BDA(NF8:NF7) = PACK(BDA1(NF10:NF1), NF_TRUE) + END SUBROUTINE + + SUBROUTINE P_INTd(nf10,nf8,nf7,nf1,nf0,nf_true) + logical nf_true + INTEGER BDA(10) + INTEGER BDA1(nf10) + BDA(NF8:NF7) = PACK(BDA1(NF10:NF1), NF_TRUE) + END SUBROUTINE + diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 63b6ad0ddc8..89019b36f8a 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,29 @@ +2008-05-04 Thomas Koenig + + PR libfortran/35990 + * intrinsics/pack_generic.c: If an extent of the source + array is less then zero, set it to zero. Set the source + pointer to NULL if the source size is zero. Set the total + number of elements to zero if the vector has an extent + less or equal to zero. + * m4/pack.m4: Set the source pointer to NULL if the + source array is zero-sized. Set the total number of + elemements to zero if the vector has an extent less or + equal to zero. + * generated/pack_i1.c: Regenerated. + * generated/pack_i2.c: Regenerated. + * generated/pack_i4.c: Regenerated. + * generated/pack_i8.c: Regenerated. + * generated/pack_i16.c: Regenerated. + * generated/pack_r4.c: Regenerated. + * generated/pack_r8.c: Regenerated. + * generated/pack_r10.c: Regenerated. + * generated/pack_r16.c: Regenerated. + * generated/pack_c4.c: Regenerated. + * generated/pack_c8.c: Regenerated. + * generated/pack_c10.c: Regenerated. + * generated/pack_c16.c: Regenerated. + 2008-05-01 Jerry DeLisle PR libfortran/36094 diff --git a/libgfortran/generated/pack_c10.c b/libgfortran/generated/pack_c10.c index c9a0c58a5b5..0bad32385d8 100644 --- a/libgfortran/generated/pack_c10.c +++ b/libgfortran/generated/pack_c10.c @@ -103,7 +103,6 @@ pack_c10 (gfc_array_c10 *ret, const gfc_array_c10 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_c10 (gfc_array_c10 *ret, const gfc_array_c10 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_c10 (gfc_array_c10 *ret, const gfc_array_c10 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_c10 (gfc_array_c10 *ret, const gfc_array_c10 *array, } #endif + diff --git a/libgfortran/generated/pack_c16.c b/libgfortran/generated/pack_c16.c index 2996be2d220..a0c87ec8a26 100644 --- a/libgfortran/generated/pack_c16.c +++ b/libgfortran/generated/pack_c16.c @@ -103,7 +103,6 @@ pack_c16 (gfc_array_c16 *ret, const gfc_array_c16 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_c16 (gfc_array_c16 *ret, const gfc_array_c16 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_c16 (gfc_array_c16 *ret, const gfc_array_c16 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_c16 (gfc_array_c16 *ret, const gfc_array_c16 *array, } #endif + diff --git a/libgfortran/generated/pack_c4.c b/libgfortran/generated/pack_c4.c index ee41c0b8cbf..2fb6a20ad9c 100644 --- a/libgfortran/generated/pack_c4.c +++ b/libgfortran/generated/pack_c4.c @@ -103,7 +103,6 @@ pack_c4 (gfc_array_c4 *ret, const gfc_array_c4 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_c4 (gfc_array_c4 *ret, const gfc_array_c4 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_c4 (gfc_array_c4 *ret, const gfc_array_c4 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_c4 (gfc_array_c4 *ret, const gfc_array_c4 *array, } #endif + diff --git a/libgfortran/generated/pack_c8.c b/libgfortran/generated/pack_c8.c index a129422e04f..1a4e78ec792 100644 --- a/libgfortran/generated/pack_c8.c +++ b/libgfortran/generated/pack_c8.c @@ -103,7 +103,6 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_c8 (gfc_array_c8 *ret, const gfc_array_c8 *array, } #endif + diff --git a/libgfortran/generated/pack_i1.c b/libgfortran/generated/pack_i1.c index 25d7f569de5..44c6c677e44 100644 --- a/libgfortran/generated/pack_i1.c +++ b/libgfortran/generated/pack_i1.c @@ -103,7 +103,6 @@ pack_i1 (gfc_array_i1 *ret, const gfc_array_i1 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_i1 (gfc_array_i1 *ret, const gfc_array_i1 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_i1 (gfc_array_i1 *ret, const gfc_array_i1 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_i1 (gfc_array_i1 *ret, const gfc_array_i1 *array, } #endif + diff --git a/libgfortran/generated/pack_i16.c b/libgfortran/generated/pack_i16.c index 35c64ce8a9e..e9c15437977 100644 --- a/libgfortran/generated/pack_i16.c +++ b/libgfortran/generated/pack_i16.c @@ -103,7 +103,6 @@ pack_i16 (gfc_array_i16 *ret, const gfc_array_i16 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_i16 (gfc_array_i16 *ret, const gfc_array_i16 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_i16 (gfc_array_i16 *ret, const gfc_array_i16 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_i16 (gfc_array_i16 *ret, const gfc_array_i16 *array, } #endif + diff --git a/libgfortran/generated/pack_i2.c b/libgfortran/generated/pack_i2.c index 3a42bd38d78..51380c26ba7 100644 --- a/libgfortran/generated/pack_i2.c +++ b/libgfortran/generated/pack_i2.c @@ -103,7 +103,6 @@ pack_i2 (gfc_array_i2 *ret, const gfc_array_i2 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_i2 (gfc_array_i2 *ret, const gfc_array_i2 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_i2 (gfc_array_i2 *ret, const gfc_array_i2 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_i2 (gfc_array_i2 *ret, const gfc_array_i2 *array, } #endif + diff --git a/libgfortran/generated/pack_i4.c b/libgfortran/generated/pack_i4.c index 28e09f6abec..861670d6865 100644 --- a/libgfortran/generated/pack_i4.c +++ b/libgfortran/generated/pack_i4.c @@ -103,7 +103,6 @@ pack_i4 (gfc_array_i4 *ret, const gfc_array_i4 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_i4 (gfc_array_i4 *ret, const gfc_array_i4 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_i4 (gfc_array_i4 *ret, const gfc_array_i4 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_i4 (gfc_array_i4 *ret, const gfc_array_i4 *array, } #endif + diff --git a/libgfortran/generated/pack_i8.c b/libgfortran/generated/pack_i8.c index 44fc430782f..c547f3809f2 100644 --- a/libgfortran/generated/pack_i8.c +++ b/libgfortran/generated/pack_i8.c @@ -103,7 +103,6 @@ pack_i8 (gfc_array_i8 *ret, const gfc_array_i8 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_i8 (gfc_array_i8 *ret, const gfc_array_i8 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_i8 (gfc_array_i8 *ret, const gfc_array_i8 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_i8 (gfc_array_i8 *ret, const gfc_array_i8 *array, } #endif + diff --git a/libgfortran/generated/pack_r10.c b/libgfortran/generated/pack_r10.c index 72fe254d918..4b8c5784aef 100644 --- a/libgfortran/generated/pack_r10.c +++ b/libgfortran/generated/pack_r10.c @@ -103,7 +103,6 @@ pack_r10 (gfc_array_r10 *ret, const gfc_array_r10 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_r10 (gfc_array_r10 *ret, const gfc_array_r10 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_r10 (gfc_array_r10 *ret, const gfc_array_r10 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_r10 (gfc_array_r10 *ret, const gfc_array_r10 *array, } #endif + diff --git a/libgfortran/generated/pack_r16.c b/libgfortran/generated/pack_r16.c index 0ced53ab017..a691f7c4041 100644 --- a/libgfortran/generated/pack_r16.c +++ b/libgfortran/generated/pack_r16.c @@ -103,7 +103,6 @@ pack_r16 (gfc_array_r16 *ret, const gfc_array_r16 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_r16 (gfc_array_r16 *ret, const gfc_array_r16 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_r16 (gfc_array_r16 *ret, const gfc_array_r16 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_r16 (gfc_array_r16 *ret, const gfc_array_r16 *array, } #endif + diff --git a/libgfortran/generated/pack_r4.c b/libgfortran/generated/pack_r4.c index 17172ed92a8..c008aadf4d4 100644 --- a/libgfortran/generated/pack_r4.c +++ b/libgfortran/generated/pack_r4.c @@ -103,7 +103,6 @@ pack_r4 (gfc_array_r4 *ret, const gfc_array_r4 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_r4 (gfc_array_r4 *ret, const gfc_array_r4 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_r4 (gfc_array_r4 *ret, const gfc_array_r4 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_r4 (gfc_array_r4 *ret, const gfc_array_r4 *array, } #endif + diff --git a/libgfortran/generated/pack_r8.c b/libgfortran/generated/pack_r8.c index 9d0fb5b5d78..7b360479628 100644 --- a/libgfortran/generated/pack_r8.c +++ b/libgfortran/generated/pack_r8.c @@ -103,7 +103,6 @@ pack_r8 (gfc_array_r8 *ret, const gfc_array_r8 *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -139,6 +138,11 @@ pack_r8 (gfc_array_r8 *ret, const gfc_array_r8 *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -149,6 +153,11 @@ pack_r8 (gfc_array_r8 *ret, const gfc_array_r8 *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -308,3 +317,4 @@ pack_r8 (gfc_array_r8 *ret, const gfc_array_r8 *array, } #endif + diff --git a/libgfortran/m4/pack.m4 b/libgfortran/m4/pack.m4 index 87409a56223..4f31ffdd15e 100644 --- a/libgfortran/m4/pack.m4 +++ b/libgfortran/m4/pack.m4 @@ -104,7 +104,6 @@ pack_'rtype_code` ('rtype` *ret, const 'rtype` *array, dim = GFC_DESCRIPTOR_RANK (array); - sptr = array->data; mptr = mask->data; /* Use the same loop for all logical types, by using GFC_LOGICAL_1 @@ -140,6 +139,11 @@ pack_'rtype_code` ('rtype` *ret, const 'rtype` *array, if (mstride[0] == 0) mstride[0] = mask_kind; + if (zero_sized) + sptr = NULL; + else + sptr = array->data; + if (ret->data == NULL || compile_options.bounds_check) { /* Count the elements, either for allocating memory or @@ -150,6 +154,11 @@ pack_'rtype_code` ('rtype` *ret, const 'rtype` *array, /* The return array will have as many elements as there are in VECTOR. */ total = vector->dim[0].ubound + 1 - vector->dim[0].lbound; + if (total < 0) + { + total = 0; + vector = NULL; + } } else { @@ -309,4 +318,4 @@ pack_'rtype_code` ('rtype` *ret, const 'rtype` *array, } #endif -' \ No newline at end of file +'