See also PR 45170 comment 9 - and the examples in PR fortran/51550, PR fortran/47545, PR fortran/49050 and PR fortran/51075. Currently, using type t character(len=:), allocatable :: str_comp end type t is not supported and is rejected by a not-yet-supported error. TODO: There needs to be a hidden (integer) component, which stores the string length.
*** Bug 51075 has been marked as a duplicate of this bug. ***
*** Bug 49050 has been marked as a duplicate of this bug. ***
*** Bug 51550 has been marked as a duplicate of this bug. ***
*** Bug 47545 has been marked as a duplicate of this bug. ***
*** Bug 51394 has been marked as a duplicate of this bug. ***
Note that after this feature works, we have to ensure that FORALL with a generated temporary works with different string lengths: type t character(len=:), pointer :: str end type t type(t), pointer :: strarry(:), strarray2 allocate(strarray(3), strarray2) allocate(character(len=5) :: strarray(1)%str, strarray2(1)%str) allocate(character(len=7) :: strarray(2)%str, strarray2(2)%str) allocate(character(len=2) :: strarray(2)%str, strarray2(3)%str) forall(i=1:3) strarray2(i)%str = strarray(i)%str
Created attachment 29406 [details] Draft patch for the PR This turned out to be easier than I expected. It obviously needs a bit of cleaning up; deferred character length variables should be made consistent with their variable cousins. This will not take much doing and I expect to submit the patch tomorrow. Bootstraps and regtests on trunk. Proto-testcase: type t character(len=:), allocatable :: str_comp end type t type(t) :: x allocate (x%str_comp, source = "abc") print *, len (x%str_comp), x%str_comp deallocate (x%str_comp) allocate (x%str_comp, source = "abcdefghijklmnop") print *, len (x%str_comp), x%str_comp x%str_comp = "xyz" print *, len (x%str_comp), x%str_comp x%str_comp = "abcdefghijklmnop" call foo (x%str_comp) contains subroutine foo (chr) character (*) :: chr print *, len (chr), chr end subroutine end Cheers Paul
With the patch in comment #7 most of the duplicates compile and run, but: pr49050 which gives pr49050.f90:13.10: item = item_type('key') 1 Error: No initializer for component '_key' given in the structure constructor at (1)! (note that the original code at http://gcc.gnu.org/ml/fortran/2011-05/msg00129.html compiles but segfault at runtime); pr51550 which gives an ICE gimplification failed: 0 <integer_cst 0x14280bc80 type <integer_type 0x1428125e8 integer(kind=4)> constant 0> pr51550.f90: In function 'add_key_only': pr51550.f90:64:0: internal compiler error: gimplification failed allocate( character(len=len(key)) :: value%key ) ^ and a similar error for the test in comment #6 type t character(len=:), pointer :: str end type t type(t), pointer :: strarray(:), strarray2(:) allocate(strarray(3), strarray2(3)) allocate(character(len=5) :: strarray(1)%str, strarray2(1)%str) allocate(character(len=7) :: strarray(2)%str, strarray2(2)%str) allocate(character(len=2) :: strarray(2)%str, strarray2(3)%str) ! forall(i=1:3) strarray2(i)%str = strarray(i)%str print *, (len(strarray2(i)%str), i=1,3) end gimplification failed: 0 <integer_cst 0x14280bc80 type <integer_type 0x1428125e8 integer(kind=4)> constant 0> pr51976_1.f90: In function 'MAIN__': pr51976_1.f90:7:0: internal compiler error: gimplification failed allocate(character(len=5) :: strarray(1)%str, strarray2(1)%str) ^ If the FORALL is uncommented, the ICE is pr51976_1.f90: In function 'MAIN__': pr51976_1.f90:11:0: internal compiler error: in gfc_add_modify_loc, at fortran/trans.c:159 forall(i=1:3) strarray2(i)%str = strarray(i)%str ^ At runtime the test attached to pr48654 gives a segmentation fault (fixed by the revised patch sent privately). The iso_varying_string I have in store also compiles and run (limited testing).
Latest patch: http://gcc.gnu.org/ml/fortran/2013-02/msg00136.html
FYI: Ian Hardy has some fancy examples uses character(:) in DT at the bottom of the thread http://software.intel.com/en-us/forums/topic/326077 (attached files)
Another example fancy example: ftp://ftp.numerical.rl.ac.uk/pub/MRandC/oo.f90 From https://groups.google.com/forum/?fromgroups#!topic/comp.lang.fortran/aRz3HMpblTs
Adding myself (Walter Spector) to the cc list. My contribution is a simple little test case that works with current versions of Intel (with -assume realloc_lhs option) and NAG. As of todays gfortran snapshot (20130828), I get a lot of 'Deferred-length character component 'city' at (1) is not yet supported' errors. program city_names implicit none type city_entry_t character(:), allocatable :: city character(:), allocatable :: state end type type(city_entry_t), allocatable :: cities(:) integer :: i cities = (/ & city_entry_t ("San Francisco", "California"), & city_entry_t ("Portland", "Oregon"), & city_entry_t ("Seattle", "Washington"), & city_entry_t ("Salt Lake City", "Utah"), & city_entry_t ("Reno", "Nevada"), & city_entry_t ("Tucson", "Arizona"), & city_entry_t ("Denver", "Colorado"), & city_entry_t ("Kansas City","Kansas"), & city_entry_t ("Tulsa", "Oklahoma"), & city_entry_t ("Houston", "Texas") & /) print '(5a)', (">",cities(i)%city, ", ", cities(i)%state,"<", i=1,size (cities)) end program
The latest patch posted at http://gcc.gnu.org/ml/fortran/2014-02/msg00109.html works smoothly on the test case in comment 12.
Hi all, > I think it went as follows: We found out that some code doesn't - in > particular code which uses array-valued deferred-length characters. > After trying to fix it, you (Paul) decided that the simplest way to fix > it would be the new array descriptor - and then it got stuck. A list of known problems can be found at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51976#c8 > Regarding this patch, I have mixed feelings. I think it is a much wished > feature - but I am not sure about the stability of the patch and it is > rather large, given that we are in stage 4. I have the patch in my working tree since more than a year without any related problem. Indeed I had to practice minor surgery to keep it alive. AFAICT the changes are quite localized and I don't expect any major problem if it is committed. > Regarding the new array descriptor: I think it would be useful if we > could get the new descriptor working early in the GCC 4.10/5.0/2015 > development stage. I think the main large task is to convert all all > remaining stride-based code to stride-multiplier code without breaking > vectorization and causing other regressions. Additionally, it would be > nice to get rid of "offset" - and have in the descriptor always an > lower_bound of 0, except for pointers/allocatables (cf. TS29113). I > think the version on the branch is in a relatively good shape; however, > the stride and offset changes seem to be of such a kind that one needs to > modify several code locations simultaneously - otherwise, it will break > badly. Additionally, all remaining regressions have to be fixed. When > that's done, adding some extra field is all what's needed. (As follow > up, enough remains to be done: I'd like to use it for all class(*), > possibly even for nonarray class(type), assumed-rank needs an update, > assumed-shape/-rank/deferred-shape character arrays also have to be > adapted (also mandated by TS29113 for interop). And we should do an ABI > cleanup in libgfortran as we have now the chance to break the ABI.) - Is > anyone volunteering? I think the new array descriptor should be given the highest priority and fortran-dev merged to trunk as soon as the last regression is fixed. My tests show that its present state is quite close (note regtesting should be done for both -m32 and -m64: some scanning tests fail with -m32). Cheers, Dominique
Author: janus Date: Thu Mar 6 21:45:31 2014 New Revision: 208386 URL: http://gcc.gnu.org/viewcvs?rev=208386&root=gcc&view=rev Log: 2014-03-06 Paul Thomas <pault@gcc.gnu.org> Janus Weil <janus@gcc.gnu.org> PR fortran/51976 * gfortran.h (symbol_attribute): Add deferred_parameter attribute. * primary.c (build_actual_constructor): It is not an error if a missing component has the deferred_parameter attribute; equally, if one is given a value, it is an error. * resolve.c (resolve_fl_derived0): Remove error for deferred character length components. Add the hidden string length field to the structure. Give it the deferred_parameter attribute. * trans-array.c (duplicate_allocatable): Add a strlen field which is used as the element size if it is non-null. (gfc_duplicate_allocatable, gfc_copy_allocatable_data): Pass a NULL to the new argument in duplicate_allocatable. (structure_alloc_comps): Set the hidden string length as appropriate. Use it in calls to duplicate_allocatable. (gfc_alloc_allocatable_for_assignment): When a deferred length backend declaration is variable, use that; otherwise use the string length from the expression evaluation. * trans-expr.c (gfc_conv_component_ref): If this is a deferred character length component, the string length should have the value of the hidden string length field. (gfc_trans_subcomponent_assign): Set the hidden string length field for deferred character length components. Allocate the necessary memory for the string. (alloc_scalar_allocatable_for_assignment): Same change as in gfc_alloc_allocatable_for_assignment above. * trans-stmt.c (gfc_trans_allocate): Likewise. * trans-intrinsic (size_of_string_in_bytes): Make non-static. * trans-types.c (gfc_get_derived_type): Set the tree type for a deferred character length component. * trans.c (gfc_deferred_strlen): New function. * trans.h (size_of_string_in_bytes,gfc_deferred_strlen): New prototypes. 2014-03-06 Paul Thomas <pault@gcc.gnu.org> Janus Weil <janus@gcc.gnu.org> PR fortran/51976 * gfortran.dg/deferred_type_component_1.f90 : New test. * gfortran.dg/deferred_type_component_2.f90 : New test. Added: trunk/gcc/testsuite/gfortran.dg/deferred_type_component_1.f90 trunk/gcc/testsuite/gfortran.dg/deferred_type_component_2.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/gfortran.h trunk/gcc/fortran/primary.c trunk/gcc/fortran/resolve.c trunk/gcc/fortran/trans-array.c trunk/gcc/fortran/trans-expr.c trunk/gcc/fortran/trans-intrinsic.c trunk/gcc/fortran/trans-stmt.c trunk/gcc/fortran/trans-types.c trunk/gcc/fortran/trans.c trunk/gcc/fortran/trans.h trunk/gcc/testsuite/ChangeLog
subroutine foo () type dt character(len=:), allocatable :: o character(len=:), allocatable :: n(:) end type type (dt) :: d logical :: l integer :: n n = 4 allocate(character(len=n+1) :: d%o) allocate(character(len=n+2) :: d%n(4)) end seems to ICE during gimplification (there is 0 = 4; stmt in *.original), and the length of d%n allocation is weird too. subroutine bar () character(len=:), allocatable :: o, o2 character(len=:), allocatable :: n(:), n2(:) allocate(character(len=4) :: o, n(10)) o2 = o n2 = n end ICEs too.
I think the last issues in comment 16 can be tracked by pr54070 and this PR closed as FIXED.
> I think the last issues in comment 16 can be tracked by pr54070 and > this PR closed as FIXED. No answer since more than a year and a half. Closing as FIXED. Please open new PRs for new issues.