(Forwarding Debian Bug#542158)

Unchecked_Deallocation of a record extension containing an Unbounded_String
executes incorrectly. Here is a reproducer:

with Ada.Strings.Unbounded;
use Ada.Strings.Unbounded;
package Double_Free is
   type Test_Base is tagged null record;
   type Test_Class_Access is access all Test_Base'Class;
   type Test_Extension is new Test_Base with record
      Last_Name : Unbounded_String := Null_Unbounded_String;
   end record;
end Double_Free;

   ---

with Ada.Unchecked_Deallocation;
with Double_Free; use Double_Free;
procedure Main is
   procedure Free is new Ada.Unchecked_Deallocation
     (Object => Test_Base'Class,
      Name   => Test_Class_Access);
   Handle : Test_Class_Access := new Test_Extension;
begin
   Free (Handle);
end Main;

$ gnatmake main.adb
$ ./main
*** glibc detected *** main: double free or corruption errors.

valgrind --leak-check=full --show-reachable=yes --leak-resolution=high ./main

==5772== Memcheck, a memory error detector.
==5772== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==5772== Using LibVEX rev 1884, a library for dynamic binary translation.
==5772== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==5772== Using valgrind-3.4.1-Debian, a dynamic binary instrumentation
framework.
==5772== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==5772== For more details, rerun with: -v
==5772==
==5772== Invalid free() / delete / delete[]
==5772==    at 0x4C2261F: free (vg_replace_malloc.c:323)
==5772==    by 0x50A8D84: __gnat_free (in /usr/lib/libgnat-4.4.so.1)
==5772==    by 0x403FC4: _ada_main (in /home/reet/double-free/obj/main)
==5772==    by 0x40327B: main (in /home/reet/double-free/obj/main)
==5772==  Address 0x5b3b040 is 16 bytes inside a block of size 136 alloc'd
==5772==    at 0x4C2391E: malloc (vg_replace_malloc.c:207)
==5772==    by 0x50A8DC7: __gnat_malloc (in /usr/lib/libgnat-4.4.so.1)
==5772==    by 0x403EF0: _ada_main (in /home/reet/double-free/obj/main)
==5772==    by 0x40327B: main (in /home/reet/double-free/obj/main)
==5772==
==5772== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1)
==5772== malloc/free: in use at exit: 136 bytes in 1 blocks.
==5772== malloc/free: 1 allocs, 1 frees, 136 bytes allocated.
==5772== For counts of detected errors, rerun with: -v
==5772== searching for pointers to 1 not-freed blocks.
==5772== checked 203,328 bytes.
==5772==
==5772==
==5772== 136 bytes in 1 blocks are definitely lost in loss record 1 of 1
==5772==    at 0x4C2391E: malloc (vg_replace_malloc.c:207)
==5772==    by 0x50A8DC7: __gnat_malloc (in /usr/lib/libgnat-4.4.so.1)
==5772==    by 0x403EF0: _ada_main (in /home/reet/double-free/obj/main)
==5772==    by 0x40327B: main (in /home/reet/double-free/obj/main)
==5772==
==5772== LEAK SUMMARY:
==5772==    definitely lost: 136 bytes in 1 blocks.
==5772==      possibly lost: 0 bytes in 0 blocks.
==5772==    still reachable: 0 bytes in 0 blocks.
==5772==         suppressed: 0 bytes in 0 blocks.

Freeing memory of a base type object (Test_Base) works without problems.
When the unbounded string field (Name) is removed or replaced (e.g. by
an Integer), freeing also works for the type extension.

The code has been tested with the following compiler / arch
combinations:

i386/gnat-4.3  : works
i386/gnat-4.4  : works
amd64/gnat-4.3 : works
amd64/gnat-4.4 : FAILS

This bug hurts PolyORB and prevents us from migrating all Ada packages in
Debian to gnat-4.4.


-- 
           Summary: [4.4 regression] Unchecked_Deallocation causes double-
                    free errors
           Product: gcc
           Version: 4.4.1
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: ada
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ludovic at ludovic-brenta dot org
  GCC host triplet: x86_64-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41100

Reply via email to