public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Tobias Burnus <burnus@net-b.de>
To: fortran@gcc.gnu.org
Subject: [Patch, Fortran] PR fortran/83522 – reject array-valued substrings
Date: Mon, 08 Oct 2018 19:45:00 -0000	[thread overview]
Message-ID: <c0ed507e-bf17-ea71-6715-906c10ee054d@net-b.de> (raw)

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

Hi all,

as the PR (and the attached testcase) shows, gfortran doesn't handle 
noncontiguous access with substrings. Namely, "str_array(:)(1:5)" is 
mishandled (segfault while building the "tree" as expr == NULL).

As Jerry has dug up in the standard (F2008, R610 alias F2018, R908), 
substrings are only permitted on scalars (or array elements). – 
[gfortran has some partial support for noncontiguous memory as actual 
argument the now rejected test cases show.]

In words of the standard (here: F2018):

9.4.1  Substrings

A substring is a contiguous portion of a character string (7.4.4).

R908   substring   is   parent-string  ( substring-range )

R909   parent-string
             is   scalar-variable-name
             or  array-element
             or  coindexed-named-object
             or  scalar-structure-component
             or  scalar-constant

The patch adds a check to the variable resolving – it comes too late to 
print a nice error message for "string(:)(:)"; that statement gets 
matched unsuccessfully and at the end the buffered error message of 
match_variable (unexpected character "(") gets printed. – One could 
reject it earlier but the code doesn't seem to be that nice. (See PR for 
a variant.)

Build and regtested on x86_64-linux.
OK for the trunk?

Cheers

Tobias


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: array_substring.diff --]
[-- Type: text/x-patch; name="array_substring.diff", Size: 4992 bytes --]

2018-10-08  Tobias Burnus <burnus@net-b.de>

	PR fortran/83522
	* resolve.c (resolve_ref): Reject nonscalar
	substring references.

        PR fortran/83522
	* gfortran.dg/actual_array_substr_1.f90: Add dg-error,
	change to dg-do compile.
	* gfortran.dg/actual_array_substr_2.f90: Ditto.
	* gfortran.dg/array_initializer_1.f90: Use array
	element not size-one section.
	* gfortran.dg/array_substring.f90: New.

diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 87e65df5f4e..4ec881e5d78 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5129,6 +5129,13 @@ resolve_ref (gfc_expr *expr)
 	  break;
 
 	case REF_SUBSTRING:
+	  /* F2008, R610 alias F2018, R908.  */
+	  if (current_part_dimension || seen_part_dimension)
+	    {
+	      gfc_error ("Substring reference of nonscalar not permitted at %L",
+			 &expr->where);
+	      return false;
+	    }
 	  break;
 	}
 
diff --git a/gcc/testsuite/gfortran.dg/actual_array_substr_1.f90 b/gcc/testsuite/gfortran.dg/actual_array_substr_1.f90
index 7c10c7020eb..d992f45f465 100644
--- a/gcc/testsuite/gfortran.dg/actual_array_substr_1.f90
+++ b/gcc/testsuite/gfortran.dg/actual_array_substr_1.f90
@@ -1,15 +1,17 @@
-! { dg-do run }
+! { dg-do compile }
 ! Test fix of PR28118, in which a substring reference to an
 ! actual argument with an array reference would cause a segfault.
 !
+! Revised for PR fortran/83522
+!
 ! Contributed by Paul Thomas  <pault@gcc.gnu.org>
 !
 program gfcbug33
   character(12) :: a(2)
   a(1) = "abcdefghijkl"
   a(2) = "mnopqrstuvwx"
-  call foo ((a(2:1:-1)(6:)))
-  call bar ((a(:)(7:11)))
+  call foo ((a(2:1:-1)(6:))) ! { dg-error "Substring reference of nonscalar not permitted" }
+  call bar ((a(:)(7:11))) ! { dg-error "Substring reference of nonscalar not permitted" }
 contains
   subroutine foo (chr)
     character(7) :: chr(:)
