diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-10-29 12:06:28 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-10-29 12:15:07 (GMT) |
commit | fb94cee1a10c7bfb8e73dd0a094ae71fe96bf3e7 (patch) | |
tree | d9802b2fb480e675992c69e58b42caa887253498 /src | |
parent | c4d715260bd0ed5f3b6d38a63a2659715342c90a (diff) | |
download | Qt-fb94cee1a10c7bfb8e73dd0a094ae71fe96bf3e7.zip Qt-fb94cee1a10c7bfb8e73dd0a094ae71fe96bf3e7.tar.gz Qt-fb94cee1a10c7bfb8e73dd0a094ae71fe96bf3e7.tar.bz2 |
Fix gcc bug in qReallocAligned
the line
faked.pptr[-1] = real.ptr;
was ignored by the GCC 4.5. (optimized out)
Workaround by using proper reinterpret_cast casting instead of union casting.
Fixes crash in tst_Collections::alignment
The crash would occurs for any use of qReallocAligned with alignement > sizeof(void*)
(fortunately this is not often called)
Reviewed-by: thiago
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/global/qmalloc.cpp | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp index 090998c..028a0a5 100644 --- a/src/corelib/global/qmalloc.cpp +++ b/src/corelib/global/qmalloc.cpp @@ -90,8 +90,6 @@ void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t align return newptr + 1; } - union { void *ptr; void **pptr; quintptr n; } real, faked; - // qMalloc returns pointers aligned at least at sizeof(size_t) boundaries // but usually more (8- or 16-byte boundaries). // So we overallocate by alignment-sizeof(size_t) bytes, so we're guaranteed to find a @@ -100,19 +98,21 @@ void *qReallocAligned(void *oldptr, size_t newsize, size_t oldsize, size_t align // However, we need to store the actual pointer, so we need to allocate actually size + // alignment anyway. - real.ptr = qRealloc(actualptr, newsize + alignment); - if (!real.ptr) + void *real = qRealloc(actualptr, newsize + alignment); + if (!real) return 0; - faked.n = real.n + alignment; - faked.n &= ~(alignment - 1); + quintptr faked = reinterpret_cast<quintptr>(real) + alignment; + faked &= ~(alignment - 1); + + void **faked_ptr = reinterpret_cast<void **>(faked); // now save the value of the real pointer at faked-sizeof(void*) // by construction, alignment > sizeof(void*) and is a power of 2, so // faked-sizeof(void*) is properly aligned for a pointer - faked.pptr[-1] = real.ptr; + faked_ptr[-1] = real; - return faked.ptr; + return faked_ptr; } void qFreeAligned(void *ptr) |