PR fortran/50815
* trans-decl.c (add_argument_checking): Skip bound checking
for deferred-length strings.
2011-12-08 Tobias Burnus <burnus@net-b.de>
PR fortran/50815
* gfortran.dg/bounds_check_16.f90: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182134
138bc75d-0d04-0410-961f-
82ee72b054a4
2011-12-08 Tobias Burnus <burnus@net-b.de>
2011-12-08 Tobias Burnus <burnus@net-b.de>
+ PR fortran/50815
+ * trans-decl.c (add_argument_checking): Skip bound checking
+ for deferred-length strings.
+
+2011-12-08 Tobias Burnus <burnus@net-b.de>
+
PR fortran/51378
* symbol.c (gfc_find_component): Fix access check of parent
components.
PR fortran/51378
* symbol.c (gfc_find_component): Fix access check of parent
components.
if the actual argument is (part of) an array, but only if the
dummy argument is an array. (See "Sequence association" in
Section 12.4.1.4 for F95 and 12.4.1.5 for F2003.) */
if the actual argument is (part of) an array, but only if the
dummy argument is an array. (See "Sequence association" in
Section 12.4.1.4 for F95 and 12.4.1.5 for F2003.) */
- if (fsym->attr.pointer || fsym->attr.allocatable
- || (fsym->as && fsym->as->type == AS_ASSUMED_SHAPE))
+ if (fsym->ts.deferred)
+ continue;
+ else if (fsym->attr.pointer || fsym->attr.allocatable
+ || (fsym->as && fsym->as->type == AS_ASSUMED_SHAPE))
{
comparison = NE_EXPR;
message = _("Actual string length does not match the declared one"
{
comparison = NE_EXPR;
message = _("Actual string length does not match the declared one"
2011-12-08 Tobias Burnus <burnus@net-b.de>
2011-12-08 Tobias Burnus <burnus@net-b.de>
+ PR fortran/50815
+ * gfortran.dg/bounds_check_16.f90: New.
+
+2011-12-08 Tobias Burnus <burnus@net-b.de>
+
PR fortran/51378
* gfortran.dg/private_type_14.f90: New.
PR fortran/51378
* gfortran.dg/private_type_14.f90: New.
--- /dev/null
+! { dg-do compile }
+! { dg-options "-fcheck=bounds" }
+!
+! PR fortran/50815
+!
+! Don't check the bounds of deferred-length strings.
+! gfortran had an ICE before because it did.
+!
+SUBROUTINE TEST(VALUE)
+ IMPLICIT NONE
+ CHARACTER(LEN=:), ALLOCATABLE :: VALUE
+ CHARACTER(LEN=128) :: VAL
+ VALUE = VAL
+END SUBROUTINE TEST
+static int
+require_numeric_type (st_parameter_dt *dtp, bt actual, const fnode *f)
+{
+#define BUFLEN 100
+ char buffer[BUFLEN];
+
+ if (actual == BT_INTEGER || actual == BT_REAL || actual == BT_COMPLEX)
+ return 0;
+
+ /* Adjust item_count before emitting error message. */
+ snprintf (buffer, BUFLEN,
+ "Expected numeric type for item %d in formatted transfer, got %s",
+ dtp->u.p.item_count - 1, type_name (actual));
+
+ format_error (dtp, f, buffer);
+ return 1;
+}
+
+
/* This function is in the main loop for a formatted data transfer
statement. It would be natural to implement this as a coroutine
with the user program, but C makes that awkward. We loop,
/* This function is in the main loop for a formatted data transfer
statement. It would be natural to implement this as a coroutine
with the user program, but C makes that awkward. We loop,
if (n == 0)
goto need_read_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
if (n == 0)
goto need_read_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
+ && require_numeric_type (dtp, type, f))
+ return;
+ if (!(compile_options.allow_std & GFC_STD_F2008)
&& require_type (dtp, BT_INTEGER, type, f))
return;
read_radix (dtp, f, p, kind, 2);
&& require_type (dtp, BT_INTEGER, type, f))
return;
read_radix (dtp, f, p, kind, 2);
if (n == 0)
goto need_read_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
if (n == 0)
goto need_read_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
+ && require_numeric_type (dtp, type, f))
+ return;
+ if (!(compile_options.allow_std & GFC_STD_F2008)
&& require_type (dtp, BT_INTEGER, type, f))
return;
read_radix (dtp, f, p, kind, 8);
&& require_type (dtp, BT_INTEGER, type, f))
return;
read_radix (dtp, f, p, kind, 8);
if (n == 0)
goto need_read_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
if (n == 0)
goto need_read_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
+ && require_numeric_type (dtp, type, f))
+ return;
+ if (!(compile_options.allow_std & GFC_STD_F2008)
&& require_type (dtp, BT_INTEGER, type, f))
return;
read_radix (dtp, f, p, kind, 16);
&& require_type (dtp, BT_INTEGER, type, f))
return;
read_radix (dtp, f, p, kind, 16);
if (n == 0)
goto need_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
if (n == 0)
goto need_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
+ && require_numeric_type (dtp, type, f))
+ return;
+ if (!(compile_options.allow_std & GFC_STD_F2008)
&& require_type (dtp, BT_INTEGER, type, f))
return;
write_b (dtp, f, p, kind);
&& require_type (dtp, BT_INTEGER, type, f))
return;
write_b (dtp, f, p, kind);
if (n == 0)
goto need_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
if (n == 0)
goto need_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
+ && require_numeric_type (dtp, type, f))
+ return;
+ if (!(compile_options.allow_std & GFC_STD_F2008)
&& require_type (dtp, BT_INTEGER, type, f))
return;
write_o (dtp, f, p, kind);
&& require_type (dtp, BT_INTEGER, type, f))
return;
write_o (dtp, f, p, kind);
if (n == 0)
goto need_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
if (n == 0)
goto need_data;
if (!(compile_options.allow_std & GFC_STD_GNU)
+ && require_numeric_type (dtp, type, f))
+ return;
+ if (!(compile_options.allow_std & GFC_STD_F2008)
&& require_type (dtp, BT_INTEGER, type, f))
return;
write_z (dtp, f, p, kind);
&& require_type (dtp, BT_INTEGER, type, f))
return;
write_z (dtp, f, p, kind);