diff --git a/gcc/testsuite/gfortran.dg/actual_array_substr_2.f90 b/gcc/testsuite/gfortran.dg/actual_array_substr_2.f90
index fed51342ee0..9bcd19c3fb0 100644
--- a/gcc/testsuite/gfortran.dg/actual_array_substr_2.f90
+++ b/gcc/testsuite/gfortran.dg/actual_array_substr_2.f90
@@ -1,10 +1,12 @@
-! { dg-do run }
+! { dg-do compile }
 ! Tests the fix for pr28174, in which the fix for pr28118 was
 ! corrupting the character lengths of arrays that shared a
 ! character length structure.  In addition, in developing the
 ! fix, it was noted that intent(out/inout) arguments were not
 ! getting written back to the calling scope.
 !
+! Revised for PR fortran/83522
+!
 ! Based on the testscase by Harald Anlauf  <anlauf@gmx.de>
 !
 program pr28174
@@ -20,7 +22,7 @@ program pr28174
   n = m - 4
 
 ! Make sure that variable substring references work.
-  call foo (a(:)(m:m+5), c(:)(n:m+2), d(:)(5:9))
+  call foo (a(:)(m:m+5), c(:)(n:m+2), d(:)(5:9)) ! { dg-error "Substring reference of nonscalar not permitted" }
   if (any (a .ne. teststring)) STOP 1
   if (any (b .ne. teststring)) STOP 2
   if (any (c .ne. (/"ab456789#hij", &
@@ -37,8 +39,7 @@ contains
 ! This next is not required by the standard but tests the
 ! functioning of the gfortran implementation.
 !   if (all (x(:)(3:7) .eq. y)) STOP 5
-    x = foostring (:)(5 : 4 + len (x))
-    y = foostring (:)(3 : 2 + len (y))
+    x = foostring (:)(5 : 4 + len (x)) ! { dg-error "Substring reference of nonscalar not permitted" }
+    y = foostring (:)(3 : 2 + len (y)) ! { dg-error "Substring reference of nonscalar not permitted" }
   end subroutine foo
 end program pr28174
-
diff --git a/gcc/testsuite/gfortran.dg/array_initializer_1.f90 b/gcc/testsuite/gfortran.dg/array_initializer_1.f90
index d4f5e940c10..28c9272f3ac 100644
--- a/gcc/testsuite/gfortran.dg/array_initializer_1.f90
+++ b/gcc/testsuite/gfortran.dg/array_initializer_1.f90
@@ -18,7 +18,7 @@
 
   character(4), parameter :: chr(4) = (/"abcd", "efgh", "ijkl", "mnop"/)
   character(4), parameter :: chrs = chr(ii)(2:3)//chr(2)(ii-3:ii-2) 
-  character(4), parameter :: chrt(2) = (/chr(2:2)(2:3), chr(ii-1)(3:ii)/)
+  character(4), parameter :: chrt(2) = (/chr(2)(2:3), chr(ii-1)(3:ii)/)
   character(2), parameter :: chrx(2) = (/(chr(i)(i:i+1), i=2,3)/)
 
   if (any (y .ne. (/5., 6., 15., 16./))) STOP 1
diff --git a/gcc/testsuite/gfortran.dg/array_substring.f90 b/gcc/testsuite/gfortran.dg/array_substring.f90
new file mode 100644
index 00000000000..ea80556cfc1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_substring.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+!
+! PR fortran/83522
+!
+! Contributed by urbanjost and Jerry DeLisle
+!
+program testit
+  character(len=:),allocatable :: strings(:)
+  integer :: i
+  strings=[character(len=2) :: 'AA','BB']
+  write(*,*)strings(:)(:)  ! { dg-error "Substring reference of nonscalar not permitted" }
+  !strings(:)(:) ! Parse error: "Invalid character in name"
+  strings(:)(:) = 'x'   ! { dg-error "Substring reference of nonscalar not permitted" }
+  do i=1, size(strings)
+    write(*,*)strings(i)(:)  ! This is valid and works
+  end do
+end program testit

             reply	other threads:[~2018-10-08 19:45 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-08 19:45 Tobias Burnus [this message]
2018-10-08 22:15 ` Thomas Koenig
2018-10-10 23:12   ` Paul Richard Thomas
2018-10-11 13:56     ` David Edelsohn
2018-10-11 14:20     ` David Edelsohn
2018-10-11 14:39       ` Paul Richard Thomas
2018-10-11 10:46 ` Jakub Jelinek
2018-10-11 19:37   ` Tobias Burnus
2018-10-11 19:40     ` Paul Richard Thomas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c0ed507e-bf17-ea71-6715-906c10ee054d@net-b.de \
    --to=burnus@net-b.de \
    --cc=fortran@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).