summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2014-07-16 18:39:40 -0700
committerThiago Macieira <thiago.macieira@intel.com>2014-07-30 10:24:29 +0200
commit3866c89dee50e3a1156097f3f866e280b327ba28 (patch)
treef5206d39b727c966dc8abdb7b170133e828f5286 /src/corelib
parente7839d9717820a8f0049316c626d28fbcf252fa7 (diff)
Work around ICC bug in local static symbols for Q_GLOBAL_STATIC
When compiling the innerFunction() of the Q_GLOBAL_STATIC expansion, ICC emits global symbols for the internal "holder" local static variable and its guard. If there are two global statics of the same name in two different .cpp files, the linker will incorrectly merge the two "holder" variables. This was noted between the "customTypes" global statics of qmetatype.cpp and qdbusmetatype.cpp in a static build. The C++ standard requires that local static variables declared in inline functions must be the same, regardless of whether the body of the function got inlined or not. The IA-64 C++ ABI does that by requiring local static symbols for inline functions to be global and mergeable ("link once"). However, two functions in anonymous namespaces in different files are not considered to be the same function, so their local statics should not be merged. This is where ICC failed: the local statics are global and mergeable, even though the function is in an anonymous namespace. ICC correctly emits the function itself as a local symbol. Alternative solutions were: 1) add "static", but you can't use a static symbol in a template parameter in C++98 mode 2) remove the "inline" keyword, but then GCC 4.8 will not inline Intel issue ID: 6000058488 Task-number: QTBUG-40053 Change-Id: I307622222499682dde711b2771c8cf7557400799 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qglobalstatic.h11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index ad39452cf4..1c44569dbd 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -68,8 +68,17 @@ enum GuardValues {
// until the constructor returns ...
// We better avoid these kind of problems by using our own locked implementation.
+#if defined(Q_OS_UNIX) && defined(Q_CC_INTEL)
+// Work around Intel issue ID 6000058488:
+// local statics inside an inline function inside an anonymous namespace are global
+// symbols (this affects the IA-64 C++ ABI, so OS X and Linux only)
+# define Q_GLOBAL_STATIC_INTERNAL_DECORATION Q_DECL_HIDDEN
+#else
+# define Q_GLOBAL_STATIC_INTERNAL_DECORATION Q_DECL_HIDDEN inline
+#endif
+
#define Q_GLOBAL_STATIC_INTERNAL(ARGS) \
- Q_DECL_HIDDEN inline Type *innerFunction() \
+ Q_GLOBAL_STATIC_INTERNAL_DECORATION Type *innerFunction() \
{ \
struct HolderBase { \
~HolderBase() Q_DECL_NOTHROW \