Commit e11449d1 by Fritz Reese Committed by Fritz Reese

Fix handling of invalid assumed-shape/size arrays in legacy initializer lists.

2018-07-16  Fritz Reese  <fritzoreese@gmail.com>

    Fix handling of invalid assumed-shape/size arrays in legacy initializer
    lists.

    gcc/fortran/ChangeLog:

	PR fortran/83184
	* decl.c (match_old_style_init): Initialize locus of variable expr when
	creating a data variable.
	(match_clist_expr): Verify array is explicit shape/size before
	attempting to allocate constant array constructor.

    gcc/testsuite/ChangeLog:

	PR fortran/83184
	* gfortran.dg/assumed_rank_14.f90: New testcase.
	* gfortran.dg/assumed_rank_15.f90: New testcase.
	* gfortran.dg/dec_structure_8.f90: Update error messages.
	* gfortran.dg/dec_structure_23.f90: Update error messages.

From-SVN: r262744
parent 835e529d
2018-07-16 Fritz Reese <fritzoreese@gmail.com> 2018-07-16 Fritz Reese <fritzoreese@gmail.com>
PR fortran/83184
* decl.c (match_old_style_init): Initialize locus of variable expr when
creating a data variable.
(match_clist_expr): Verify array is explicit shape/size before
attempting to allocate constant array constructor.
2018-07-16 Fritz Reese <fritzoreese@gmail.com>
PR fortran/86417 PR fortran/86417
* module.c (mio_component): Set component->loc when loading from module. * module.c (mio_component): Set component->loc when loading from module.
......
...@@ -534,6 +534,7 @@ match_old_style_init (const char *name) ...@@ -534,6 +534,7 @@ match_old_style_init (const char *name)
newdata = gfc_get_data (); newdata = gfc_get_data ();
newdata->var = gfc_get_data_variable (); newdata->var = gfc_get_data_variable ();
newdata->var->expr = gfc_get_variable_expr (st); newdata->var->expr = gfc_get_variable_expr (st);
newdata->var->expr->where = sym->declared_at;
newdata->where = gfc_current_locus; newdata->where = gfc_current_locus;
/* Match initial value list. This also eats the terminal '/'. */ /* Match initial value list. This also eats the terminal '/'. */
...@@ -659,7 +660,7 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as) ...@@ -659,7 +660,7 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as)
{ {
gfc_constructor_base array_head = NULL; gfc_constructor_base array_head = NULL;
gfc_expr *expr = NULL; gfc_expr *expr = NULL;
match m; match m = MATCH_ERROR;
locus where; locus where;
mpz_t repeat, cons_size, as_size; mpz_t repeat, cons_size, as_size;
bool scalar; bool scalar;
...@@ -667,18 +668,27 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as) ...@@ -667,18 +668,27 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as)
gcc_assert (ts); gcc_assert (ts);
mpz_init_set_ui (repeat, 0);
scalar = !as || !as->rank;
/* We have already matched '/' - now look for a constant list, as with /* We have already matched '/' - now look for a constant list, as with
top_val_list from decl.c, but append the result to an array. */ top_val_list from decl.c, but append the result to an array. */
if (gfc_match ("/") == MATCH_YES) if (gfc_match ("/") == MATCH_YES)
{ {
gfc_error ("Empty old style initializer list at %C"); gfc_error ("Empty old style initializer list at %C");
goto cleanup; return MATCH_ERROR;
} }
where = gfc_current_locus; where = gfc_current_locus;
scalar = !as || !as->rank;
if (!scalar && !spec_size (as, &as_size))
{
gfc_error ("Array in initializer list at %L must have an explicit shape",
as->type == AS_EXPLICIT ? &as->upper[0]->where : &where);
/* Nothing to cleanup yet. */
return MATCH_ERROR;
}
mpz_init_set_ui (repeat, 0);
for (;;) for (;;)
{ {
m = match_data_constant (&expr); m = match_data_constant (&expr);
...@@ -708,7 +718,10 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as) ...@@ -708,7 +718,10 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as)
m = match_data_constant (&expr); m = match_data_constant (&expr);
if (m == MATCH_NO) if (m == MATCH_NO)
gfc_error ("Expected data constant after repeat spec at %C"); {
m = MATCH_ERROR;
gfc_error ("Expected data constant after repeat spec at %C");
}
if (m != MATCH_YES) if (m != MATCH_YES)
goto cleanup; goto cleanup;
} }
...@@ -751,6 +764,9 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as) ...@@ -751,6 +764,9 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as)
goto syntax; goto syntax;
} }
/* If we break early from here out, we encountered an error. */
m = MATCH_ERROR;
/* Set up expr as an array constructor. */ /* Set up expr as an array constructor. */
if (!scalar) if (!scalar)
{ {
...@@ -763,25 +779,13 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as) ...@@ -763,25 +779,13 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as)
/* Validate sizes. We built expr ourselves, so cons_size will be /* Validate sizes. We built expr ourselves, so cons_size will be
constant (we fail above for non-constant expressions). constant (we fail above for non-constant expressions).
We still need to verify that the array-spec has constant size. */ We still need to verify that the sizes match. */
cmp = 0;
gcc_assert (gfc_array_size (expr, &cons_size)); gcc_assert (gfc_array_size (expr, &cons_size));
if (!spec_size (as, &as_size)) cmp = mpz_cmp (cons_size, as_size);
{ if (cmp < 0)
gfc_error ("Expected constant array-spec in initializer list at %L", gfc_error ("Not enough elements in array initializer at %C");
as->type == AS_EXPLICIT ? &as->upper[0]->where : &where); else if (cmp > 0)
cmp = -1; gfc_error ("Too many elements in array initializer at %C");
}
else
{
/* Make sure the specs are of the same size. */
cmp = mpz_cmp (cons_size, as_size);
if (cmp < 0)
gfc_error ("Not enough elements in array initializer at %C");
else if (cmp > 0)
gfc_error ("Too many elements in array initializer at %C");
mpz_clear (as_size);
}
mpz_clear (cons_size); mpz_clear (cons_size);
if (cmp) if (cmp)
goto cleanup; goto cleanup;
...@@ -796,10 +800,11 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as) ...@@ -796,10 +800,11 @@ match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as)
expr->ts.u.cl->length_from_typespec = 1; expr->ts.u.cl->length_from_typespec = 1;
*result = expr; *result = expr;
mpz_clear (repeat); m = MATCH_YES;
return MATCH_YES; goto done;
syntax: syntax:
m = MATCH_ERROR;
gfc_error ("Syntax error in old style initializer list at %C"); gfc_error ("Syntax error in old style initializer list at %C");
cleanup: cleanup:
...@@ -807,8 +812,12 @@ cleanup: ...@@ -807,8 +812,12 @@ cleanup:
expr->value.constructor = NULL; expr->value.constructor = NULL;
gfc_free_expr (expr); gfc_free_expr (expr);
gfc_constructor_free (array_head); gfc_constructor_free (array_head);
done:
mpz_clear (repeat); mpz_clear (repeat);
return MATCH_ERROR; if (!scalar)
mpz_clear (as_size);
return m;
} }
......
2018-07-16 Fritz Reese <fritzoreese@gmail.com>
PR fortran/83184
* gfortran.dg/assumed_rank_14.f90: New testcase.
* gfortran.dg/assumed_rank_15.f90: New testcase.
* gfortran.dg/dec_structure_8.f90: Update error messages.
* gfortran.dg/dec_structure_23.f90: Update error messages.
2018-07-16 Bernd Edlinger <bernd.edlinger@hotmail.de> 2018-07-16 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR middle-end/86528 PR middle-end/86528
......
! { dg-do compile }
! { dg-options "-std=legacy" }
!
! PR fortran/83184
!
integer n1(..) /1/
! { dg-error "Assumed-rank array.*must be a dummy argument" "" { target *-*-* } 7 }
! { dg-error "Assumed-rank variable.*actual argument" "" { target *-*-* } 7 }
end
! { dg-do compile }
! { dg-options "-fdec-structure" }
!
! PR fortran/83184
!
structure /s/
integer n(..) /1/ ! { dg-error "must have an explicit shape" }
end structure
end
...@@ -13,8 +13,8 @@ program p ...@@ -13,8 +13,8 @@ program p
integer :: nn integer :: nn
real :: rr real :: rr
structure /s/ structure /s/
integer x(n) /1/ ! { dg-error "array with nonconstant bounds" } integer x(n) /1/ ! { dg-error "must have an explicit shape" }
integer xx(nn) /1/ ! { dg-error "array with nonconstant bounds" } integer xx(nn) /1/ ! { dg-error "must have an explicit shape" }
integer xxx(rr) /1.0/ ! { dg-error "array with nonconstant bounds" } integer xxx(rr) /1.0/ ! { dg-error "must have an explicit shape" }
end structure end structure
end end
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
! Old-style (clist) initialization ! Old-style (clist) initialization
integer,parameter :: as = 3 integer,parameter :: as = 3
structure /t1/ structure /t1/ ! { dg-error "Type definition.*T1" }
integer*1 a /300_2/ ! { dg-error "Arithmetic overflow" } integer*1 a /300_2/ ! { dg-error "Arithmetic overflow" }
integer b // ! { dg-error "Empty old style initializer list" } integer b // ! { dg-error "Empty old style initializer list" }
integer c /2*3/ ! { dg-error "Repeat spec invalid in scalar" } integer c /2*3/ ! { dg-error "Repeat spec invalid in scalar" }
...@@ -44,14 +44,14 @@ record /t1/ ! { dg-error "Invalid character in name" } ...@@ -44,14 +44,14 @@ record /t1/ ! { dg-error "Invalid character in name" }
structure /t2/ structure /t2/
ENTRY here ! { dg-error "ENTRY statement.*cannot appear" } ENTRY here ! { dg-error "ENTRY statement.*cannot appear" }
integer a integer a ! { dg-error "Component.*already declared" }
integer a ! { dg-error "Component.*already declared" } integer a ! { dg-error "Component.*already declared" }
structure $z ! { dg-error "Invalid character in name" } structure $z ! { dg-error "Invalid character in name" }
structure // ! { dg-error "Invalid character in name" } structure // ! { dg-error "Invalid character in name" }
structure // x ! { dg-error "Invalid character in name" } structure // x ! { dg-error "Invalid character in name" }
structure /t3/ ! { dg-error "Invalid character in name" } structure /t3/ ! { dg-error "Invalid character in name" }
structure /t3/ x,$y ! { dg-error "Invalid character in name" } structure /t3/ x,$y ! { dg-error "Invalid character in name" }
structure /t4/ y structure /t4/ y ! { dg-error "Type definition.*T4" }
integer i, j, k integer i, j, k
end structure end structure
structure /t4/ z ! { dg-error "Type definition.*T4" } structure /t4/ z ! { dg-error "Type definition.*T4" }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment