public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR fortran/99205 - [10/11 Regression] Out of memory with undefined character length
@ 2021-03-09 19:45 Harald Anlauf
  2021-03-10 10:06 ` Tobias Burnus
  0 siblings, 1 reply; 6+ messages in thread
From: Harald Anlauf @ 2021-03-09 19:45 UTC (permalink / raw)
  To: fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 604 bytes --]

Dear all,

character variables with undefined length are not allowed as
objects in DATA statements.  We better reject them.

Regtested on x86_64-pc-linux-gnu.  OK for master / backport?

Thanks,
Harald


PR fortran/99205 - Out of memory with undefined character length

A variable that is a data statement object shall be a designator,
thus a character variable shall have a constant length.

gcc/fortran/ChangeLog:

	PR fortran/99205
	* data.c (gfc_assign_data_value): Reject non-constant character
	length for lvalue.

gcc/testsuite/ChangeLog:

	PR fortran/99205
	* gfortran.dg/pr99205.f90: New test.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: pr99205.patch --]
[-- Type: text/x-patch, Size: 1165 bytes --]

diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
index 25e97930169..71e2552025d 100644
--- a/gcc/fortran/data.c
+++ b/gcc/fortran/data.c
@@ -595,6 +595,9 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index,
       /* An initializer has to be constant.  */
       if (lvalue->ts.u.cl->length == NULL && !(ref && ref->u.ss.length != NULL))
 	return false;
+      if (lvalue->ts.u.cl->length
+	  && lvalue->ts.u.cl->length->expr_type != EXPR_CONSTANT)
+	return false;
       expr = create_character_initializer (init, last_ts, ref, rvalue);
       if (!expr)
 	return false;
diff --git a/gcc/testsuite/gfortran.dg/pr99205.f90 b/gcc/testsuite/gfortran.dg/pr99205.f90
new file mode 100644
index 00000000000..ed0782ce8a0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr99205.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! PR fortran/99205 - Out of memory with undefined character length
+! { dg-options "-w" }
+
+program p
+  character(l) :: c(2) ! { dg-error "must have constant character length" }
+  data c /'a', 'b'/
+  common c
+end
+
+! { dg-error "cannot appear in the expression at" " " { target *-*-* } 6 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] PR fortran/99205 - [10/11 Regression] Out of memory with undefined character length
  2021-03-09 19:45 [PATCH] PR fortran/99205 - [10/11 Regression] Out of memory with undefined character length Harald Anlauf
@ 2021-03-10 10:06 ` Tobias Burnus
  2021-03-10 19:43   ` Harald Anlauf
  2021-03-10 21:26   ` Harald Anlauf
  0 siblings, 2 replies; 6+ messages in thread
From: Tobias Burnus @ 2021-03-10 10:06 UTC (permalink / raw)
  To: Harald Anlauf, fortran, gcc-patches

Dear Harald, dear all,

On 09.03.21 20:45, Harald Anlauf via Fortran wrote:
> character variables with undefined length are not allowed as
> objects in DATA statements.  We better reject them.
>
> Regtested on x86_64-pc-linux-gnu.  OK for master / backport?
>
> PR fortran/99205 - Out of memory with undefined character length
>
> A variable that is a data statement object shall be a designator,
> thus a character variable shall have a constant length.

This comment is wrong: A designator does not imply this – nor is
F2018:C875 violated, not even the substring starting/ending point
const expr bit.


The reason that it is not permitted is the "automatic data object"
(see *...* highlighted parts in the quote):

C876   (R839) A *variable* whose *designator* appears as a
*data-stmt-object* or a data-i-do-object hall not be a
dummy argument, accessed by use or host association,
in a named common block unless the DATA statement is
in a block data program unit, in blank common, a function name,
a function result name, an *automatic* *data* *object,*
or an allocatable variable.

With the definition: "3.11 automatic data object
nondummy data object with a type parameter or array bound that
depends on the value of aspecification-expr that is not
a constant expression (8.3)"


In the following variant of the program, the invalid
variable declaration of 'c' itself is avoided by using
a block:

integer :: ll
ll = 4
block
   character(ll) :: c(2), cc(2)
   character(ll) :: c2(2), cc2(2)
   data c /'a', 'b'/
   data c2(:)(1:1) /'a', 'b'/
   common /block/ cc, cc2
end block
end

You may consider to update your testcase or to
augment your testcase.

The patch itself is OK, but you really need to
update the commit description.

Tobias

>
> gcc/fortran/ChangeLog:
>
>       PR fortran/99205
>       * data.c (gfc_assign_data_value): Reject non-constant character
>       length for lvalue.
>
> gcc/testsuite/ChangeLog:
>
>       PR fortran/99205
>       * gfortran.dg/pr99205.f90: New test.
>
>
> pr99205.patch
>
> diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
> index 25e97930169..71e2552025d 100644
> --- a/gcc/fortran/data.c
> +++ b/gcc/fortran/data.c
> @@ -595,6 +595,9 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index,
>         /* An initializer has to be constant.  */
>         if (lvalue->ts.u.cl->length == NULL && !(ref && ref->u.ss.length != NULL))
>       return false;
> +      if (lvalue->ts.u.cl->length
> +       && lvalue->ts.u.cl->length->expr_type != EXPR_CONSTANT)
> +     return false;
>         expr = create_character_initializer (init, last_ts, ref, rvalue);
>         if (!expr)
>       return false;
> diff --git a/gcc/testsuite/gfortran.dg/pr99205.f90 b/gcc/testsuite/gfortran.dg/pr99205.f90
> new file mode 100644
> index 00000000000..ed0782ce8a0
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/pr99205.f90
> @@ -0,0 +1,11 @@
> +! { dg-do compile }
> +! PR fortran/99205 - Out of memory with undefined character length
> +! { dg-options "-w" }
> +
> +program p
> +  character(l) :: c(2) ! { dg-error "must have constant character length" }
> +  data c /'a', 'b'/
> +  common c
> +end
> +
> +! { dg-error "cannot appear in the expression at" " " { target *-*-* } 6 }
-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank Thürauf

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] PR fortran/99205 - [10/11 Regression] Out of memory with undefined character length
  2021-03-10 10:06 ` Tobias Burnus
@ 2021-03-10 19:43   ` Harald Anlauf
  2021-03-10 20:18     ` Tobias Burnus
  2021-03-10 21:26   ` Harald Anlauf
  1 sibling, 1 reply; 6+ messages in thread
From: Harald Anlauf @ 2021-03-10 19:43 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: fortran, gcc-patches

Dear Tobias,

thanks for your comments.

> > A variable that is a data statement object shall be a designator,
> > thus a character variable shall have a constant length.
> 
> This comment is wrong: A designator does not imply this – nor is
> F2018:C875 violated, not even the substring starting/ending point
> const expr bit.

OK, I will think of a better wording.

> In the following variant of the program, the invalid
> variable declaration of 'c' itself is avoided by using
> a block:
> 
> integer :: ll
> ll = 4
> block
>    character(ll) :: c(2), cc(2)
>    character(ll) :: c2(2), cc2(2)
>    data c /'a', 'b'/
>    data c2(:)(1:1) /'a', 'b'/
>    common /block/ cc, cc2
> end block
> end

No, this example is invalid, see

C1107(R1107) A block-specification-part shall not contain a COMMON, EQUIVALENCE, INTENT, NAMELIST,
OPTIONAL, statement function, or VALUE statement.

Harald


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] PR fortran/99205 - [10/11 Regression] Out of memory with undefined character length
  2021-03-10 19:43   ` Harald Anlauf
@ 2021-03-10 20:18     ` Tobias Burnus
  0 siblings, 0 replies; 6+ messages in thread
From: Tobias Burnus @ 2021-03-10 20:18 UTC (permalink / raw)
  To: Harald Anlauf; +Cc: fortran, gcc-patches

Dear Harald,

