Patchwork [Fortran] PR 42647: Missed initialization/dealloc of allocatable scalar DT with allocatable component

login
register
mail settings
Submitter Tobias Burnus
Date Oct. 24, 2010, 7:08 p.m.
Message ID <4CC4842A.8010201@net-b.de>
Download mbox | patch
Permalink /patch/69045/
State New
Headers show

Comments

Tobias Burnus - Oct. 24, 2010, 7:08 p.m.
Am 24.10.2010 13:29, schrieb Tobias Burnus:
> Janus Weil wrote:
>> In the meantime: Any further comments on this patch?
>
> It does not solve the related issues of PR 43018 and PR 45451.
>
> Regarding the former: For the following program, valgrind shows:
>    Invalid read of size 8
>       at 0x40087A: MAIN__ (alloc_comp_scalar_1.f90:8)
> for the line "a1 = a2".
>
> The dump looks quite unspectacular. Does anyone see the problem?

Well, one couldn't easily see it - it was hidden in the "myalloc" dump. 
If one looks at the optimized dump, one sees:

               D.1504 = (void * restrict) __builtin_malloc (4);
             D.1506 = (void * restrict) __builtin_malloc (8);
             __builtin_memcpy (a1.entry, a2.entry, 8);

The problem is that "entry" is a pointer to an integer(4). The first 
malloc correctly allocates 4 bytes to store the integer - but in the 
assignment, not the size of the target is used (4 bytes) but the size of 
the pointer (8 bytes on x86-64-linux) - thus, the program works with 
-m32 ...

The issue is seemingly in trans-array.c's duplicate_allocatable. The 
following works for me - I will create a proper, regtested patch later.

           tmp = gfc_call_malloc (&block, type, size);

Tobias

PS: For those hoping for collateral fixing: That patch together with 
Janus' patch for PR 42647 does not help with PR 45451.

Patch

--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -6072,7 +6072,7 @@  duplicate_allocatable (tree dest, tree src, tree 
type, int rank,
        null_data = gfc_finish_block (&block);

        gfc_init_block (&block);
-      size = TYPE_SIZE_UNIT (type);
+      size = TYPE_SIZE_UNIT (TREE_TYPE (type));
        if (!no_malloc)
         {