forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Bug with pointer components of derived type.

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sat Feb 16, 2013 10:06 pm    Post subject: Bug with pointer components of derived type. Reply with quote

The following code contains a derive type PER_T which contains a pointer to an array of derived type GRP_T.

The derived type GRP_T in turn contains a pointer to an array of derived type EL_T.

When the line marked (A) is executed, the members of pers(1) lose their values and are set to zero. The allocate on this line is not working; this is indicated by the pointer in line (B) which becomes NULL.

I have tracked this down to be due to the use of null() to initialise the els(:) pointer in line (C). If I remove this initialisation, the code works correctly.

Please can this be fixed?

Regards
David

Code:

program anon

   type el_t
      real :: a
   end type el_t

   type grp_t
      type(el_t), pointer :: els(:) => null()  ! (C)
   end type grp_t

   type per_t
      integer :: num
      real :: x
      type(grp_t), pointer :: grps(:) => null()
   end type per_t

   type(per_t), allocatable :: pers(:)

   integer :: i
   type(grp_t), pointer :: grps_ptr(:)

   allocate (pers(1))

   ! Setup values of pers(1)
   pers(1)%num = 1
   pers(1)%x = 1.0

   ! Allocate grps(:) part of pers(1) to point to array of size 5
   allocate(pers(1)%grps(5))          !< (A) BUG HERE. Value of pers(1)%num and pers(1)%x get changed to 0
   grps_ptr => pers(1)%grps(:)        !< (B) BUG HERE. grps_ptr is NULL POINTER and shouldn't be

   ! Allocate els(:) to point to array of size 1
   do i=1, 5
      allocate (pers(1)%grps(i)%els(1))
   end do

   ! Set value of a in els
   pers(1)%grps(1)%els(1)%a = 2.0

   print *, pers(1)%num
   print *, pers(1)%x

end program anon

_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl


Last edited by davidb on Sun Feb 17, 2013 9:08 pm; edited 1 time in total
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sun Feb 17, 2013 9:20 am    Post subject: Reply with quote

Thanks. I have logged this for investigation.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Wed Jul 31, 2013 8:10 am    Post subject: Reply with quote

This is still an issue with 6.35. I wonder if it could be patched for the next release please.

I have produced the following very simple example to show what is wrong. When the second allocate is done, the data at the address of per(1) is initialized instead of the data at address of grps(1) (corrupting the value of num).

The error is also obvious from the EXPLIST for this code.

Code:

program anon

   type grp_t
      integer :: n = 2 ! (C)
   end type grp_t

   type per_t
      integer :: num
      type(grp_t), pointer :: grps(:) => null()
   end type per_t

   type(per_t), allocatable :: pers(:)

   ! Setup values of pers(1)
   allocate (pers(1))   
   pers(1)%num = 1

   ! BUG HERE. Allocate needs to set n = 2 to initialise grps(1).
   ! However the data at the address of pers(1) is initialised instead.
   ! This causes the value of pers(1)%num to change to 2

   ! Allocate grps(:) part of pers(1) to point to array of size 1   
   allocate(pers(1)%grps(1))

   print *, pers(1)%num, ' <-- should be 1 !'

end program anon

_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Fri Aug 02, 2013 7:47 pm    Post subject: Reply with quote

I did do a preliminary investigation on this bug, sufficient to indicate that it is a reality nasty one to fix.

Given that a new release is planned shortly, it is unlikely that this one can be fixed in time.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Fri Aug 02, 2013 8:12 pm    Post subject: Reply with quote

If you can get the front end of the compiler to replace

Code:

allocate(pers(1)%grps(1))


by

Code:

p => pers(1)
allocate(p%grps(1))


the BUG will disappear.

I can do this in Fortran code, but have to declare pers with the TARGET attribute, which I don't really need.

I am surprised this is so tricky. Looks like just an address is wrong looking at the assembly.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Fri Aug 02, 2013 8:28 pm    Post subject: Reply with quote

Thanks for the suggestion.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sat Apr 12, 2014 2:05 pm    Post subject: Reply with quote

Paul,

Was this bug fixed as a side-effect of the recent fix to default initialisation in the next release, or is it still an ongoing issue.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Mon Apr 14, 2014 7:49 am    Post subject: Reply with quote

Unfortunately this issue is still outstanding.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sat Apr 26, 2014 10:27 am    Post subject: Reply with quote

I have been studying this some more and have found the problem (at least at the assembly level).

I looked at the following codes, which are the simplest I can make which reproduces the problem.

Code P1 shows the BUG and doesn't work, while P2 works fine. The only difference is that the integer x is located at the start of bbb in code P1, whereas in P2 the pointer array is at the beginning.
Code:

