[Development] Pointer aliasing problem in optimized gcc builds

Olivier Goffart olivier at woboq.com
Fri Sep 13 17:22:32 CEST 2013


On Friday 13 September 2013 15:55:45 Soroush Rabiei wrote:
> Hi everybody
> 
> 
> I'm using a custom build of Qt 5.1.1 compiled with GCC 4.8.1 on
> Windows (MinGW builds x86_64). For some performance reasons I have to
> enable "-O3" flag until my project is ported out of Qt. The Qt was
> built with C++11 support.
> 
> 
> When program tries to append an item to a container it crashes.
> Debuggers stops at this line in qlist.h:
> 
> 
> template <typename T>
> 
> Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
> 
> {
> 
>     if (d->ref.isShared()) { // <== Here
> 
>         Node *n = detach_helper_grow(INT_MAX, 1);
> 
>         QT_TRY {
> 
>             node_construct(n, t);
> 
>         } QT_CATCH(...) {
> 
>             --d->end;
> 
>             QT_RETHROW;
> 
>         }
> 
> // ...
> 
> 
> Looking into functions that append calls, I found that node_construct
> contains some unsafe code:
> 
> 
> template <typename T>
> 
> Q_INLINE_TEMPLATE void QList<T>::node_construct(Node *n, const T &t)
> 
> {
> 
>     if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) n->v = new T(t);
> 
>     else if (QTypeInfo<T>::isComplex) new (n) T(t);
> 
> #if (defined(__GNUC__) || defined(__INTEL_COMPILER) ||
> defined(__IBMCPP__)) && !defined(__OPTIMIZE__)
> 
>     // This violates pointer aliasing rules, but it is known to be
> safe (and silent)
> 
>     // in unoptimized GCC builds (-fno-strict-aliasing). The other
> compilers which
> 
>     // set the same define are assumed to be safe.
> 
>     else *reinterpret_cast<T*>(n) = t;
> 
> #else
> 
>     // This is always safe, but penaltizes unoptimized builds a lot.
> 
>     else ::memcpy(n, static_cast<const void *>(&t), sizeof(T));
> 
> #endif
> 
> }
> 
> 
> I guess problem is same in detach_helper_grow function. Tried adding
> -fno-strict-aliasing to compile flags and defined __OPTIMIZE__. Also
> removed -O3 from compile flags, but no hope. So I have a couple of
> questions:
> * How bad are -O3 compiles? I've read that it's completely safe for
> well-written code but using optimization aggressively, may cause undefined
> behavior or even runtime crashes for bad codes. How is Qt code?
> * How can I solve this problem? (Using official builds is not preferred)
> * Do I need to recompile Qt with "-fno-strict-aliasing" flag or defining
> __OPTIMIZE__ ? Since templated classes are header-only and I already tried
> both in my project, I guess the answer is no.


Hi,

It is much more likely that the problem is somewhere else in your program.
Especially if you can reproduce the problem without optimisation.

I bet you have a dangling pointer somewhere in your application.

The reinterpret_cast there should be safe as the node are only accessed as T.

(memcpy is builtin, even in debug mode so the comment is wrong and the code 
could be simplified)

-- 
Olivier

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org




More information about the Development mailing list