https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70758

            Bug ID: 70758
           Summary: unique_ptr<T[]> of aligned T calls invalid free
           Product: gcc
           Version: 4.9.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: 2013.bugzilla.gcc.gnu.org at ingomueller dot net
  Target Milestone: ---

Created attachment 38321
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38321&action=edit
Example c++ program that produces the invalid free.

In a certain situation, the default delete of a unique_ptr<T[]> calls an
invalid free.

The situation occurs for a struct that as an __attributed__ ((aligned(x))) with
a google dense_hash_map as a member. I haven't been able to figure out what is
special about the dense_hash_map yet. A short version of the code that produces
the bug (full version is attached):

typedef google::dense_hash_map<uint32_t,uint32_t> HmType;

typedef struct C {
    HmType hm;
} C __attribute__ ((aligned(64)));

int main(int,char**)
{
    std::unique_ptr<C[]> cx( new C[100] );
}

The free called by delete [] called by the deleter of the unique pointer is
invalid: valgrind says it is "56 bytes inside a block of size 8,064 alloc'd".

To reproduce:
1) Install google sparsehash-2.0.3
(https://github.com/sparsehash/sparsehash/releases).
2) Compile and run with valgrind: g++ -std=c++11 uniqueptr.cpp && valgrind
./a.out

Relevant output:
==7631== Invalid free() / delete / delete[] / realloc()
==7631==    at 0x4C2A8E0: operator delete[](void*) (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7631==    by 0x401D3D: std::default_delete<C []>::operator()(C*) const (in
/tmp/a.out)
==7631==    by 0x4018B4: std::unique_ptr<C [], std::default_delete<C []>
>::~unique_ptr() (in /tmp/a.out)
==7631==    by 0x400D10: main (in /tmp/a.out)
==7631==  Address 0x5a07fd8 is 56 bytes inside a block of size 8,064 alloc'd
==7631==    at 0x4C298A0: operator new[](unsigned long) (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7631==    by 0x400CBB: main (in /tmp/a.out)

Other remark: g++ warns that it ignores attributes on C of the unique_ptr<C>,
but doesn't warn on unique_ptr<C[]>. Maybe it should ignore the alignment for
the array as well, but doesn't?

Reply via email to