Bug 56594

Summary: Invalid read of size 1 for gfortran.dg/realloc_on_assign_5.f03
Product: gcc Reporter: Dominique d'Humieres <dominiq>
Component: fortranAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: tkoenig
Priority: P3    
Version: 4.8.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description Dominique d'Humieres 2013-03-11 13:27:34 UTC
Running gfortran.dg/realloc_on_assign_5.f03 under valgrind gives

==32678== Invalid read of size 1
==32678==    at 0x7FFFFFE007D4: ???
==32678==    by 0x100000DA6: MAIN__ (realloc_on_assign_5.f03:15)
==32678==    by 0x100000E60: main (realloc_on_assign_5.f03:18)
==32678==  Address 0x100449541 is 0 bytes after a block of size 1 alloc'd
==32678==    at 0x100012891: realloc (vg_replace_malloc.c:635)
==32678==    by 0x100000D71: MAIN__ (realloc_on_assign_5.f03:15)
==32678==    by 0x100000E60: main (realloc_on_assign_5.f03:18)
==32678== 

Program aborted. Backtrace:
#0  0x10001fe42
#1  0x1000201b2
#2  0x1000f1618
#3  0x100000dfc
#4  0x100000e60
==32678== 
==32678== Process terminating with default action of signal 6 (SIGABRT)
==32678==    at 0x1001DA0B6: __kill (in /usr/lib/libSystem.B.dylib)
==32678==    by 0x100020198: _gfortrani_sys_abort (in /opt/gcc/gcc4.8w/lib/libgfortran.3.dylib)
==32678==    by 0x100000E60: main (realloc_on_assign_5.f03:18)
==32678== 
==32678== HEAP SUMMARY:
==32678==     in use at exit: 3,822 bytes in 18 blocks
==32678==   total heap usage: 21 allocs, 3 frees, 3,953 bytes allocated
==32678== 
==32678== LEAK SUMMARY:
==32678==    definitely lost: 0 bytes in 0 blocks
==32678==    indirectly lost: 0 bytes in 0 blocks
==32678==      possibly lost: 0 bytes in 0 blocks
==32678==    still reachable: 3,734 bytes in 17 blocks
==32678==         suppressed: 88 bytes in 1 blocks
==32678== Rerun with --leak-check=full to see details of leaked memory
==32678== 
==32678== For counts of detected and suppressed errors, rerun with: -v
==32678== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Abort

The test also aborts at run time when compiled with -fsanitize=address.

Reduced test

program main
  implicit none
  character(:), allocatable :: a, b
  a = 'ax'
  a = a(2:2)
end program main

There is no error if "a = a(2:2)" is replaced with "a = 'x'".
Comment 1 Tilo Schwarz 2013-03-17 19:56:11 UTC
I think the problem is, that for the line 

a = a(2:2)

1st, a is realloced to length one and
2nd, a(2) is memmoved to a(1), but at that time a(2) is already invalid.

Using -fdump-tree-original:

On line 42 the realloc happens to length 1.
On line 50 the memmove happens from &(*a)[2], which is not valid anymore because of the realloc on line 42.

 42         a = (character(kind=1)[1:.a] *) __builtin_realloc ((void *) a, 1);
 43         L.4:;
 44         .a = 1;
 45         D.1827 = .a;
 46         if (D.1827 != 0)
 47           {
 48             if ((character(kind=4)) D.1827 <= 1)
 49               {
 50                 __builtin_memmove ((void *) a, (void *) &(*a)[2]{lb: 1 sz: 1}, (character(kind=4)) D.1827);
 51               }
Comment 2 Thomas Koenig 2013-04-08 20:25:49 UTC
Dup of PR 47674.

*** This bug has been marked as a duplicate of bug 47674 ***