- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi.
The following code aids in illustrating the problem.
implicit none
type :: sentence
character(:), allocatable :: lower, upper
end type
type :: list
type(sentence), allocatable :: list(:)
end type
integer :: i, n = 7
type(list) :: a
character(*), parameter :: LOWER = 'abcdefghijklmnopqrstuvwxyz'
character(*), parameter :: UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
a%list = [sentence ::]
do i = 0, n
if (MOD(i, 2) == 0) then
a%list = [a%list, sentence(LOWER(:13+i), UPPER(:13-i))]
else
a%list = [a%list, sentence(LOWER(i+1:), UPPER(:i+1))]
endif
enddo
do i = 1, SIZE(a%list)
print *, i, ', lower=',a%list(i)%lower, ', upper=', a%list(i)%upper
enddo
end
From the code, it's clear that the a%list%lower component shouldn't have any uppercase characters, but I get the following with the ifort compiler:
$ ifort -g -O0 test.f90 && ./a.out
1 , lower=abcdefghijklm, upper=ABCDEFGHIJKLM
2 , lower=cdefghijklmnopqrstuvwxyzA, upper=AB
3 , lower=abcdefghijklmno, upper=ABCDEFGHIJK
4 , lower=ghijklmnopqrstuvwxyzABC, upper=ABCD
5 , lower=abcdefghijklmnopq, upper=ABCDEFGHI
6 , lower=klmnopqrstuvwxyzABCDE, upper=ABCDEF
7 , lower=abcdefghijklmnopqrs, upper=ABCDEFG
8 , lower=opqrstuvwxyzABCDEFG, upper=ABCDEFGH
Enabling the default optimizatiions mitigates the problem:
$ ifort test.f90 && ./a.out
1 , lower=abcdefghijklm, upper=ABCDEFGHIJKLM
2 , lower=cdefghijklmnopqrstuvwxyz, upper=AB
3 , lower=abcdefghijklmno, upper=ABCDEFGHIJK
4 , lower=ghijklmnopqrstuvwxyz, upper=ABCD
5 , lower=abcdefghijklmnopq, upper=ABCDEFGHI
6 , lower=klmnopqrstuvwxyz, upper=ABCDEF
7 , lower=abcdefghijklmnopqrs, upper=ABCDEFG
8 , lower=opqrstuvwxyzA, upper=ABCDEFGH
Using the ifx compiler with no default optimizations seems to match expected behavior, except for the last entry:
$ ifx -g -O0 test.f90 && ./a.out
1 , lower=abcdefghijklm, upper=ABCDEFGHIJKLM
2 , lower=cdefghijklmnopqrstuvwxyz, upper=AB
3 , lower=abcdefghijklmno, upper=ABCDEFGHIJK
4 , lower=ghijklmnopqrstuvwxyz, upper=ABCD
5 , lower=abcdefghijklmnopq, upper=ABCDEFGHI
6 , lower=klmnopqrstuvwxyz, upper=ABCDEF
7 , lower=abcdefghijklmnopqrs, upper=ABCDEFG
8 , lower=opqrstuvwxy, upper=ABCDEFGH
And the something similar happens for ifx with the default optimizations:
$ ifx test.f90 && ./a.out
1 , lower=abcdefghijklm, upper=ABCDEFGHIJKLM
2 , lower=cdefghijklmnopqrstuvwxyz, upper=AB
3 , lower=abcdefghijklmno, upper=ABCDEFGHIJK
4 , lower=ghijklmnopqrstuvwxyz, upper=ABCD
5 , lower=abcdefghijklmnopq, upper=ABCDEFGHI
6 , lower=klmnopqrstuvwxyz, upper=ABCDEF
7 , lower=abcdefghijklmnopqrs, upper=ABCDEFG
8 , lower=opqrstuvwxyzA, upper=ABCDEFGH
These are the compiler versions:
$ ifort -V && ifx -V
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.9.0 Build 20230302_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2023.1.0 Build 20230320
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please try the latest ifx and ifort versions that were released last week. Looks to me like it's working now.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried your code on Windows with default optimisation and no optimisation and got some different spurious variants. I suspect the array constructor is at fault as there seem to have been a number of recent bugs on this.
ifort test_dt_alloc.f90 /Od
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.9.0 Build 20230302_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.30.30709.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:test_dt_alloc.exe
-subsystem:console
test_dt_alloc.obj
test_dt_alloc
1 , lower=abcdefghijklm, upper=ABCDEFGHIJKLM
2 , lower=cdefghijklmnopqrstuvwxyzA, upper=AB
3 , lower=abcdefghijklmno, upper=ABCDEFGHIJK
4 , lower=ghijklmnopqrstuvwxyzABC, upper=ABCD
5 , lower=abcdefghijklmnopq, upper=ABCDEFGHI
6 , lower=klmnopqrstuvwxyzABCDE, upper=ABCDEF
7 , lower=abcdefghijklmnopqrs, upper=ABCDEFG
8 , lower=opqrstuvwxyzABCDEFG, upper=ABCDEFGH
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ifort test_dt_alloc.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.9.0 Build 20230302_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.30.30709.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:test_dt_alloc.exe
-subsystem:console
test_dt_alloc.obj
test_dt_alloc
1 , lower=abcdefghijklm, upper=ABCDEFGHIJKLM
2 , lower=cdefghijklmnopqrstuvwxyz , upper=AB
3 , lower=abcdefghijklmno, upper=ABCDEFGHIJK
4 , lower=ghijklmnopqrstuvwxyz , upper=ABCD
5 , lower=abcdefghijklmnopq, upper=ABCDEFGHI
6 , lower=klmnopqrstuvwxyz , upper=ABCDEF
7 , lower=abcdefghijklmnopqrs, upper=ABCDEFG
8 , lower=opqrstuvwxyz A, upper=ABCDEFGH
optimisation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
consider this program, which also gives interesting results!
program test_dt_alloc2
implicit none
type :: sentence
character(:), allocatable :: lower, upper
end type
integer :: i, n = 7
type(sentence) :: b
character(*), parameter :: LOWER = 'abcdefghijklmnopqrstuvwxyz'
character(*), parameter :: UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
do i = 0, n
if (MOD(i, 2) == 0) then
b = sentence(LOWER(:13+i), UPPER(:13-i))
else
b = sentence(LOWER(i+1:), UPPER(:i+1))
endif
print *, i, ', b%lower ',b%lower, ', b%upper= ', b%upper
enddo
end
ifort test_dt_alloc2.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.9.0 Build 20230302_000000
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.30.30709.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:test_dt_alloc2.exe
-subsystem:console
test_dt_alloc2.obj
test_dt_alloc2
0 , b%lower abcdefghijklm, b%upper= ABCDEFGHIJKLM
1 , b%lower cdefghijklmnopqrstuvwxyz , b%upper= AB
2 , b%lower abcdefghijklmno, b%upper= ABCDEFGHIJK
3 , b%lower ghijklmnopqrstuvwxyz , b%upper= ABCD
4 , b%lower abcdefghijklmnopq, b%upper= ABCDEFGHI
5 , b%lower klmnopqrstuvwxyz , b%upper= ABCDEF
6 , b%lower abcdefghijklmnopqrs, b%upper= ABCDEFG
7 , b%lower opqrstuvwxyz A, b%upper= ABCDEFGH
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This one is well behaved. So the default constructor for sentence seem to be the problem....
program test_dt_alloc3
implicit none
integer :: i, n = 7
character(*), parameter :: LOWER = 'abcdefghijklmnopqrstuvwxyz'
character(*), parameter :: UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
do i = 0, n
if (MOD(i, 2) == 0) then
print *, i, ', b%lower ',LOWER(:13+i), ', b%upper= ', UPPER(:13-i)
else
print *, i, ', b%lower ',LOWER(i+1:), ', b%upper= ', UPPER(:i+1)
endif
enddo
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@jwmwalrus, Thanks for reporting this. I see the same thing with pre-production compilers
@andrew_4619, having more reproducers is great! Thank you.
I'll get a bug filed today.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I filed CMPLRLLVM-49308 for you both. I will let you know when it's fixed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi.
It's funny how, by trying to simplify the test case as much as possible, I stumbled upon a different thing.
In the original code, the issue is with reallocation on assignment when the derived type has a deferred-length character component (and the workaround is to use MOVE_ALLOC).
The following code (which could be shortened further, I admit) illustrates the problem:
module tables
implicit none
private
save
type, public :: table_entry
character(:), allocatable :: key
character(:), allocatable :: val
end type
interface table_entry
module procedure table_entry_new
end interface
type, public :: table
type(table_entry), allocatable :: storage(:)
contains
procedure, private :: add_entry1
generic :: add => add_entry1
end type
contains
function table_entry_new(i, k, v) result(new)
type(table_entry) :: new
integer, intent(in) :: i
character(*), intent(in) :: k, v
new%key = k
new%val = v
end function
subroutine add_entry1(this, kv)
class(table), intent(inout) :: this
type(table_entry), intent(in) :: kv
integer :: i
print'(/a)','value to add:'
print*,'key=',kv%key,', val=',kv%val
print '(/a)','storage, before adding:'
do i = 1, SIZE(this%storage)
print *,i,'key=',this%storage(i)%key,', val=',this%storage(i)%val
enddo
this%storage = [this%storage, kv]
print'(/a)','storage, after adding:'
do i = 1, SIZE(this%storage)
print *,i,'key=',this%storage(i)%key,', val=',this%storage(i)%val
enddo
end subroutine
end module tables
use tables
implicit none
integer :: i, n = 7
type(table) :: h
type(table_entry) :: kv
character(*), parameter :: LOWER = 'abcdefghijklmnopqrstuvwxyz'
character(*), parameter :: UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
h%storage = [table_entry :: ]
do i = 0, n
if (MOD(i, 2) == 0) then
kv = table_entry(i, LOWER(:13+i), UPPER(:13-i))
else
kv = table_entry(i, LOWER(i+1:), UPPER(:i+1))
endif
call h%add(kv)
enddo
end
Please notice that I'm using a custom constructor.
Here's the output:
$ ifort test.f90 && ./a.out
value to add:
key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, before adding:
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
value to add:
key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, after adding:
1 key=abcdefghijklm, val=��I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
value to add:
key=abcdefghijklmno, val=ABCDEFGHIJK
storage, before adding:
1 key=abcdefghijklm, val=��I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, after adding:
1 key=abcdefghijklm, val=0 �I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
value to add:
key=defghijklmnopqrstuvwxyz, val=ABCD
storage, before adding:
1 key=abcdefghijklm, val=0 �I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=��
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
value to add:
key=abcdefghijklmnopq, val=ABCDEFGHI
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=��
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
value to add:
key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
value to add:
key=abcdefghijklmnopqrs, val=ABCDEFG
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
value to add:
key=hijklmnopqrstuvwxyz, val=ABCDEFGH
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=bcdefghijklmnopqrst, val=ABCDEFG
8 key=hijklmnopqrstuvwxyz, val=ABCDEFGH
In the original code, the table, when saved to a file, contains some caret notation symbols, so I guess this test is much closer.
And this is the output using gfortran:
$ gfortran test.f90 && ./a.out
value to add:
key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, before adding:
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
value to add:
key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
value to add:
key=abcdefghijklmno, val=ABCDEFGHIJK
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
value to add:
key=defghijklmnopqrstuvwxyz, val=ABCD
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
value to add:
key=abcdefghijklmnopq, val=ABCDEFGHI
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
value to add:
key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
value to add:
key=abcdefghijklmnopqrs, val=ABCDEFG
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
value to add:
key=hijklmnopqrstuvwxyz, val=ABCDEFGH
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
8 key=hijklmnopqrstuvwxyz, val=ABCDEFGH
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi.
It's funny how, by trying to simplify the test case as much as possible, I stumbled upon a different thing.
In the original code, the issue is with reallocation on assignment when the derived type has a deferred-length character component (and the workaround is to use MOVE_ALLOC).
The following code (which could be shortened further, I admit) illustrates the problem:
module tables
implicit none
private
save
type, public :: table_entry
character(:), allocatable :: key
character(:), allocatable :: val
end type
interface table_entry
module procedure table_entry_new
end interface
type, public :: table
type(table_entry), allocatable :: storage(:)
contains
procedure, private :: add_entry1
generic :: add => add_entry1
end type
contains
function table_entry_new(i, k, v) result(new)
type(table_entry) :: new
integer, intent(in) :: i
character(*), intent(in) :: k, v
new%key = k
new%val = v
end function
subroutine add_entry1(this, kv)
class(table), intent(inout) :: this
type(table_entry), intent(in) :: kv
integer :: i
print'(/a)','value to add:'
print*,'key=',kv%key,', val=',kv%val
print '(/a)','storage, before adding:'
do i = 1, SIZE(this%storage)
print *,i,'key=',this%storage(i)%key,', val=',this%storage(i)%val
enddo
this%storage = [this%storage, kv]
print'(/a)','storage, after adding:'
do i = 1, SIZE(this%storage)
print *,i,'key=',this%storage(i)%key,', val=',this%storage(i)%val
enddo
end subroutine
end module tables
use tables
implicit none
integer :: i, n = 7
type(table) :: h
type(table_entry) :: kv
character(*), parameter :: LOWER = 'abcdefghijklmnopqrstuvwxyz'
character(*), parameter :: UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
h%storage = [table_entry :: ]
do i = 0, n
if (MOD(i, 2) == 0) then
kv = table_entry(i, LOWER(:13+i), UPPER(:13-i))
else
kv = table_entry(i, LOWER(i+1:), UPPER(:i+1))
endif
call h%add(kv)
enddo
end
Please notice that I'm using a custom constructor.
Here's the output:
$ ifort test.f90 && ./a.out
value to add:
key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, before adding:
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
value to add:
key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, after adding:
1 key=abcdefghijklm, val=��I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
value to add:
key=abcdefghijklmno, val=ABCDEFGHIJK
storage, before adding:
1 key=abcdefghijklm, val=��I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, after adding:
1 key=abcdefghijklm, val=0 �I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
value to add:
key=defghijklmnopqrstuvwxyz, val=ABCD
storage, before adding:
1 key=abcdefghijklm, val=0 �I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=��
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
value to add:
key=abcdefghijklmnopq, val=ABCDEFGHI
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=��
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
value to add:
key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
value to add:
key=abcdefghijklmnopqrs, val=ABCDEFG
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
value to add:
key=hijklmnopqrstuvwxyz, val=ABCDEFGH
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=bcdefghijklmnopqrst, val=ABCDEFG
8 key=hijklmnopqrstuvwxyz, val=ABCDEFGH
In the original code, the table is saved to a file and contains some caret notation symbols, so I guess this test is much closer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Btw, it seems that editing a post in this forum, makes it disappear completely.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
(Reposted, since it got deleted.)
Hi.
It's funny how, by trying to simplify the test case as much as possible, I stumbled upon a different thing.
In the original code, the issue is with reallocation on assignment when the derived type has a deferred-length character component (and the workaround is to use MOVE_ALLOC).
The following code (which could be shortened further, I admit) illustrates the problem:
module tables
implicit none
private
save
type, public :: table_entry
character(:), allocatable :: key
character(:), allocatable :: val
end type
interface table_entry
module procedure table_entry_new
end interface
type, public :: table
type(table_entry), allocatable :: storage(:)
contains
procedure, private :: add_entry1
generic :: add => add_entry1
end type
contains
function table_entry_new(i, k, v) result(new)
type(table_entry) :: new
integer, intent(in) :: i
character(*), intent(in) :: k, v
new%key = k
new%val = v
end function
subroutine add_entry1(this, kv)
class(table), intent(inout) :: this
type(table_entry), intent(in) :: kv
integer :: i
print'(/a)','value to add:'
print*,'key=',kv%key,', val=',kv%val
print '(/a)','storage, before adding:'
do i = 1, SIZE(this%storage)
print *,i,'key=',this%storage(i)%key,', val=',this%storage(i)%val
enddo
this%storage = [this%storage, kv]
print'(/a)','storage, after adding:'
do i = 1, SIZE(this%storage)
print *,i,'key=',this%storage(i)%key,', val=',this%storage(i)%val
enddo
end subroutine
end module tables
use tables
implicit none
integer :: i, n = 7
type(table) :: h
type(table_entry) :: kv
character(*), parameter :: LOWER = 'abcdefghijklmnopqrstuvwxyz'
character(*), parameter :: UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
h%storage = [table_entry :: ]
do i = 0, n
if (MOD(i, 2) == 0) then
kv = table_entry(i, LOWER(:13+i), UPPER(:13-i))
else
kv = table_entry(i, LOWER(i+1:), UPPER(:i+1))
endif
call h%add(kv)
enddo
end
Please notice that I'm using a custom constructor.
Here's the output:
$ ifort test.f90 && ./a.out
value to add:
key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, before adding:
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
value to add:
key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, after adding:
1 key=abcdefghijklm, val=��I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
value to add:
key=abcdefghijklmno, val=ABCDEFGHIJK
storage, before adding:
1 key=abcdefghijklm, val=��I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, after adding:
1 key=abcdefghijklm, val=0 �I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
value to add:
key=defghijklmnopqrstuvwxyz, val=ABCD
storage, before adding:
1 key=abcdefghijklm, val=0 �I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=��
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
value to add:
key=abcdefghijklmnopq, val=ABCDEFGHI
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=��
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
value to add:
key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
value to add:
key=abcdefghijklmnopqrs, val=ABCDEFG
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
value to add:
key=hijklmnopqrstuvwxyz, val=ABCDEFGH
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key=��I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=bcdefghijklmnopqrst, val=ABCDEFG
8 key=hijklmnopqrstuvwxyz, val=ABCDEFGH
In the original code, the table is saved to a file and contains some caret notation symbols, so I guess this test is much closer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for another reproducer! I added it to the bug report.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The reproducers are printing the correct results for both ifx and ifort with the compilers that were released earlier this week.
Please check out the new compiler versions!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi.
Thanks for the follow-up.
I'm still getting similar behavior with the latest version of ifort/ifx:
This is the code (same as the one posted above):
module tables
implicit none
private
save
type, public :: table_entry
character(:), allocatable :: key
character(:), allocatable :: val
end type
interface table_entry
module procedure table_entry_new
end interface
type, public :: table
type(table_entry), allocatable :: storage(:)
contains
procedure, private :: add_entry1
generic :: add => add_entry1
end type
contains
function table_entry_new(i, k, v) result(new)
type(table_entry) :: new
integer, intent(in) :: i
character(*), intent(in) :: k, v
new%key = k
new%val = v
end function
subroutine add_entry1(this, kv)
class(table), intent(inout) :: this
type(table_entry), intent(in) :: kv
integer :: i
print'(/a)','value to add:'
print*,'key=',kv%key,', val=',kv%val
print '(/a)','storage, before adding:'
do i = 1, SIZE(this%storage)
print *,i,'key=',this%storage(i)%key,', val=',this%storage(i)%val
enddo
this%storage = [this%storage, kv]
print'(/a)','storage, after adding:'
do i = 1, SIZE(this%storage)
print *,i,'key=',this%storage(i)%key,', val=',this%storage(i)%val
enddo
end subroutine
end module tables
use tables
implicit none
integer :: i, n = 7
type(table) :: h
type(table_entry) :: kv
character(*), parameter :: LOWER = 'abcdefghijklmnopqrstuvwxyz'
character(*), parameter :: UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
h%storage = [table_entry :: ]
do i = 0, n
if (MOD(i, 2) == 0) then
kv = table_entry(i, LOWER(:13+i), UPPER(:13-i))
else
kv = table_entry(i, LOWER(i+1:), UPPER(:i+1))
endif
call h%add(kv)
enddo
end
And this is the output I get:
(ins)$ ifx -V test.f90 && ./a.out
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.0.0 Build 20231017
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Intel(R) Fortran 24.0-1238.2
GNU ld (GNU Binutils for Debian) 2.41
value to add:
key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, before adding:
storage, after adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
value to add:
key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, before adding:
1 key=abcdefghijklm, val=ABCDEFGHIJKLM
storage, after adding:
1 key=abcdefghijklm, val= �I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
value to add:
key=abcdefghijklmno, val=ABCDEFGHIJK
storage, before adding:
1 key=abcdefghijklm, val= �I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
storage, after adding:
1 key=abcdefghijklm, val=0��I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
value to add:
key=defghijklmnopqrstuvwxyz, val=ABCD
storage, before adding:
1 key=abcdefghijklm, val=0��I
2 key=bcdefghijklmnopqrstuvwxyz, val=AB
3 key=abcdefghijklmno, val=ABCDEFGHIJK
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val= �
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
value to add:
key=abcdefghijklmnopq, val=ABCDEFGHI
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val= �
3 key=abcdefghijklmno, val=ABCDEFGHIJK
4 key=defghijklmnopqrstuvwxyz, val=ABCD
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key= �I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
value to add:
key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key= �I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=abcdefghijklmnopq, val=ABCDEFGHI
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key= �I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
value to add:
key=abcdefghijklmnopqrs, val=ABCDEFG
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key= �I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=fghijklmnopqrstuvwxyz, val=ABCDEF
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key= �I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
value to add:
key=hijklmnopqrstuvwxyz, val=ABCDEFGH
storage, before adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key= �I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=abcdefghijklmnopqrs, val=ABCDEFG
storage, after adding:
1 key=abcdefghijklm, val=abcdefghijklm
2 key=bcdefghijklmnopqrstuvwxyz, val=ab
3 key= �I, val=ABCDEFGHIJK
4 key=bcdefghijklmnopqrstuvwx, val=ABCD
5 key=bcdefghijklmnopqr, val=ABCDEFGHI
6 key=bcdefghijklmnopqrstuv, val=ABCDEF
7 key=bcdefghijklmnopqrst, val=ABCDEFG
8 key=hijklmnopqrstuvwxyz, val=ABCDEFGH
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, heck! I tried it before I posted the news and I thought printed correctly. But it doesn't.
I'll let the compiler person know.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@jwmwalrus, the two cases you posted actually two different bugs according to the compiler engineer. Both will be fixed in 2024.1.0 due to be available in a few months.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a similar problem that seems to point to a different origin of this bug.
Suppose that in the original code by @jwmwalrus one redefines the type sentence:
type :: sentence
character(:), allocatable :: lower, upper
end type
to a new one like that:
type :: sentence
real, allocatable :: A(:)
! real, pointer :: A(:)
end type
Note the option to declare the component A as a pointer.
In my code, the component A is corrupted after reallocation of a%list if A is allocatable. But A is NOT corrupted after reallocation of a%list if A is a pointer that is allocated before it.
Thus, I believe this bug is not triggered by reallocation only.
Hope this reply helps.
I can post a snippet code if necessary.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Adelson_BR, a complete reproducer would be useful! The compiler team likes to confirm fixes against multiple examples.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Barbara_P_Intel,
Sorry for the delay.
The folowing code reproduces the bug and also shows that using pointers prevents the bug.
The idea is to work with a structure (C) that contains another struture (C(#)%B) that in turn contains matrices A (C(#)%B(#)%A). Reallocations of C and C(#)%B are made in a subroutine but one could reproduce the bug in a DO loop as @jwmwalrus did. Like the problem reported by @jwmwalrus, the content of matrix A is corrupted when C(#)%B is reallocated.
The code is in the attached file teste_realoca_tipos.f90.
I've tried ifx and ifort 2023. I also tried gfortran. Gfortran does not even compile for versions up to 12 but Gfortran works fine for versions 13+.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Adelson_BR, what output do you expect from your code?
I also tried commenting out the ALLOCATABLE and using POINTER. I got a runtime seg fault.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page