Bug 31821 - character pointer => target(range) should detect if lengths don't match
Summary: character pointer => target(range) should detect if lengths don't match
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Thomas Koenig
URL:
Keywords: accepts-invalid
Depends on:
Blocks: Fortran_character
  Show dependency treegraph
 
Reported: 2007-05-04 20:10 UTC by Tobias Burnus
Modified: 2010-12-24 08:44 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-05-25 05:38:53


Attachments
patch which causes regressions (1.72 KB, patch)
2010-12-12 13:58 UTC, Thomas Koenig
Details | Diff
As far as I got... (1.72 KB, patch)
2010-12-13 20:29 UTC, Thomas Koenig
Details | Diff
Patch that has a good chance of working (959 bytes, patch)
2010-12-21 22:11 UTC, Thomas Koenig
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2007-05-04 20:10:57 UTC
character (len=4), s1
  character (len=20), pointer :: p1
  s1 = 'abcd'
  p1 => s1(2:3)

should be rejected at compile time as len(s1(2:3)) == 2 but p1 has the length 20.

This is not detected because primary.c's match_varspec contains:

        if (substring)
            primary->ts.cl = NULL;

If one removes this check, the proper error:
   Error: Different character lengths in pointer assignment at (1)
is shown. The solution is to resolve ts.cl->length for substrings if possible and only set it to NULL if it is not known at compile time.
Comment 1 Jerry DeLisle 2007-05-04 20:43:23 UTC
This looks suspiciously like the problem we are hunting down in pr31197.  Can you have a look and see if its related, if not the same bug?
Comment 2 Tobias Burnus 2007-05-04 22:14:23 UTC
See also: http://gcc.gnu.org/ml/fortran/2007-05/msg00072.html

One also needs a run-time test for:

    character (len=4), target :: s1
    character (len=2), pointer :: p1
    s1 = 'abcd'
    p1 => s1(1:2)
    if(s1 /= 'abcd') call abort()
    if(p1 /= 'ab')   call abort()
  end

There might be already such a check, though.
Comment 3 Paul Thomas 2007-05-25 05:38:53 UTC
There seems to be a consensus on this - confirmed.

Paul
Comment 4 Thomas Koenig 2010-12-11 09:46:57 UTC
The error message is wrong if the

        if (substring)
            primary->ts.cl = NULL;

part is removed:

ig25@linux-fd1f:~/Krempel/Char> cat aa.f90
  character (len=4), pointer:: s1
  character (len=20), pointer :: p1
  s1 = 'abcd'
  p1 => s1(2:3)
end
ig25@linux-fd1f:~/Krempel/Char> gfortran aa.f90
aa.f90:4.2:

  p1 => s1(2:3)
  1
Fehler: Unequal character lengths (20/4) in pointer assignment at (1)

The length of the substring is wrongly taken to be 4, instead of 2.
Comment 5 Thomas Koenig 2010-12-11 12:38:01 UTC
gfc_check_same_strlen does not check for references.

Ouch.
Comment 6 Thomas Koenig 2010-12-11 13:25:16 UTC
Working on a patch.
Comment 7 Thomas Koenig 2010-12-12 13:58:15 UTC
Created attachment 22724 [details]
patch which causes regressions
Comment 8 Thomas Koenig 2010-12-12 14:09:12 UTC
The patch in comment#7 causes a regression in

program gfcbug33
  character(12) :: a(2)
  a(1) = "abcdefghijkl"
  a(2) = "mnopqrstuvwx"
  call foo ((a(2:1:-1)(6:)))
contains
  subroutine foo (chr)
    character(7) :: chr(:)
    print *,'X',chr(1),'Y'
    print *,'A',chr(2),'B'
    if (chr(1)//chr(2) .ne. "rstuvwxfghijkl") call abort ()
  end subroutine foo
end program gfcbug33
ig25@linux-fd1f:~/Krempel/Char> gfortran short_1.f90
ig25@linux-fd1f:~/Krempel/Char> ./a.out
 XrstuvwxY
 A%�2�fgB
Abgebrochen

which is a shortened version of actual_array_substr_1.f90.

The part of the patch

-         if (substring)
-           primary->ts.u.cl = NULL;
-

opens a can of worms of wrong-code and rejects-valid bugs...
Comment 9 Thomas Koenig 2010-12-13 20:29:03 UTC
Created attachment 22746 [details]
As far as I got...

This is as far as I got.  Offsets are still calculated wrongly,
but without a clue as to where to start looking, I think I'll
give up for now.
Comment 10 Thomas Koenig 2010-12-21 22:11:30 UTC
Created attachment 22838 [details]
Patch that has a good chance of working

(In reply to comment #8)
>
> The part of the patch
> 
> -         if (substring)
> -           primary->ts.u.cl = NULL;
> -
>

is part of the precipitate.  This should be better.
Comment 11 Thomas Koenig 2010-12-24 08:42:07 UTC
Author: tkoenig
Date: Fri Dec 24 08:42:04 2010
New Revision: 168224

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168224
Log:
2010-12-24  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/31821
	* check.c (gfc_var_strlen):  New function, also including
	substring references.
	(gfc_check_same_strlen):  Use gfc_var_strlen.

2010-12-24  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/31821
	* gfortran.dg/char_pointer_assign_6.f90:  New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/char_pointer_assign_6.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/check.c
    trunk/gcc/testsuite/ChangeLog
Comment 12 Thomas Koenig 2010-12-24 08:44:24 UTC
Fixed, closing.