On 10.03.21 20:43, Harald Anlauf wrote:
>> In the following variant of the program, the invalid
>> variable declaration of 'c' itself is avoided by using
>> a block:
>>
>> integer :: ll
>> ll = 4
>> block
>>     character(ll) :: c(2), cc(2)
>>     character(ll) :: c2(2), cc2(2)
>>     data c /'a', 'b'/
>>     data c2(:)(1:1) /'a', 'b'/
>>     common /block/ cc, cc2
>> end block
>> end
> No, this example is invalid

Of course this example is invalid – I only wrote that it avoids the
issues with the declaration of 'C' itself not that the code as a whole
is valid.

Regarding:

> C1107(R1107) A block-specification-part shall not contain a COMMON, EQUIVALENCE, INTENT, NAMELIST,
> OPTIONAL, statement function, or VALUE statement.

That could be mended by removing the 'common' line. Especially as I
forgot to actually use 'cc'/'cc2' in a data statement ... Or by using a
host-associated 'll' instead of a block. But that still will have the
automatic issue for common, hence, removing common is probably best. One
the other hand:

In any case, there are hundreds of ways to write invalid code – chose
one you like for the testcase :-)

Thanks for this patch – and all the belated patch work!

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank Thürauf

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] PR fortran/99205 - [10/11 Regression] Out of memory with undefined character length
  2021-03-10 10:06 ` Tobias Burnus
  2021-03-10 19:43   ` Harald Anlauf
@ 2021-03-10 21:26   ` Harald Anlauf
  2021-03-10 21:52     ` Tobias Burnus
  1 sibling, 1 reply; 6+ messages in thread
From: Harald Anlauf @ 2021-03-10 21:26 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1730 bytes --]

Dear Tobias, all,

> The reason that it is not permitted is the "automatic data object"
> (see *...* highlighted parts in the quote):
>
> C876   (R839) A *variable* whose *designator* appears as a
> *data-stmt-object* or a data-i-do-object hall not be a
> dummy argument, accessed by use or host association,
> in a named common block unless the DATA statement is
> in a block data program unit, in blank common, a function name,
> a function result name, an *automatic* *data* *object,*
> or an allocatable variable.
>
> With the definition: "3.11 automatic data object
> nondummy data object with a type parameter or array bound that
> depends on the value of aspecification-expr that is not
> a constant expression (8.3)"

inspired by Tobias' (although invalid) code example I found another
testcase which lead to trouble during error recovery due to a NULL
pointer dereference.  Here's the updated changelog for the updated
patch (attached).  I also renamed the first testcase so that they
fit better to the existing scheme.

Again regtested on x86_64-pc-linux-gnu.  Now OK for mainline / 10?

Thanks,
Harald


PR fortran/99205 - Out of memory with undefined character length

A character variable appearing as a data statement object cannot
be automatic, thus it shall have constant length.

gcc/fortran/ChangeLog:

	PR fortran/99205
	* data.c (gfc_assign_data_value): Reject non-constant character
	length for lvalue.
	* trans-array.c (gfc_conv_array_initializer): Restrict loop to
	elements which are defined to avoid NULL pointer dereference.

gcc/testsuite/ChangeLog:

	PR fortran/99205
	* gfortran.dg/data_char_4.f90: New test.
	* gfortran.dg/data_char_5.f90: New test.


