summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-10-29 12:06:28 (GMT)
committerOlivier Goffart <olivier.goffart@nokia.com>2010-10-29 12:15:07 (GMT)
commitfb94cee1a10c7bfb8e73dd0a094ae71fe96bf3e7 (patch)
treed9802b2fb480e675992c69e58b42caa887253498
parentc4d715260bd0ed5f3b6d38a63a2659715342c90a (diff)
downloadQt-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
-rw-r--r--src/corelib/global/qmalloc.cpp16
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)