PR fortran/36517, fortran/36492
2008-06-18 Daniel Kraft <d@domob.eu> PR fortran/36517, fortran/36492 * gfortran.dg/array_constructor_25.f03: New test. * gfortran.dg/array_constructor_26.f03: New test. * gfortran.dg/array_constructor_27.f03: New test. * gfortran.dg/array_constructor_28.f03: New test. * gfortran.dg/array_constructor_29.f03: New test. * gfortran.dg/array_constructor_30.f03: New test. * gfortran.dg/array_constructor_type_19.f03: New test. * gfortran.dg/array_constructor_type_20.f03: New test. * gfortran.dg/array_constructor_type_21.f03: New test. 2008-06-18 Daniel Kraft <d@domob.eu> PR fortran/36517, fortran/36492 * array.c (gfc_resolve_character_array_constructor): Call gfc_set_constant_character_len with changed length-chec argument. * decl.c (gfc_set_constant_character_len): Changed array argument to be a generic length-checking argument that can be used for correct checking with typespec and in special cases where the should-be length is different from the target length. (build_struct): Call gfc_set_constant_character_len with changed length checking argument and introduced additional checks for exceptional conditions on invalid code. (add_init_expr_to_sym), (do_parm): Call gfc_set_constant_character_len with changed argument. * match.h (gfc_set_constant_character_len): Changed third argument to int for the should-be length rather than bool. From-SVN: r136894
This commit is contained in:
parent
f0c882ab6f
commit
d28480827e
@ -1,3 +1,20 @@
|
|||||||
|
2008-06-18 Daniel Kraft <d@domob.eu>
|
||||||
|
|
||||||
|
PR fortran/36517, fortran/36492
|
||||||
|
* array.c (gfc_resolve_character_array_constructor): Call
|
||||||
|
gfc_set_constant_character_len with changed length-chec argument.
|
||||||
|
* decl.c (gfc_set_constant_character_len): Changed array argument to
|
||||||
|
be a generic length-checking argument that can be used for correct
|
||||||
|
checking with typespec and in special cases where the should-be length
|
||||||
|
is different from the target length.
|
||||||
|
(build_struct): Call gfc_set_constant_character_len with changed length
|
||||||
|
checking argument and introduced additional checks for exceptional
|
||||||
|
conditions on invalid code.
|
||||||
|
(add_init_expr_to_sym), (do_parm): Call gfc_set_constant_character_len
|
||||||
|
with changed argument.
|
||||||
|
* match.h (gfc_set_constant_character_len): Changed third argument to
|
||||||
|
int for the should-be length rather than bool.
|
||||||
|
|
||||||
2008-06-17 Daniel Kraft <d@domob.eu>
|
2008-06-17 Daniel Kraft <d@domob.eu>
|
||||||
|
|
||||||
PR fortran/36112
|
PR fortran/36112
|
||||||
|
@ -1680,25 +1680,29 @@ got_charlen:
|
|||||||
(without typespec) all elements are verified to have the same length
|
(without typespec) all elements are verified to have the same length
|
||||||
anyway. */
|
anyway. */
|
||||||
if (found_length != -1)
|
if (found_length != -1)
|
||||||
for (p = expr->value.constructor; p; p = p->next)
|
for (p = expr->value.constructor; p; p = p->next)
|
||||||
if (p->expr->expr_type == EXPR_CONSTANT)
|
if (p->expr->expr_type == EXPR_CONSTANT)
|
||||||
{
|
{
|
||||||
gfc_expr *cl = NULL;
|
gfc_expr *cl = NULL;
|
||||||
int current_length = -1;
|
int current_length = -1;
|
||||||
|
bool has_ts;
|
||||||
|
|
||||||
if (p->expr->ts.cl && p->expr->ts.cl->length)
|
if (p->expr->ts.cl && p->expr->ts.cl->length)
|
||||||
{
|
{
|
||||||
cl = p->expr->ts.cl->length;
|
cl = p->expr->ts.cl->length;
|
||||||
gfc_extract_int (cl, ¤t_length);
|
gfc_extract_int (cl, ¤t_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If gfc_extract_int above set current_length, we implicitly
|
/* If gfc_extract_int above set current_length, we implicitly
|
||||||
know the type is BT_INTEGER and it's EXPR_CONSTANT. */
|
know the type is BT_INTEGER and it's EXPR_CONSTANT. */
|
||||||
|
|
||||||
if (! cl
|
has_ts = (expr->ts.cl && expr->ts.cl->length_from_typespec);
|
||||||
|| (current_length != -1 && current_length < found_length))
|
|
||||||
gfc_set_constant_character_len (found_length, p->expr, true);
|
if (! cl
|
||||||
}
|
|| (current_length != -1 && current_length < found_length))
|
||||||
|
gfc_set_constant_character_len (found_length, p->expr,
|
||||||
|
has_ts ? -1 : found_length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -1084,10 +1084,12 @@ build_sym (const char *name, gfc_charlen *cl,
|
|||||||
|
|
||||||
|
|
||||||
/* Set character constant to the given length. The constant will be padded or
|
/* Set character constant to the given length. The constant will be padded or
|
||||||
truncated. */
|
truncated. If we're inside an array constructor without a typespec, we
|
||||||
|
additionally check that all elements have the same length; check_len -1
|
||||||
|
means no checking. */
|
||||||
|
|
||||||
void
|
void
|
||||||
gfc_set_constant_character_len (int len, gfc_expr *expr, bool array)
|
gfc_set_constant_character_len (int len, gfc_expr *expr, int check_len)
|
||||||
{
|
{
|
||||||
gfc_char_t *s;
|
gfc_char_t *s;
|
||||||
int slen;
|
int slen;
|
||||||
@ -1110,10 +1112,11 @@ gfc_set_constant_character_len (int len, gfc_expr *expr, bool array)
|
|||||||
|
|
||||||
/* Apply the standard by 'hand' otherwise it gets cleared for
|
/* Apply the standard by 'hand' otherwise it gets cleared for
|
||||||
initializers. */
|
initializers. */
|
||||||
if (array && slen < len && !(gfc_option.allow_std & GFC_STD_GNU))
|
if (check_len != -1 && slen != check_len
|
||||||
|
&& !(gfc_option.allow_std & GFC_STD_GNU))
|
||||||
gfc_error_now ("The CHARACTER elements of the array constructor "
|
gfc_error_now ("The CHARACTER elements of the array constructor "
|
||||||
"at %L must have the same length (%d/%d)",
|
"at %L must have the same length (%d/%d)",
|
||||||
&expr->where, slen, len);
|
&expr->where, slen, check_len);
|
||||||
|
|
||||||
s[len] = '\0';
|
s[len] = '\0';
|
||||||
gfc_free (expr->value.character.string);
|
gfc_free (expr->value.character.string);
|
||||||
@ -1269,7 +1272,7 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus)
|
|||||||
gfc_constructor * p;
|
gfc_constructor * p;
|
||||||
|
|
||||||
if (init->expr_type == EXPR_CONSTANT)
|
if (init->expr_type == EXPR_CONSTANT)
|
||||||
gfc_set_constant_character_len (len, init, false);
|
gfc_set_constant_character_len (len, init, -1);
|
||||||
else if (init->expr_type == EXPR_ARRAY)
|
else if (init->expr_type == EXPR_ARRAY)
|
||||||
{
|
{
|
||||||
/* Build a new charlen to prevent simplification from
|
/* Build a new charlen to prevent simplification from
|
||||||
@ -1280,7 +1283,7 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus)
|
|||||||
init->ts.cl->length = gfc_copy_expr (sym->ts.cl->length);
|
init->ts.cl->length = gfc_copy_expr (sym->ts.cl->length);
|
||||||
|
|
||||||
for (p = init->value.constructor; p; p = p->next)
|
for (p = init->value.constructor; p; p = p->next)
|
||||||
gfc_set_constant_character_len (len, p->expr, false);
|
gfc_set_constant_character_len (len, p->expr, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1402,19 +1405,48 @@ build_struct (const char *name, gfc_charlen *cl, gfc_expr **init,
|
|||||||
|
|
||||||
/* Should this ever get more complicated, combine with similar section
|
/* Should this ever get more complicated, combine with similar section
|
||||||
in add_init_expr_to_sym into a separate function. */
|
in add_init_expr_to_sym into a separate function. */
|
||||||
if (c->ts.type == BT_CHARACTER && !c->pointer && c->initializer)
|
if (c->ts.type == BT_CHARACTER && !c->pointer && c->initializer && c->ts.cl
|
||||||
|
&& c->ts.cl->length && c->ts.cl->length->expr_type == EXPR_CONSTANT)
|
||||||
{
|
{
|
||||||
int len = mpz_get_si (c->ts.cl->length->value.integer);
|
int len;
|
||||||
|
|
||||||
|
gcc_assert (c->ts.cl && c->ts.cl->length);
|
||||||
|
gcc_assert (c->ts.cl->length->expr_type == EXPR_CONSTANT);
|
||||||
|
gcc_assert (c->ts.cl->length->ts.type == BT_INTEGER);
|
||||||
|
|
||||||
|
len = mpz_get_si (c->ts.cl->length->value.integer);
|
||||||
|
|
||||||
if (c->initializer->expr_type == EXPR_CONSTANT)
|
if (c->initializer->expr_type == EXPR_CONSTANT)
|
||||||
gfc_set_constant_character_len (len, c->initializer, false);
|
gfc_set_constant_character_len (len, c->initializer, -1);
|
||||||
else if (mpz_cmp (c->ts.cl->length->value.integer,
|
else if (mpz_cmp (c->ts.cl->length->value.integer,
|
||||||
c->initializer->ts.cl->length->value.integer))
|
c->initializer->ts.cl->length->value.integer))
|
||||||
{
|
{
|
||||||
|
bool has_ts;
|
||||||
gfc_constructor *ctor = c->initializer->value.constructor;
|
gfc_constructor *ctor = c->initializer->value.constructor;
|
||||||
for (;ctor ; ctor = ctor->next)
|
|
||||||
if (ctor->expr->expr_type == EXPR_CONSTANT)
|
bool first = true;
|
||||||
gfc_set_constant_character_len (len, ctor->expr, true);
|
int first_len;
|
||||||
|
|
||||||
|
has_ts = (c->initializer->ts.cl
|
||||||
|
&& c->initializer->ts.cl->length_from_typespec);
|
||||||
|
|
||||||
|
for (; ctor; ctor = ctor->next)
|
||||||
|
{
|
||||||
|
/* Remember the length of the first element for checking that
|
||||||
|
all elements *in the constructor* have the same length. This
|
||||||
|
need not be the length of the LHS! */
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
gcc_assert (ctor->expr->expr_type == EXPR_CONSTANT);
|
||||||
|
gcc_assert (ctor->expr->ts.type == BT_CHARACTER);
|
||||||
|
first_len = ctor->expr->value.character.length;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctor->expr->expr_type == EXPR_CONSTANT)
|
||||||
|
gfc_set_constant_character_len (len, ctor->expr,
|
||||||
|
has_ts ? -1 : first_len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5822,7 +5854,7 @@ do_parm (void)
|
|||||||
&& init->expr_type == EXPR_CONSTANT
|
&& init->expr_type == EXPR_CONSTANT
|
||||||
&& init->ts.type == BT_CHARACTER)
|
&& init->ts.type == BT_CHARACTER)
|
||||||
gfc_set_constant_character_len (
|
gfc_set_constant_character_len (
|
||||||
mpz_get_si (sym->ts.cl->length->value.integer), init, false);
|
mpz_get_si (sym->ts.cl->length->value.integer), init, -1);
|
||||||
else if (sym->ts.type == BT_CHARACTER && sym->ts.cl != NULL
|
else if (sym->ts.type == BT_CHARACTER && sym->ts.cl != NULL
|
||||||
&& sym->ts.cl->length == NULL)
|
&& sym->ts.cl->length == NULL)
|
||||||
{
|
{
|
||||||
|
@ -147,7 +147,7 @@ match gfc_match_final_decl (void);
|
|||||||
match gfc_match_implicit_none (void);
|
match gfc_match_implicit_none (void);
|
||||||
match gfc_match_implicit (void);
|
match gfc_match_implicit (void);
|
||||||
|
|
||||||
void gfc_set_constant_character_len (int, gfc_expr *, bool);
|
void gfc_set_constant_character_len (int, gfc_expr *, int);
|
||||||
|
|
||||||
/* Matchers for attribute declarations. */
|
/* Matchers for attribute declarations. */
|
||||||
match gfc_match_allocatable (void);
|
match gfc_match_allocatable (void);
|
||||||
|
@ -1,3 +1,16 @@
|
|||||||
|
2008-06-18 Daniel Kraft <d@domob.eu>
|
||||||
|
|
||||||
|
PR fortran/36517, fortran/36492
|
||||||
|
* gfortran.dg/array_constructor_25.f03: New test.
|
||||||
|
* gfortran.dg/array_constructor_26.f03: New test.
|
||||||
|
* gfortran.dg/array_constructor_27.f03: New test.
|
||||||
|
* gfortran.dg/array_constructor_28.f03: New test.
|
||||||
|
* gfortran.dg/array_constructor_29.f03: New test.
|
||||||
|
* gfortran.dg/array_constructor_30.f03: New test.
|
||||||
|
* gfortran.dg/array_constructor_type_19.f03: New test.
|
||||||
|
* gfortran.dg/array_constructor_type_20.f03: New test.
|
||||||
|
* gfortran.dg/array_constructor_type_21.f03: New test.
|
||||||
|
|
||||||
2008-06-17 Daniel Kraft <d@domob.eu>
|
2008-06-17 Daniel Kraft <d@domob.eu>
|
||||||
|
|
||||||
PR fortran/36112
|
PR fortran/36112
|
||||||
|
12
gcc/testsuite/gfortran.dg/array_constructor_25.f03
Normal file
12
gcc/testsuite/gfortran.dg/array_constructor_25.f03
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
! { dg-do compile }
|
||||||
|
! { dg-options "-std=f2003" }
|
||||||
|
|
||||||
|
! PR fortran/36492
|
||||||
|
! Check for incorrect error message with -std=f2003.
|
||||||
|
! Reduced test based on the one from comment #4, PR 36492.
|
||||||
|
|
||||||
|
type t
|
||||||
|
character (2) :: arr (1) = [ "a" ]
|
||||||
|
end type t
|
||||||
|
|
||||||
|
end
|
18
gcc/testsuite/gfortran.dg/array_constructor_26.f03
Normal file
18
gcc/testsuite/gfortran.dg/array_constructor_26.f03
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
! { dg-do compile }
|
||||||
|
|
||||||
|
! PR fortran/36492
|
||||||
|
! Check for incorrect error message with -std=f2003.
|
||||||
|
! Test from comment #4, PR 36492 causing ICE.
|
||||||
|
|
||||||
|
MODULE WinData
|
||||||
|
IMPLICIT NONE
|
||||||
|
INTEGER (1), PARAMETER :: MAXFLD = 25_1, MAXHED = 5_1, MAXCHR = 80_1
|
||||||
|
integer :: i
|
||||||
|
TYPE TWindowData
|
||||||
|
CHARACTER (MAX_FLD_HED, 1) :: DWFdHd(MAXFLD) = [(" ", i = 1, MAXFLD)]
|
||||||
|
! { dg-error "no IMPLICIT type" "" { target *-*-* } 12 }
|
||||||
|
! { dg-error "specification expression" "" { target *-*-* } 12 }
|
||||||
|
END TYPE TWindowData
|
||||||
|
END MODULE WinData
|
||||||
|
|
||||||
|
! { dg-final { cleanup-modules "WinData" } }
|
15
gcc/testsuite/gfortran.dg/array_constructor_27.f03
Normal file
15
gcc/testsuite/gfortran.dg/array_constructor_27.f03
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
! { dg-do compile }
|
||||||
|
|
||||||
|
! PR fortran/36492
|
||||||
|
! Check for incorrect error message with -std=f2003.
|
||||||
|
! Reduced test triggering the ICE mentioned in comment #4, PR 36492.
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
type t
|
||||||
|
character (a) :: arr (1) = [ "a" ]
|
||||||
|
! { dg-error "no IMPLICIT type" "" { target *-*-* } 10 }
|
||||||
|
! { dg-error "specification expression" "" { target *-*-* } 10 }
|
||||||
|
end type t
|
||||||
|
|
||||||
|
end
|
11
gcc/testsuite/gfortran.dg/array_constructor_28.f03
Normal file
11
gcc/testsuite/gfortran.dg/array_constructor_28.f03
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
! { dg-do compile }
|
||||||
|
! { dg-options "-std=f2003" }
|
||||||
|
|
||||||
|
! PR fortran/36492
|
||||||
|
! Check that the error is still emitted for really incorrect constructor.
|
||||||
|
|
||||||
|
type t
|
||||||
|
character (2) :: arr (2) = [ "a", "ab" ] ! { dg-error "Different CHARACTER" }
|
||||||
|
end type t
|
||||||
|
|
||||||
|
end
|
13
gcc/testsuite/gfortran.dg/array_constructor_29.f03
Normal file
13
gcc/testsuite/gfortran.dg/array_constructor_29.f03
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
! { dg-do compile }
|
||||||
|
|
||||||
|
! PR fortran/36492
|
||||||
|
! Similar to the ICE-test, but now test it works for real constants.
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer, parameter :: a = 42
|
||||||
|
type t
|
||||||
|
character (a) :: arr (1) = [ "a" ]
|
||||||
|
end type t
|
||||||
|
|
||||||
|
end
|
16
gcc/testsuite/gfortran.dg/array_constructor_30.f03
Normal file
16
gcc/testsuite/gfortran.dg/array_constructor_30.f03
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
! { dg-do compile }
|
||||||
|
|
||||||
|
! PR fortran/36492
|
||||||
|
! Similar to the ICE-test, but now test for complaint about constant
|
||||||
|
! specification expression.
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer :: a = 42
|
||||||
|
type t
|
||||||
|
character (a) :: arr (1) = [ "a" ]
|
||||||
|
! { dg-error "in the expression" "" { target *-*-* } 11 }
|
||||||
|
! { dg-error "specification expression" "" { target *-*-* } 11 }
|
||||||
|
end type t
|
||||||
|
|
||||||
|
end
|
9
gcc/testsuite/gfortran.dg/array_constructor_type_19.f03
Normal file
9
gcc/testsuite/gfortran.dg/array_constructor_type_19.f03
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
! { dg-do compile }
|
||||||
|
! { dg-options "-std=f2003" }
|
||||||
|
|
||||||
|
! PR fortran/36517
|
||||||
|
! Check for incorrect error message with -std=f2003.
|
||||||
|
! This is the test of comment #1, PR 36517.
|
||||||
|
|
||||||
|
print *, [ character(len=2) :: 'a', 'bb' ]
|
||||||
|
end
|
11
gcc/testsuite/gfortran.dg/array_constructor_type_20.f03
Normal file
11
gcc/testsuite/gfortran.dg/array_constructor_type_20.f03
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
! { dg-do compile }
|
||||||
|
! { dg-options "-std=f2003" }
|
||||||
|
|
||||||
|
! PR fortran/36517
|
||||||
|
! Check for incorrect error message with -std=f2003.
|
||||||
|
! This is the original test from PR 36517.
|
||||||
|
|
||||||
|
CHARACTER (len=*) MY_STRING(1:3)
|
||||||
|
PARAMETER ( MY_STRING = (/ CHARACTER (len=3) :: "AC", "B", "C" /) )
|
||||||
|
CHARACTER (len=*), PARAMETER :: str(2) = [ CHARACTER (len=3) :: 'A', 'cc' ]
|
||||||
|
END
|
11
gcc/testsuite/gfortran.dg/array_constructor_type_21.f03
Normal file
11
gcc/testsuite/gfortran.dg/array_constructor_type_21.f03
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
! { dg-do compile }
|
||||||
|
! { dg-options "-std=f2003" }
|
||||||
|
|
||||||
|
! PR fortran/36492
|
||||||
|
! Check that it works with a typespec even for not-the-same-length elements.
|
||||||
|
|
||||||
|
type t
|
||||||
|
character (1) :: arr (2) = [ character(len=2) :: "a", "ab" ]
|
||||||
|
end type t
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user