[-- Attachment #2: pr99205.patch-v2 --]
[-- Type: application/octet-stream, Size: 2351 bytes --]

diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
index 25e97930169..71e2552025d 100644
--- a/gcc/fortran/data.c
+++ b/gcc/fortran/data.c
@@ -595,6 +595,9 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index,
       /* An initializer has to be constant.  */
       if (lvalue->ts.u.cl->length == NULL && !(ref && ref->u.ss.length != NULL))
 	return false;
+      if (lvalue->ts.u.cl->length
+	  && lvalue->ts.u.cl->length->expr_type != EXPR_CONSTANT)
+	return false;
       expr = create_character_initializer (init, last_ts, ref, rvalue);
       if (!expr)
 	return false;
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index c6725659093..478cddda070 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -6162,7 +6162,7 @@ gfc_conv_array_initializer (tree type, gfc_expr * expr)
     case EXPR_ARRAY:
       /* Create a vector of all the elements.  */
       for (c = gfc_constructor_first (expr->value.constructor);
-	   c; c = gfc_constructor_next (c))
+	   c && c->expr; c = gfc_constructor_next (c))
         {
           if (c->iterator)
             {
diff --git a/gcc/testsuite/gfortran.dg/data_char_4.f90 b/gcc/testsuite/gfortran.dg/data_char_4.f90
new file mode 100644
index 00000000000..ed0782ce8a0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/data_char_4.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! PR fortran/99205 - Out of memory with undefined character length
+! { dg-options "-w" }
+
+program p
+  character(l) :: c(2) ! { dg-error "must have constant character length" }
+  data c /'a', 'b'/
+  common c
+end
+
+! { dg-error "cannot appear in the expression at" " " { target *-*-* } 6 }
diff --git a/gcc/testsuite/gfortran.dg/data_char_5.f90 b/gcc/testsuite/gfortran.dg/data_char_5.f90
new file mode 100644
index 00000000000..ea26687e3d5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/data_char_5.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! PR fortran/99205 - Issues with non-constant character length
+
+subroutine sub ()
+  integer :: ll = 4
+  block
+    character(ll) :: c(2) ! { dg-error "non-constant" }
+    data c /'a', 'b'/
+  end block
+contains
+  subroutine sub1 ()
+    character(ll) :: d(2) ! { dg-error "non-constant" }
+    data d /'a', 'b'/
+  end subroutine sub1
+end subroutine sub

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] PR fortran/99205 - [10/11 Regression] Out of memory with undefined character length
  2021-03-10 21:26   ` Harald Anlauf
@ 2021-03-10 21:52     ` Tobias Burnus
  0 siblings, 0 replies; 6+ messages in thread
From: Tobias Burnus @ 2021-03-10 21:52 UTC (permalink / raw)
  To: Harald Anlauf, Tobias Burnus; +Cc: fortran, gcc-patches

Dear Harald, dear all,

On 10.03.21 22:26, Harald Anlauf wrote:
> [...] I found another testcase which lead to trouble during error
> recovery due to a NULL pointer dereference.

I was a bit surprised that the crash only occurs in trans*.c;
however, the error 'non-constant initialization expression'
is only issued by gfc_conv_constant, called via gfc_get_symbol_decl.

Thus, when the error is shown we are already deep in trans*.c land.

>    Here's the updated changelog for the updated
> patch (attached).  I also renamed the first testcase so that they
> fit better to the existing scheme.
>
> Again regtested on x86_64-pc-linux-gnu.  Now OK for mainline / 10?

LGTM for mainline and after a bit of waiting for GCC10.

Thanks,

Tobias

> PR fortran/99205 - Out of memory with undefined character length
>
> A character variable appearing as a data statement object cannot
> be automatic, thus it shall have constant length.
>
> gcc/fortran/ChangeLog:
>
>       PR fortran/99205
>       * data.c (gfc_assign_data_value): Reject non-constant character
>       length for lvalue.
>       * trans-array.c (gfc_conv_array_initializer): Restrict loop to
>       elements which are defined to avoid NULL pointer dereference.
>
> gcc/testsuite/ChangeLog:
>
>       PR fortran/99205
>       * gfortran.dg/data_char_4.f90: New test.
>       * gfortran.dg/data_char_5.f90: New test.
>
-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank Thürauf

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-03-10 21:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-09 19:45 [PATCH] PR fortran/99205 - [10/11 Regression] Out of memory with undefined character length Harald Anlauf
2021-03-10 10:06 ` Tobias Burnus
2021-03-10 19:43   ` Harald Anlauf
2021-03-10 20:18     ` Tobias Burnus
2021-03-10 21:26   ` Harald Anlauf
2021-03-10 21:52     ` Tobias Burnus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).