! Doesn't work
program P1

    type aaa_t
       integer :: a = 999
    end type aaa_t

    type bbb_t
       integer :: x
       type(aaa_t), pointer :: aaa(:)
    end type bbb_t

    type(bbb_t) :: bbb(1)

    ! Setup bbb(1)
    bbb(1)%x = 1

    ! Allocate aaa(:) part of bbb(1) to point to array of size 5
    allocate(bbb(1)%aaa(5))
   
    print *, bbb(1)%x, ' <= should be 1 but 999 is printed!'

 end program P1

Code:

! Works
program P2

    type aaa_t
       integer :: a = 999
    end type aaa_t

    type bbb_t
       type(aaa_t), pointer :: aaa(:)
       integer :: x   
    end type bbb_t

    type(bbb_t) :: bbb(1)

    ! Setup bbb(1)
    bbb(1)%x = 1

    ! Allocate aaa(:) part of bbb(1) to point to array of size 5
    allocate(bbb(1)%aaa(5))
   
    print *, bbb(1)%x, ' <= should be 1 and is!'

 end program P2


The assembly code for P1 and P2 include the following loop for doing the default initialisation (its the same assembly code in each case):

Code:

      00000090(42/3/458)      Label     __N3
      00000090(43/6/492)         mov       ecx,II@01
      00000093(44/6/492)         imul      ecx,=28
      00000099(45/4/289)         mov       edx,AAA_T(999)
      0000009f(46/4/289)         mov       BBB[ecx],edx
      000000a3(47/4/467)         inc       II@01
      000000a6(48/4/468)         mov       eax,LoopUpper@1
      000000a9(49/4/468)         cmp       eax,II@01
      000000ac(50/4/468)         jge       __N3


II@01 is the loop counter which starts at 0 and LoopUpper@1 is upper value of the loop counter, 4.

In this code register ecx used in BBB[ecx] contains the successive values 0, 28, 56, etc. This is correct for P2. However it isn't correct for P1 where it needs to contain the values 4, 32, 60, etc.

You could possibly fix this by adding the appropriate offset to ecx as follows.

Code:

      00000090(43/6/492)         mov       ecx,II@01
      00000093(44/6/492)         imul      ecx,=28
                                 add       ecx, 4


Obviously the offset to be added will change depending on where in BBB the pointer array is located. In code P2 for example, the offset would be zero (which explains why the BUG doesn't get exposed in this case).

PS. I also looked at the equivalent of P1 but with a scalar for BBB instead of an array of size 1; this code works and has the offset that is needed.
Code:

      00000090(42/3/267)      Label     __N3
      00000090(43/6/278)         mov       ecx,BBB[8]
      00000093(44/6/278)         add       ecx,II@01
      00000096(45/5/280)         mov       edi,BBB[4]
      00000099(46/4/159)         mov       eax,AAA_T(999)
      0000009f(47/4/159)         mov       [edi+ecx*4],eax
      000000a3(48/4/274)         inc       II@01
      000000a6(49/4/275)         mov       ecx,LoopUpper@1
      000000a9(50/4/275)         cmp       ecx,II@01
      000000ac(51/4/275)         jge       __N3

I hope this helps
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sat Apr 26, 2014 4:04 pm    Post subject: Reply with quote

Thanks for this. I will make a note of your analysis.

However, this needs to be fixed in the tree structure before we get to the backend assembly. That way the fix is applied to both Win32 and .NET and potentially Win64. The backend will handle it once the tree is fixed.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sat Apr 26, 2014 6:05 pm    Post subject: Reply with quote

Yes, it needs fixing in the front end.

As FTN95 doesn't expose the abstract tree I haven't been able to look at it.

But hopefully having this little look at the assembly code for Win32 may provide some insight into what may be going on. You at least know that an incorrect memory offset is the cause. You might also look at the difference between the abstract tree for the cases where BBB is an array (which fails) and where BBB is a scalar (which works).

Good luck and thanks for looking Paul. Default initialisation does seem to be a big feature in my coding at present (like a habit), and I am having to do explicit initialisation as a workaround with FTN95.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sat Apr 26, 2014 6:09 pm    Post subject: Re: Reply with quote

PaulLaidler wrote:
and potentially Win64.


Are you teasing us?
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Sun Apr 27, 2014 6:48 am    Post subject: Reply with quote

Wow...64bit... please don't say NO, Paul
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Mon Jun 24, 2019 10:47 am    Post subject: Reply with quote

This issue has finally been fixed. The fix will be in the next release of FTN95.
Back to top
View user's profile Send private message AIM Address
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sun Jul 07, 2019 6:05 pm    Post subject: Reply with quote

Thanks Paul, your work on this is much appreciated.
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group