From 3a726628f13c8f46b447cf0844eb8a5b740a1993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 6 May 2015 18:15:03 +0200 Subject: Android: Store and use the class names as key when caching. Previously the jclass handle was part of the key used for caching the class' methods and fields. Using the jclass handle is not ideal, but it meant that we could easily create a key when the only identifier we had was the jobject or jclass handle. However, in Android 5.1, the re-use of handles seems to be more aggressive and therefore increasing the chance of a collision in the cache look-up. This change removes caching for all calls where we don't know the class name, as that is the only thing that guarantees that we create unique keys for each class. The consequence of this is that only calls that provide a class name will benefit from the internal caching. Task-number: QTBUG-45748 Change-Id: I0039d04e7c068debc9e3b3983632c45dc8e52309 Reviewed-by: Frank Meerkoetter Reviewed-by: Alex Blasche --- src/corelib/kernel/qjni.cpp | 472 +++++++++++++++++++++++++++----------------- src/corelib/kernel/qjni_p.h | 1 + 2 files changed, 293 insertions(+), 180 deletions(-) diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 8431ee3b67..344f7725a0 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE static inline QString keyBase() { - return QStringLiteral("%1%2%3"); + return QStringLiteral("%1%2:%3"); } static QString qt_convertJString(jstring string) @@ -72,15 +72,15 @@ typedef QHash JClassHash; Q_GLOBAL_STATIC(JClassHash, cachedClasses) Q_GLOBAL_STATIC(QReadWriteLock, cachedClassesLock) -static QString toDotEncodedClassName(const char *className) +static QByteArray toBinaryEncClassName(const QByteArray &className) { - return QString::fromLatin1(className).replace(QLatin1Char('/'), QLatin1Char('.')); + return QByteArray(className).replace('/', '.'); } -static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0) +static jclass getCachedClass(const QByteArray &classBinEnc, bool *isCached = 0) { QReadLocker locker(cachedClassesLock); - const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const QHash::const_iterator &it = cachedClasses->constFind(QString::fromLatin1(classBinEnc)); const bool found = (it != cachedClasses->constEnd()); if (isCached != 0) @@ -89,10 +89,12 @@ static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0) return found ? it.value() : 0; } -static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) +inline static jclass loadClass(const QByteArray &className, JNIEnv *env, bool binEncoded = false) { + const QByteArray &binEncClassName = binEncoded ? className : toBinaryEncClassName(className); + bool isCached = false; - jclass clazz = getCachedClass(classDotEnc, &isCached); + jclass clazz = getCachedClass(binEncClassName, &isCached); if (clazz != 0 || isCached) return clazz; @@ -102,11 +104,12 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) QWriteLocker locker(cachedClassesLock); // did we lose the race? - const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const QLatin1String key(binEncClassName); + const QHash::const_iterator &it = cachedClasses->constFind(key); if (it != cachedClasses->constEnd()) return it.value(); - QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(classDotEnc); + QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(key); QJNIObjectPrivate classObject = classLoader.callObjectMethod("loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", stringName.object()); @@ -114,27 +117,40 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) if (!exceptionCheckAndClear(env) && classObject.isValid()) clazz = static_cast(env->NewGlobalRef(classObject.object())); - cachedClasses->insert(classDotEnc, clazz); + cachedClasses->insert(key, clazz); return clazz; } -inline static jclass loadClass(const char *className, JNIEnv *env) -{ - return loadClassDotEnc(toDotEncodedClassName(className), env); -} - typedef QHash JMethodIDHash; Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID) Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock) +static inline jmethodID getMethodID(JNIEnv *env, + jclass clazz, + const char *name, + const char *sig, + bool isStatic = false) +{ + jmethodID id = isStatic ? env->GetStaticMethodID(clazz, name, sig) + : env->GetMethodID(clazz, name, sig); + + if (exceptionCheckAndClear(env)) + return 0; + + return id; +} + static jmethodID getCachedMethodID(JNIEnv *env, jclass clazz, + const QByteArray &className, const char *name, const char *sig, bool isStatic = false) { - // TODO: We need to use something else then the ref. from clazz to avoid collisions. - const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + if (className.isEmpty()) + return getMethodID(env, clazz, name, sig, isStatic); + + const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig)); QHash::const_iterator it; { @@ -150,14 +166,7 @@ static jmethodID getCachedMethodID(JNIEnv *env, if (it != cachedMethodID->constEnd()) return it.value(); - jmethodID id = 0; - if (isStatic) - id = env->GetStaticMethodID(clazz, name, sig); - else - id = env->GetMethodID(clazz, name, sig); - - if (exceptionCheckAndClear(env)) - id = 0; + jmethodID id = getMethodID(env, clazz, name, sig, isStatic); cachedMethodID->insert(key, id); return id; @@ -168,13 +177,32 @@ typedef QHash JFieldIDHash; Q_GLOBAL_STATIC(JFieldIDHash, cachedFieldID) Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock) +static inline jfieldID getFieldID(JNIEnv *env, + jclass clazz, + const char *name, + const char *sig, + bool isStatic = false) +{ + jfieldID id = isStatic ? env->GetStaticFieldID(clazz, name, sig) + : env->GetFieldID(clazz, name, sig); + + if (exceptionCheckAndClear(env)) + return 0; + + return id; +} + static jfieldID getCachedFieldID(JNIEnv *env, jclass clazz, + const QByteArray &className, const char *name, const char *sig, bool isStatic = false) { - const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + if (className.isNull()) + return getFieldID(env, clazz, name, sig, isStatic); + + const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig)); QHash::const_iterator it; { @@ -190,14 +218,7 @@ static jfieldID getCachedFieldID(JNIEnv *env, if (it != cachedFieldID->constEnd()) return it.value(); - jfieldID id = 0; - if (isStatic) - id = env->GetStaticFieldID(clazz, name, sig); - else - id = env->GetFieldID(clazz, name, sig); - - if (exceptionCheckAndClear(env)) - id = 0; + jfieldID id = getFieldID(env, clazz, name, sig, isStatic); cachedFieldID->insert(key, id); return id; @@ -241,7 +262,7 @@ JNIEnv *QJNIEnvironmentPrivate::operator->() jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) { - const QString &classDotEnc = toDotEncodedClassName(className); + const QByteArray &classDotEnc = toBinaryEncClassName(className); bool isCached = false; jclass clazz = getCachedClass(classDotEnc, &isCached); @@ -250,9 +271,10 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) if (found) return clazz; + const QLatin1String key(classDotEnc); if (env != 0) { // We got an env. pointer (We expect this to be the right env. and call FindClass()) QWriteLocker locker(cachedClassesLock); - const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const QHash::const_iterator &it = cachedClasses->constFind(key); // Did we lose the race? if (it != cachedClasses->constEnd()) return it.value(); @@ -264,11 +286,11 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) } if (clazz != 0) - cachedClasses->insert(classDotEnc, clazz); + cachedClasses->insert(key, clazz); } if (clazz == 0) // We didn't get an env. pointer or we got one with the WRONG class loader... - clazz = loadClassDotEnc(classDotEnc, QJNIEnvironmentPrivate()); + clazz = loadClass(classDotEnc, QJNIEnvironmentPrivate(), true); return clazz; } @@ -309,11 +331,12 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className) : d(new QJNIObjectData()) { QJNIEnvironmentPrivate env; - d->m_jclass = loadClass(className, env); + d->m_className = toBinaryEncClassName(className); + d->m_jclass = loadClass(d->m_className, env, true); d->m_own_jclass = false; if (d->m_jclass) { // get default constructor - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", "()V"); + jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "", "()V"); if (constructorId) { jobject obj = env->NewObject(d->m_jclass, constructorId); if (obj) { @@ -328,10 +351,11 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, ... : d(new QJNIObjectData()) { QJNIEnvironmentPrivate env; - d->m_jclass = loadClass(className, env); + d->m_className = toBinaryEncClassName(className); + d->m_jclass = loadClass(d->m_className, env, true); d->m_own_jclass = false; if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "", sig); if (constructorId) { va_list args; va_start(args, sig); @@ -349,10 +373,11 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, con : d(new QJNIObjectData()) { QJNIEnvironmentPrivate env; - d->m_jclass = loadClass(className, env); + d->m_className = toBinaryEncClassName(className); + d->m_jclass = loadClass(d->m_className, env, true); d->m_own_jclass = false; if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "", sig); if (constructorId) { jobject obj = env->NewObjectV(d->m_jclass, constructorId, args); if (obj) { @@ -370,7 +395,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz) d->m_jclass = static_cast(env->NewGlobalRef(clazz)); if (d->m_jclass) { // get default constructor - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", "()V"); + jmethodID constructorId = getMethodID(env, d->m_jclass, "", "()V"); if (constructorId) { jobject obj = env->NewObject(d->m_jclass, constructorId); if (obj) { @@ -388,7 +413,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, ...) if (clazz) { d->m_jclass = static_cast(env->NewGlobalRef(clazz)); if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getMethodID(env, d->m_jclass, "", sig); if (constructorId) { va_list args; va_start(args, sig); @@ -410,7 +435,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, const QVaLis if (clazz) { d->m_jclass = static_cast(env->NewGlobalRef(clazz)); if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getMethodID(env, d->m_jclass, "", sig); if (constructorId) { jobject obj = env->NewObjectV(d->m_jclass, constructorId, args); if (obj) { @@ -430,15 +455,15 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj) QJNIEnvironmentPrivate env; d->m_jobject = env->NewGlobalRef(obj); - jclass objectClass = env->GetObjectClass(d->m_jobject); - d->m_jclass = static_cast(env->NewGlobalRef(objectClass)); - env->DeleteLocalRef(objectClass); + jclass cls = env->GetObjectClass(obj); + d->m_jclass = static_cast(env->NewGlobalRef(cls)); + env->DeleteLocalRef(cls); } template <> void QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { env->CallVoidMethodV(d->m_jobject, id, args); } @@ -458,7 +483,7 @@ jboolean QJNIObjectPrivate::callMethodV(const char *methodName, const { QJNIEnvironmentPrivate env; jboolean res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallBooleanMethodV(d->m_jobject, id, args); } @@ -480,7 +505,7 @@ jbyte QJNIObjectPrivate::callMethodV(const char *methodName, const char * { QJNIEnvironmentPrivate env; jbyte res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallByteMethodV(d->m_jobject, id, args); } @@ -502,7 +527,7 @@ jchar QJNIObjectPrivate::callMethodV(const char *methodName, const char * { QJNIEnvironmentPrivate env; jchar res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallCharMethodV(d->m_jobject, id, args); } @@ -524,7 +549,7 @@ jshort QJNIObjectPrivate::callMethodV(const char *methodName, const char { QJNIEnvironmentPrivate env; jshort res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallShortMethodV(d->m_jobject, id, args); } @@ -546,7 +571,7 @@ jint QJNIObjectPrivate::callMethodV(const char *methodName, const char *si { QJNIEnvironmentPrivate env; jint res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallIntMethodV(d->m_jobject, id, args); } @@ -568,7 +593,7 @@ jlong QJNIObjectPrivate::callMethodV(const char *methodName, const char * { QJNIEnvironmentPrivate env; jlong res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallLongMethodV(d->m_jobject, id, args); } @@ -590,7 +615,7 @@ jfloat QJNIObjectPrivate::callMethodV(const char *methodName, const char { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallFloatMethodV(d->m_jobject, id, args); } @@ -612,7 +637,7 @@ jdouble QJNIObjectPrivate::callMethodV(const char *methodName, const ch { QJNIEnvironmentPrivate env; jdouble res = 0.; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallDoubleMethodV(d->m_jobject, id, args); } @@ -692,7 +717,7 @@ void QJNIObjectPrivate::callStaticMethodV(const char *className, QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { env->CallStaticVoidMethodV(clazz, id, args); } @@ -718,7 +743,7 @@ void QJNIObjectPrivate::callStaticMethodV(jclass clazz, va_list args) { QJNIEnvironmentPrivate env; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { env->CallStaticVoidMethodV(clazz, id, args); } @@ -746,7 +771,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV(const char *className, jboolean res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticBooleanMethodV(clazz, id, args); } @@ -776,7 +801,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jboolean res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticBooleanMethodV(clazz, id, args); } @@ -807,7 +832,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV(const char *className, jbyte res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticByteMethodV(clazz, id, args); } @@ -837,7 +862,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jbyte res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticByteMethodV(clazz, id, args); } @@ -868,7 +893,7 @@ jchar QJNIObjectPrivate::callStaticMethodV(const char *className, jchar res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticCharMethodV(clazz, id, args); } @@ -898,7 +923,7 @@ jchar QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jchar res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticCharMethodV(clazz, id, args); } @@ -929,7 +954,7 @@ jshort QJNIObjectPrivate::callStaticMethodV(const char *className, jshort res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticShortMethodV(clazz, id, args); } @@ -959,7 +984,7 @@ jshort QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jshort res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticShortMethodV(clazz, id, args); } @@ -990,7 +1015,7 @@ jint QJNIObjectPrivate::callStaticMethodV(const char *className, jint res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticIntMethodV(clazz, id, args); } @@ -1020,7 +1045,7 @@ jint QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jint res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticIntMethodV(clazz, id, args); } @@ -1051,7 +1076,7 @@ jlong QJNIObjectPrivate::callStaticMethodV(const char *className, jlong res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticLongMethodV(clazz, id, args); } @@ -1081,7 +1106,7 @@ jlong QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jlong res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticLongMethodV(clazz, id, args); } @@ -1112,7 +1137,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV(const char *className, jfloat res = 0.f; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticFloatMethodV(clazz, id, args); } @@ -1142,7 +1167,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticFloatMethodV(clazz, id, args); } @@ -1173,7 +1198,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV(const char *className, jdouble res = 0.; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticDoubleMethodV(clazz, id, args); } @@ -1203,7 +1228,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jdouble res = 0.; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticDoubleMethodV(clazz, id, args); } @@ -1338,7 +1363,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethodV(const char *methodName, { QJNIEnvironmentPrivate env; jobject res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallObjectMethodV(d->m_jobject, id, args); if (res && env->ExceptionCheck()) @@ -1418,7 +1443,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(const char *classNa jobject res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticObjectMethodV(clazz, id, args); if (res && env->ExceptionCheck()) @@ -1450,7 +1475,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jobject res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticObjectMethodV(clazz, id, args); if (res && env->ExceptionCheck()) @@ -1479,7 +1504,7 @@ jboolean QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jboolean res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "Z"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z"); if (id) res = env->GetBooleanField(d->m_jobject, id); @@ -1491,7 +1516,7 @@ jbyte QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jbyte res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "B"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B"); if (id) res = env->GetByteField(d->m_jobject, id); @@ -1503,7 +1528,7 @@ jchar QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jchar res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "C"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C"); if (id) res = env->GetCharField(d->m_jobject, id); @@ -1515,7 +1540,7 @@ jshort QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jshort res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "S"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S"); if (id) res = env->GetShortField(d->m_jobject, id); @@ -1527,7 +1552,7 @@ jint QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jint res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "I"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I"); if (id) res = env->GetIntField(d->m_jobject, id); @@ -1539,7 +1564,7 @@ jlong QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jlong res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "J"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J"); if (id) res = env->GetLongField(d->m_jobject, id); @@ -1551,7 +1576,7 @@ jfloat QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "F"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F"); if (id) res = env->GetFloatField(d->m_jobject, id); @@ -1563,7 +1588,7 @@ jdouble QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jdouble res = 0.; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "D"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D"); if (id) res = env->GetDoubleField(d->m_jobject, id); @@ -1575,7 +1600,7 @@ jboolean QJNIObjectPrivate::getStaticField(jclass clazz, const char *f { QJNIEnvironmentPrivate env; jboolean res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "Z", true); + jfieldID id = getFieldID(env, clazz, fieldName, "Z", true); if (id) res = env->GetStaticBooleanField(clazz, id); @@ -1586,12 +1611,15 @@ template <> jboolean QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jboolean res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "Z", true); + if (id == 0) + return 0; + + return env->GetStaticBooleanField(clazz, id); } template <> @@ -1599,7 +1627,7 @@ jbyte QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa { QJNIEnvironmentPrivate env; jbyte res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "B", true); + jfieldID id = getFieldID(env, clazz, fieldName, "B", true); if (id) res = env->GetStaticByteField(clazz, id); @@ -1610,12 +1638,15 @@ template <> jbyte QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jbyte res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "B", true); + if (id == 0) + return 0; + + return env->GetStaticByteField(clazz, id); } template <> @@ -1623,7 +1654,7 @@ jchar QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa { QJNIEnvironmentPrivate env; jchar res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "C", true); + jfieldID id = getFieldID(env, clazz, fieldName, "C", true); if (id) res = env->GetStaticCharField(clazz, id); @@ -1634,12 +1665,15 @@ template <> jchar QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jchar res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "C", true); + if (id == 0) + return 0; + + return env->GetStaticCharField(clazz, id); } template <> @@ -1647,7 +1681,7 @@ jshort QJNIObjectPrivate::getStaticField(jclass clazz, const char *field { QJNIEnvironmentPrivate env; jshort res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "S", true); + jfieldID id = getFieldID(env, clazz, fieldName, "S", true); if (id) res = env->GetStaticShortField(clazz, id); @@ -1658,12 +1692,15 @@ template <> jshort QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jshort res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "S", true); + if (id == 0) + return 0; + + return env->GetStaticShortField(clazz, id); } template <> @@ -1671,7 +1708,7 @@ jint QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName { QJNIEnvironmentPrivate env; jint res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "I", true); + jfieldID id = getFieldID(env, clazz, fieldName, "I", true); if (id) res = env->GetStaticIntField(clazz, id); @@ -1682,12 +1719,15 @@ template <> jint QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jint res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "I", true); + if (id == 0) + return 0; + + return env->GetStaticIntField(clazz, id); } template <> @@ -1695,7 +1735,7 @@ jlong QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa { QJNIEnvironmentPrivate env; jlong res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "J", true); + jfieldID id = getFieldID(env, clazz, fieldName, "J", true); if (id) res = env->GetStaticLongField(clazz, id); @@ -1706,12 +1746,15 @@ template <> jlong QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jlong res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "J", true); + if (id == 0) + return 0; + + return env->GetStaticLongField(clazz, id); } template <> @@ -1719,7 +1762,7 @@ jfloat QJNIObjectPrivate::getStaticField(jclass clazz, const char *field { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "F", true); + jfieldID id = getFieldID(env, clazz, fieldName, "F", true); if (id) res = env->GetStaticFloatField(clazz, id); @@ -1730,12 +1773,15 @@ template <> jfloat QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jfloat res = 0.f; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0.f; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "F", true); + if (id == 0) + return 0.f; + + return env->GetStaticFloatField(clazz, id); } template <> @@ -1743,7 +1789,7 @@ jdouble QJNIObjectPrivate::getStaticField(jclass clazz, const char *fie { QJNIEnvironmentPrivate env; jdouble res = 0.; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "D", true); + jfieldID id = getFieldID(env, clazz, fieldName, "D", true); if (id) res = env->GetStaticDoubleField(clazz, id); @@ -1754,12 +1800,15 @@ template <> jdouble QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jdouble res = 0.; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0.; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "D", true); + if (id == 0) + return 0.; + + return env->GetStaticDoubleField(clazz, id); } QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName, @@ -1767,7 +1816,7 @@ QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName, { QJNIEnvironmentPrivate env; jobject res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig); if (id) { res = env->GetObjectField(d->m_jobject, id); if (res && env->ExceptionCheck()) @@ -1784,12 +1833,21 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(const char *className, const char *sig) { QJNIEnvironmentPrivate env; - QJNIObjectPrivate res; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticObjectField(clazz, fieldName, sig); + if (clazz == 0) + return QJNIObjectPrivate(); - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, sig, true); + if (id == 0) + return QJNIObjectPrivate(); + + jobject res = env->GetStaticObjectField(clazz, id); + if (res && env->ExceptionCheck()) + res = 0; + + QJNIObjectPrivate obj(res); + env->DeleteLocalRef(res); + return obj; } QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz, @@ -1798,7 +1856,7 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz, { QJNIEnvironmentPrivate env; jobject res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, sig, true); + jfieldID id = getFieldID(env, clazz, fieldName, sig, true); if (id) { res = env->GetStaticObjectField(clazz, id); if (res && env->ExceptionCheck()) @@ -1814,7 +1872,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jboolean value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "Z"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z"); if (id) env->SetBooleanField(d->m_jobject, id, value); @@ -1824,7 +1882,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jbyte value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "B"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B"); if (id) env->SetByteField(d->m_jobject, id, value); @@ -1834,7 +1892,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jchar value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "C"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C"); if (id) env->SetCharField(d->m_jobject, id, value); @@ -1844,7 +1902,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jshort value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "S"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S"); if (id) env->SetShortField(d->m_jobject, id, value); @@ -1854,7 +1912,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jint value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "I"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I"); if (id) env->SetIntField(d->m_jobject, id, value); @@ -1864,7 +1922,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jlong value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "J"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J"); if (id) env->SetLongField(d->m_jobject, id, value); @@ -1874,7 +1932,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jfloat value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "F"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F"); if (id) env->SetFloatField(d->m_jobject, id, value); @@ -1884,7 +1942,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jdouble value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "D"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D"); if (id) env->SetDoubleField(d->m_jobject, id, value); @@ -1894,7 +1952,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jbooleanArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[Z"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[Z"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1904,7 +1962,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jbyteArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[B"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[B"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1914,7 +1972,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jcharArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[C"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[C"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1924,7 +1982,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jshortArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[S"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[S"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1934,7 +1992,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jintArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[I"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[I"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1944,7 +2002,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jlongArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[J"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[J"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1954,7 +2012,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jfloatArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[F"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[F"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1964,7 +2022,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jdoubleArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[D"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[D"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1974,7 +2032,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jstring value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "Ljava/lang/String;"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Ljava/lang/String;"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1986,7 +2044,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jobject value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1998,7 +2056,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jobjectArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -2010,7 +2068,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jboolean value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "Z", true); + jfieldID id = getFieldID(env, clazz, fieldName, "Z", true); if (id) env->SetStaticBooleanField(clazz, id, value); } @@ -2022,8 +2080,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "Z", true); + if (id == 0) + return; + + env->SetStaticBooleanField(clazz, id, value); } template <> @@ -2032,7 +2096,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jbyte value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "B", true); + jfieldID id = getFieldID(env, clazz, fieldName, "B", true); if (id) env->SetStaticByteField(clazz, id, value); } @@ -2044,8 +2108,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "B", true); + if (id == 0) + return; + + env->SetStaticByteField(clazz, id, value); } template <> @@ -2054,7 +2124,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jchar value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "C", true); + jfieldID id = getFieldID(env, clazz, fieldName, "C", true); if (id) env->SetStaticCharField(clazz, id, value); } @@ -2066,8 +2136,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "C", true); + if (id == 0) + return; + + env->SetStaticCharField(clazz, id, value); } template <> @@ -2076,7 +2152,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jshort value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "S", true); + jfieldID id = getFieldID(env, clazz, fieldName, "S", true); if (id) env->SetStaticShortField(clazz, id, value); } @@ -2088,8 +2164,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "S", true); + if (id == 0) + return; + + env->SetStaticShortField(clazz, id, value); } template <> @@ -2098,7 +2180,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jint value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "I", true); + jfieldID id = getFieldID(env, clazz, fieldName, "I", true); if (id) env->SetStaticIntField(clazz, id, value); } @@ -2110,8 +2192,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "I", true); + if (id == 0) + return; + + env->SetStaticIntField(clazz, id, value); } template <> @@ -2120,7 +2208,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jlong value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "J", true); + jfieldID id = getFieldID(env, clazz, fieldName, "J", true); if (id) env->SetStaticLongField(clazz, id, value); } @@ -2132,8 +2220,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "J", true); + if (id == 0) + return; + + env->SetStaticLongField(clazz, id, value); } template <> @@ -2142,7 +2236,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jfloat value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "F", true); + jfieldID id = getFieldID(env, clazz, fieldName, "F", true); if (id) env->SetStaticFloatField(clazz, id, value); } @@ -2154,8 +2248,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "F", true); + if (id == 0) + return; + + env->SetStaticFloatField(clazz, id, value); } template <> @@ -2164,7 +2264,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jdouble value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "D", true); + jfieldID id = getFieldID(env, clazz, fieldName, "D", true); if (id) env->SetStaticDoubleField(clazz, id, value); } @@ -2176,8 +2276,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "D", true); + if (id == 0) + return; + + env->SetStaticDoubleField(clazz, id, value); } template <> @@ -2187,7 +2293,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jobject value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, sig, true); + jfieldID id = getFieldID(env, clazz, fieldName, sig, true); if (id) env->SetStaticObjectField(clazz, id, value); } @@ -2200,8 +2306,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, sig, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, sig, true); + if (id == 0) + return; + + env->SetStaticObjectField(clazz, id, value); } QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string) diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h index fb1982dc74..a62e9ee056 100644 --- a/src/corelib/kernel/qjni_p.h +++ b/src/corelib/kernel/qjni_p.h @@ -74,6 +74,7 @@ public: jobject m_jobject; jclass m_jclass; bool m_own_jclass; + QByteArray m_className; }; class Q_CORE_EXPORT QJNIObjectPrivate -- cgit v1.2.3 From a1ada382ff00a8e1599aba22ee06ff53ce478666 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 30 Apr 2015 15:09:59 +0200 Subject: Handle parsing of GL_VERSION as reported by Nexus 6 The Nexus 6 device reports a GL_VERSION which is strictly not conformant to what is expected from GL_VERSION, so a check is added for this case so that it correctly detects the right OpenGL ES version. Change-Id: I00297dd7c1e505dd7f9ab8a7fa480f514162b488 Reviewed-by: Laszlo Agocs --- src/gui/kernel/qplatformopenglcontext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/kernel/qplatformopenglcontext.cpp b/src/gui/kernel/qplatformopenglcontext.cpp index 527bfdd983..364c1a5c0e 100644 --- a/src/gui/kernel/qplatformopenglcontext.cpp +++ b/src/gui/kernel/qplatformopenglcontext.cpp @@ -121,6 +121,10 @@ bool QPlatformOpenGLContext::parseOpenGLVersion(const QByteArray &versionString, if (versionParts.size() >= 2) { major = versionParts.at(0).toInt(&majorOk); minor = versionParts.at(1).toInt(&minorOk); + // Nexus 6 has "OpenGL ES 3.0V@95.0 (GIT@I86da836d38)" + if (!minorOk) + if (int idx = versionParts.at(1).indexOf('V')) + minor = versionParts.at(1).left(idx).toInt(&minorOk); } else { qWarning("Unrecognized OpenGL ES version"); } -- cgit v1.2.3 From 3eca75de67b3fd2c890715b30c7899cebc096fe9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 11 May 2015 18:30:00 +0900 Subject: Make qglobal.h complain if you use -fPIE Prior to Qt 5.4.2 (commit 36d6eb721e7d5997ade75e289d4088dc48678d0d), we allowed it, but now we need to enforce that it is not used. Note that -fPIE does define __PIC__, so we need this to catch the use of -fPIE. [ChangeLog][Important Behavior Changes] On x86 and x86-64 systems with ELF binaries (especially Linux), due to a new optimization in GCC 5.x in combination with a recent version of GNU binutils, compiling Qt applications with -fPIE is no longer enough. Applications now need to be compiled with the -fPIC option if Qt's option "reduce relocations" is active. Note that Clang is known to generate incompatible code even with -fPIC if the -flto option is active. Task-number: QTBUG-45755 Change-Id: I66a35ce5f88941f29aa6ffff13dd210e0aa2728f Reviewed-by: Dmitry Shachnev Reviewed-by: Simon Hausmann --- dist/changes-5.4.2 | 7 +++++++ src/corelib/global/qglobal.h | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/dist/changes-5.4.2 b/dist/changes-5.4.2 index e1ad9b6846..5827187e9e 100644 --- a/dist/changes-5.4.2 +++ b/dist/changes-5.4.2 @@ -34,6 +34,13 @@ information about a particular change. common EXIF-format (big-endian) was not working until 5.4.1. 5.4.2 restores the behavior of 5.4.0 and earlier for most EXIF-tagged JPEGs. EXIF orientation will be an opt-in starting with Qt 5.5. +- On x86 and x86-64 systems with ELF binaries (especially Linux), due to + a new optimization in GCC 5.x in combination with a recent version of + GNU binutils, compiling Qt applications with -fPIE is no longer + enough. Applications now need to be compiled with the -fPIC option if + Qt's option "reduce relocations" is active. Note that Clang is known + to generate incompatible code even with -fPIC if the -flto option is + active. **************************************************************************** * Library * diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index ef84662036..4547877da6 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1047,9 +1047,9 @@ Q_CORE_EXPORT int qrand(); # define QT_NO_SHAREDMEMORY #endif -#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) +#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && (!defined(__PIC__) || defined(__PIE__)) # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ - "Compile your code with -fPIC." + "Compile your code with -fPIC (-fPIE is not enough)." #endif namespace QtPrivate { -- cgit v1.2.3 From 5a3251a0324d65d688c3702a327d7a71a0de5ab9 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 22 Apr 2015 15:43:50 +0200 Subject: Doc: fix QSystemSemaphore example acquire() doesn't take arguments. Change-Id: I16f0169c40433cc3cbfcb577bd8386d217cccb12 Task-number: QTBUG-40055 Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- .../doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp index bc03770f16..9cded446d1 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp @@ -51,8 +51,9 @@ sem.release(2); // resources available == 3 //! [1] QSystemSemaphore sem("market", 5, QSystemSemaphore::Create); -sem.acquire(5); // acquire all 5 resources -sem.release(5); // release the 5 resources +for (int i = 0; i < 5; ++i) // acquire all 5 resources + sem.acquire(); +sem.release(5); // release the 5 resources //! [1] -- cgit v1.2.3 From 2023b9e76baf8d8a3b1ea59748624e16f3297ac3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 22 Apr 2015 14:18:20 +0200 Subject: Doc: clarify ownership after QStackedWidget::removeWidget Change-Id: Ia14b72cdac3205a3896c47ecc81b31adb508181b Task-number: QTBUG-44891 Reviewed-by: Leena Miettinen --- src/widgets/widgets/qstackedwidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qstackedwidget.cpp b/src/widgets/widgets/qstackedwidget.cpp index fd1bf57321..411651f480 100644 --- a/src/widgets/widgets/qstackedwidget.cpp +++ b/src/widgets/widgets/qstackedwidget.cpp @@ -182,7 +182,9 @@ int QStackedWidget::insertWidget(int index, QWidget *widget) not deleted but simply removed from the stacked layout, causing it to be hidden. - \b{Note:} Ownership of \a widget reverts to the application. + \note Parent object and parent widget of \a widget will remain the + QStackedWidget. If the application wants to reuse the removed + \a widget, then it is recommended to re-parent it. \sa addWidget(), insertWidget(), currentWidget() */ -- cgit v1.2.3 From d14397b7298879e260bc7218a5f7539b6b94a2cf Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 12 May 2015 17:11:00 +0200 Subject: Windows: Fix exit crash of GUI applications when deleting argv[]. When passing Qt arguments followed by normal arguments, a double deletion may occur due to Qt shifting argv. For example: argv[] = app -qwindowgeometry +50+50 some_arg becomes: argv[] = app some_arg some_arg Terminate deletion when encountering the null pointer. Change-Id: I5279955b6bd463f5858d6e5e8e16a1f5d0945652 Reviewed-by: Joerg Bornemann --- src/winmain/qtmain_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/winmain/qtmain_win.cpp b/src/winmain/qtmain_win.cpp index 25b79543ba..459ca114a6 100644 --- a/src/winmain/qtmain_win.cpp +++ b/src/winmain/qtmain_win.cpp @@ -111,7 +111,7 @@ extern "C" int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR /*cmdParamarg*/, int argv[argc] = Q_NULLPTR; LocalFree(argvW); const int exitCode = main(argc, argv); - for (int i = 0; i < argc; ++i) + for (int i = 0; i < argc && argv[i]; ++i) delete [] argv[i]; delete [] argv; return exitCode; -- cgit v1.2.3 From 50c41bc8efb52b2b3f2aad66d79167320e9b2b31 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 24 Nov 2014 14:53:05 +0100 Subject: Doc: corrected autolink issues statemachine.qdoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-40362 Change-Id: Ia686ebdfd722f448aa30fb1f1f266b6148df4026 Reviewed-by: Topi Reiniö --- src/corelib/doc/src/statemachine.qdoc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/corelib/doc/src/statemachine.qdoc b/src/corelib/doc/src/statemachine.qdoc index 846eb7d1f0..4b50174b88 100644 --- a/src/corelib/doc/src/statemachine.qdoc +++ b/src/corelib/doc/src/statemachine.qdoc @@ -63,7 +63,7 @@ used to effectively embed the elements and semantics of statecharts in Qt applications. The framework integrates tightly with Qt's meta-object system; for example, transitions between states can be triggered by signals, and - states can be configured to set properties and invoke methods on QObjects. + states can be configured to set properties and invoke methods on {QObject}s. Qt's event system is used to drive the state machines. The state graph in the State Machine framework is hierarchical. States can be nested inside of @@ -126,9 +126,9 @@ The QState::entered() signal is emitted when the state is entered, and the QState::exited() signal is emitted when the state is exited. In the - following snippet, the button's showMaximized() slot will be called when - state \c s3 is entered, and the button's showMinimized() slot will be called - when \c s3 is exited: + following snippet, the button's \l {QPushButton::}{showMaximized()} slot + will be called when state \c s3 is entered, and the button's \l {QPushButton::}{showMinimized()} + slot will be called when \c s3 is exited: \snippet statemachine/main.cpp 5 @@ -151,7 +151,7 @@ Assume we wanted the user to be able to quit the application at any time by clicking a Quit button. In order to achieve this, we need to create a final state and make it the target of a transition associated with the Quit - button's clicked() signal. We could add a transition from each of \c s1, \c + button's \l{QPushButton::}{clicked()} signal. We could add a transition from each of \c s1, \c s2 and \c s3; however, this seems redundant, and one would also have to remember to add such a transition from every new state that is added in the future. @@ -184,8 +184,8 @@ \snippet statemachine/main2.cpp 1 In this case we want the application to quit when the state machine is - finished, so the machine's finished() signal is connected to the - application's quit() slot. + finished, so the machine's \l {QStateMachine::}{finished()} signal is connected to the + application's \l {QCoreApplication::}{quit()} slot. A child state can override an inherited transition. For example, the following code adds a transition that effectively causes the Quit button to @@ -290,7 +290,7 @@ \endomit When \c s1 's final state is entered, \c s1 will automatically emit - finished(). We use a signal transition to cause this event to trigger a + \l {QState::}{finished()}. We use a signal transition to cause this event to trigger a state change: \snippet statemachine/main3.cpp 1 @@ -302,7 +302,7 @@ encapsulation mechanism when building complex (deeply nested) state machines. (In the above example, you could of course create a transition directly from \c s1 's \c done state rather than relying on \c s1 's - finished() signal, but with the consequence that implementation details of + \l {QState::}{finished()} signal, but with the consequence that implementation details of \c s1 are exposed and depended on). For parallel state groups, the QState::finished() signal is emitted when \e @@ -365,8 +365,8 @@ \snippet statemachine/main4.cpp 1 - In the eventTest() reimplementation, we first check if the event type is the - desired one; if so, we cast the event to a StringEvent and perform the + In the \l {QAbstractTransition::}{eventTest()} reimplementation, we first check if the event type is the + desired one; if so, we cast the event to a \c StringEvent and perform the string comparison. The following is a statechart that uses the custom event and transition: @@ -486,7 +486,7 @@ message box will pop up before the geometry of the button has actually been set. To ensure that the message box does not pop up until the geometry actually reaches its final - value, we can use the state's propertiesAssigned() signal. The propertiesAssigned() signal will be + value, we can use the state's \l {QState::}{propertiesAssigned()} signal. The \l {QState::}{propertiesAssigned()} signal will be emitted when the property is assigned its final value, whether this is done immediately or after the animation has finished playing. @@ -503,14 +503,14 @@ has been assigned the defined value. If the global restore policy is set to QStateMachine::RestoreProperties, the state will not emit - the propertiesAssigned() signal until these have been executed as well. + the \l {QState::}{propertiesAssigned()} signal until these have been executed as well. \section1 What Happens If A State Is Exited Before The Animation Has Finished If a state has property assignments, and the transition into the state has animations for the properties, the state can potentially be exited before the properties have been assigned to the values defines by the state. This is true in particular when there are transitions out from the - state that do not depend on the propertiesAssigned signal, as described in the previous section. + state that do not depend on the \l {QState::}{propertiesAssigned()} signal, as described in the previous section. The State Machine API guarantees that a property assigned by the state machine either: \list @@ -563,13 +563,13 @@ The parent state machine treats the child machine as an \e atomic state in the state machine algorithm. The child state machine is self-contained; it maintains its own event queue and - configuration. In particular, note that the \l{QStateMachine::configuration()}{configuration} + configuration. In particular, note that the \l{QStateMachine::}{configuration()} of the child machine is not part of the parent machine's configuration (only the child machine itself is). States of the child state machine cannot be specified as targets of transitions in the parent state machine; only the child state machine itself can. Conversely, states of the parent state machine cannot be specified as targets of transitions in the child state machine. The child - state machine's \l{QState::finished()}{finished}() signal can be used to trigger a transition + state machine's \l{QState::}{finished}() signal can be used to trigger a transition in the parent machine. */ -- cgit v1.2.3 From 083c9269ed73e8771e1dbe10812696b45b7389f3 Mon Sep 17 00:00:00 2001 From: Evangelos Foutras Date: Mon, 11 May 2015 12:20:57 +0300 Subject: Try to ensure that -fPIC is used in CMake builds In commit 36d6eb721e7d5997ade75e289d4088dc48678d0d the -fPIE switch was replaced with -fPIC in an effort to avoid generating copy relocations which are incompatible with Qt5 when built with -reduce-relocations. Task-number: QTBUG-45755 Change-Id: I59a55ea15052f498104848c5fd867e563ddc2290 Reviewed-by: Thiago Macieira --- src/corelib/Qt5CoreConfigExtras.cmake.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 48d5f21447..d4abc5f271 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -70,8 +70,9 @@ set(_qt5_corelib_extra_includes) # Qt5_POSITION_INDEPENDENT_CODE variable is used in the # qt5_use_module # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) -set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") +set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") +set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}) !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) -- cgit v1.2.3 From 189280026f091716dfda91ff652cc20b299683c2 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 13 May 2015 14:33:10 +0200 Subject: xcode generator: use absolute path when creating PBXFileReferences for libraries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the Xcode generator uses "sourceTree = " for all PBXFileReferences. But the paths we use for referencing libraries are relative. This patch will change this, so that we always use absolute paths to be consequent. This will fix a crash in Xcode that happens when opening projects generated by Qt. Change-Id: I3a372b93598a777c96ba353205cf19710a5923f5 Task-number: QTBUG-45966 Reviewed-by: Tor Arne Vestbø Reviewed-by: Oswald Buddenhagen --- qmake/generators/mac/pbuilder_pbx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 8f24c20712..b54f634cf9 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -950,7 +950,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!path.isEmpty() && !libdirs.contains(path)) libdirs += path; } - library = fileFixify(library); + library = fileFixify(library, FileFixifyAbsolute); QString filetype = xcodeFiletypeForFilename(library); QString key = keyFor(library); if (!project->values("QMAKE_PBX_LIBRARIES").contains(key)) { -- cgit v1.2.3 From 3f0f707d4b898a96e63e16c13a29f12be01d9b4c Mon Sep 17 00:00:00 2001 From: Mikhail Lappo Date: Thu, 7 May 2015 12:18:14 +0300 Subject: Prevent bad-ptrs deref in QNetworkConfigurationManagerPrivate Prevent application to crash with segfault in Qt bearer thread. Corrected hardly reproduceable bug, when QNetworkConfigurationManagerPrivate in pollEngines slot dereferenced null and bad pointers and caused crash Task-number: QTBUG-44407 Change-Id: I2f0b11b2d10125a21a62588d76ad824f375e4a1d Reviewed-by: Richard J. Moore --- src/network/bearer/qnetworkconfigmanager_p.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 6bbea1683c..b963aebbd5 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -75,6 +75,7 @@ QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate() QMutexLocker locker(&mutex); qDeleteAll(sessionEngines); + sessionEngines.clear(); if (bearerThread) bearerThread->quit(); } -- cgit v1.2.3 From 20e36879d72f840005a0361368985b72ce4dc6a4 Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Fri, 15 May 2015 14:42:45 +0200 Subject: Doc: Excluded qdoc files that caused unnecessary Qt Creator warnings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The customcompleter and textcodes are widget examples, but they end up in the Qt Core exampledirs boundary because of a reference to the plugandpaint example in the docs. This resulted in a couple of wrong entries being written into the examples-manifest.xml, which is used by Qt Creator. This change explicitly exludes the qdoc pages for the two examples so that qdoc doesn't add the corresponding entries into examples-manifest.xml. Task-number: QTBUG-41996 Change-Id: I0e95b6d4d93e0ce18f5b34e5034b279598b4924f Reviewed-by: Topi Reiniö Reviewed-by: Martin Smith --- src/corelib/doc/qtcore.qdocconf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index f3aff83a8b..a166df1143 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -42,5 +42,8 @@ imagedirs += images excludedirs += snippets +excludefiles += ../../../examples/widgets/tools/customcompleter/doc/src/customcompleter.qdoc \ + ../../../examples/widgets/tools/codecs/doc/src/codecs.qdoc + navigation.landingpage = "Qt Core" navigation.cppclassespage = "Qt Core C++ Classes" -- cgit v1.2.3 From 938f9fc0f8ff1575413ca3d6d66860b5fa315768 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 19 May 2015 16:07:42 +0200 Subject: Workaround for Samsung keyboard bug Return null string instead of empty string when the selection is empty. It looks like Samsung just tests for selection == null when doing backspace. Task-number: QTBUG-45785 Change-Id: Iaa006a8ffe52b2704c7348646dde9ca4e1f78c5c Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/qandroidinputcontext.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 7e81735de9..7264f9a74c 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -176,6 +176,8 @@ static jstring getSelectedText(JNIEnv *env, jobject /*thiz*/, jint flags) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug() << "@@@ GETSEL" << text; #endif + if (text.isEmpty()) + return 0; return env->NewString(reinterpret_cast(text.constData()), jsize(text.length())); } -- cgit v1.2.3 From d4a296b538da93f5c915fc7e886c6995f1b41169 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 20 May 2015 13:35:07 +0200 Subject: Do not modify decoder when determining image-format We should not configure the decoder when just determining the image- format. Doing so can cause all versions of libpng to print a warning, and some versions to fail to decode. The code appears to be a leftover from when the image-format logic was copied out of the introduction of the decoding method, where the proper settings are still applied. Task-number: QTBUG-46233 Change-Id: I6619728804f040ae6c9d637c7298a8586e22499e Reviewed-by: Andy Shaw Reviewed-by: aavit --- src/gui/image/qpnghandler.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 17a0dd3eb9..304ab0cf3e 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -674,16 +674,9 @@ QImage::Format QPngHandlerPrivate::readImageFormat() && num_palette <= 256) { // 1-bit and 8-bit color - if (bit_depth != 1) - png_set_packing(png_ptr); - png_read_update_info(png_ptr, info_ptr); - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8; } else { // 32-bit - if (bit_depth == 16) - png_set_strip_16(png_ptr); - format = QImage::Format_ARGB32; // Only add filler if no alpha, or we can get 5 channel data. if (!(color_type & PNG_COLOR_MASK_ALPHA) -- cgit v1.2.3 From e96ad10fd8f1d6badfe8ff7befbd397d5cbfe2b4 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 20 May 2015 19:28:44 +0200 Subject: Ensure the same behavior on Win as Unix re the host in isApparentlyStale When the hostname is empty then it is assumed that the lock file is from the same host as the one running the application. Change-Id: Iba8aefc171a209294371dc2022d93ede3035b242 Reviewed-by: Will Wagner Reviewed-by: David Faure --- src/corelib/io/qlockfile_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index 3587c7bffe..21ab8f8fea 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -120,7 +120,7 @@ bool QLockFilePrivate::isApparentlyStale() const // processes due to sandboxing #ifndef Q_OS_WINRT if (getLockInfo(&pid, &hostname, &appname)) { - if (hostname == QString::fromLocal8Bit(localHostName())) { + if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (!procHandle) return true; -- cgit v1.2.3 From 7a4f3645f44bae78987facbf4e39231d0d2882ef Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sat, 23 May 2015 12:11:09 +0100 Subject: Avoid false positives from google by storing OpenSSL version as Unicode. Google scan play store apps for the openssl version string which leads to false positives since we record the version we were compiled against even though we don't link it directly. Task-number: QTBUG-46265 Change-Id: Iefd0e0954149c17350d49f57f9f374938124d7b8 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/network/ssl/qsslsocket_openssl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index b132aec038..ac4336afcc 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -588,7 +588,10 @@ long QSslSocketPrivate::sslLibraryBuildVersionNumber() QString QSslSocketPrivate::sslLibraryBuildVersionString() { - return QLatin1String(OPENSSL_VERSION_TEXT); + // Using QStringLiteral to store the version string as unicode and + // avoid false positives from Google searching the playstore for old + // SSL versions. See QTBUG-46265 + return QStringLiteral(OPENSSL_VERSION_TEXT); } /*! -- cgit v1.2.3 From ab156fcedd4c2d2856c0b46699c32926288be292 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 17 Apr 2015 08:04:04 +0200 Subject: Use the new non-obsoleted functions for getting the paper details This fixes a problem with the margins not being correctly respected as the functions introduced previously would set a different property to what was being queried in this case. Change-Id: I3458c8e46239276a296d17aa80da7330c85fcf0a Reviewed-by: Friedemann Kleint --- src/printsupport/widgets/qprintpreviewwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/printsupport/widgets/qprintpreviewwidget.cpp b/src/printsupport/widgets/qprintpreviewwidget.cpp index 208ad5e0f3..7898dc9352 100644 --- a/src/printsupport/widgets/qprintpreviewwidget.cpp +++ b/src/printsupport/widgets/qprintpreviewwidget.cpp @@ -335,8 +335,8 @@ void QPrintPreviewWidgetPrivate::populateScene() pages.clear(); int numPages = pictures.count(); - QSize paperSize = printer->paperRect().size(); - QRect pageRect = printer->pageRect(); + QSize paperSize = printer->pageLayout().fullRectPixels(printer->resolution()).size(); + QRect pageRect = printer->pageLayout().paintRectPixels(printer->resolution()); for (int i = 0; i < numPages; i++) { PageItem* item = new PageItem(i+1, pictures.at(i), paperSize, pageRect); -- cgit v1.2.3 From 79be2601225bdb50cab72e2502b7d7f9ee81e94f Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 17 Apr 2015 08:10:10 +0200 Subject: Fix documentation of obsoleted functions to show the right replacement Change-Id: Ib008a5544d68d93e1f96ff6b7504e9a7ea4bb192 Reviewed-by: Friedemann Kleint --- src/printsupport/kernel/qprinter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index 8ed2732c1e..d7df796afb 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -1764,7 +1764,7 @@ QRectF QPrinter::paperRect(Unit unit) const } /*! - \obsolete Use pageLayout().paintRect() instead. + \obsolete Use pageLayout().paintRectPixels(resolution()) instead. Returns the page's rectangle; this is usually smaller than the paperRect() since the page normally has margins between its @@ -1781,7 +1781,7 @@ QRect QPrinter::pageRect() const } /*! - \obsolete Use pageLayout().fullPageRect() instead. + \obsolete Use pageLayout().fullRectPixels(resolution()) instead. Returns the paper's rectangle; this is usually larger than the pageRect(). -- cgit v1.2.3 From 18be63de2a5588ea6ac4b9ffe8de176aabe8bd83 Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Mon, 18 May 2015 15:47:51 +0200 Subject: Doc: Added the missing \brief and \image for example docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Qt TestLib examples are just tutorials so updated the qdocconf to use the default thumbnail in the Qt Creator welcome screen. Task-number: QTBUG-41996 Change-Id: Ia04a42a92e414c97a426b6095a62621a348e7de0 Reviewed-by: Topi Reiniö Reviewed-by: Martin Smith --- examples/widgets/doc/images/imagegestures-example.jpg | Bin 0 -> 38962 bytes examples/widgets/doc/src/plugandpaint.qdoc | 9 +++++++-- .../gestures/imagegestures/doc/src/imagegestures.qdoc | 3 +++ src/testlib/doc/qttestlib.qdocconf | 3 +++ src/xml/doc/qtxml.qdocconf | 3 +++ 5 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 examples/widgets/doc/images/imagegestures-example.jpg diff --git a/examples/widgets/doc/images/imagegestures-example.jpg b/examples/widgets/doc/images/imagegestures-example.jpg new file mode 100644 index 0000000000..c8484b4a71 Binary files /dev/null and b/examples/widgets/doc/images/imagegestures-example.jpg differ diff --git a/examples/widgets/doc/src/plugandpaint.qdoc b/examples/widgets/doc/src/plugandpaint.qdoc index 4e48245bd9..caf33feb0a 100644 --- a/examples/widgets/doc/src/plugandpaint.qdoc +++ b/examples/widgets/doc/src/plugandpaint.qdoc @@ -30,8 +30,7 @@ \title Plug & Paint Example \ingroup examples-widgets-tools - \brief The Plug & Paint example demonstrates how to write Qt - applications that can be extended through plugins. + \brief Demonstrates how to extend Qt applications using plugins. \image plugandpaint.png Screenshot of the Plug & Paint example @@ -314,6 +313,9 @@ /*! \example tools/plugandpaintplugins/basictools \title Plug & Paint Basic Tools Example + \brief A plugin providing the basic tools for painting functionality. + + \image plugandpaint.png Screenshot of the Plug & Paint example The Basic Tools example is a static plugin for the \l{tools/plugandpaint}{Plug & Paint} example. It provides a set @@ -499,6 +501,9 @@ /*! \example tools/plugandpaintplugins/extrafilters \title Plug & Paint Extra Filters Example + \brief A plugin providing the extra filters. + + \image plugandpaint.png Screenshot of the Plug & Paint example The Extra Filters example is a plugin for the \l{tools/plugandpaint}{Plug & Paint} example. It provides a set diff --git a/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc b/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc index d6d215d6bd..6a1405b0b1 100644 --- a/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc +++ b/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc @@ -28,10 +28,13 @@ /*! \example gestures/imagegestures \title Image Gestures Example + \brief Demonstrates the use of simple gestures in a widget This example shows how to enable gestures for a widget and use gesture input to perform actions. + \image imagegestures-example.jpg + We use two classes to create the user interface for the application: \c MainWidget and \c ImageWidget. The \c MainWidget class is simply used as a container for the \c ImageWidget class, which we will configure to accept gesture input. Since we diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf index 35b4fbcb7b..0fafc733b1 100644 --- a/src/testlib/doc/qttestlib.qdocconf +++ b/src/testlib/doc/qttestlib.qdocconf @@ -40,5 +40,8 @@ excludedirs += ../../../examples/widgets/doc imagedirs += images +# Add a thumbnail for examples that do not have images +manifestmeta.thumbnail.names = "QtTestLib/Chapter *" + navigation.landingpage = "Qt Test" navigation.cppclassespage = "Qt Test C++ Classes" diff --git a/src/xml/doc/qtxml.qdocconf b/src/xml/doc/qtxml.qdocconf index 8ca421ff4e..419859ac8b 100644 --- a/src/xml/doc/qtxml.qdocconf +++ b/src/xml/doc/qtxml.qdocconf @@ -40,3 +40,6 @@ imagedirs += images \ navigation.landingpage = "Qt XML" navigation.cppclassespage = "Qt XML C++ Classes" + +# Add a thumbnail for examples that do not have images +manifestmeta.thumbnail.names = "QtXml/XML Stream Lint Example" -- cgit v1.2.3 From 8829ce67d8d0eac90e9fd6fde088b41f157177a5 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 25 May 2015 14:55:38 +0200 Subject: Only add -fPIC flags for compilers known to require it. Commit 083c9269 (Try to ensure that -fPIC is used in CMake builds, 2015-05-11) added a raw -fPIC to the INTERFACE_COMPILE_OPTIONS of Qt5::Core, which affects all consuming compilers. Use the qmake variable $$QMAKE_CXXFLAGS_APP instead, which at least currently contains only the -fPIC variable or harmlessly expands to nothing. If the content of that qmake variable changes in the future, a $$QMAKE_CXXFLAGS_APP_PIC variable should be extracted in qmake and used here. Don't use the POSITION_INDEPENDENT_CODE feature of CMake. That adds the -fPIE flag for executables, which is explicitly what qglobal.h forbids since commit 3eca75de (Make qglobal.h complain if you use -fPIE, 2015-05-11). The current behavior of that CMake feature is tracked here: http://public.kitware.com/Bug/view.php?id=15570 Change-Id: I5c5bcc40fe4b310b55a681a3505f45c50adfa054 Reviewed-by: Oswald Buddenhagen Reviewed-by: Simon Hausmann --- src/corelib/Qt5CoreConfigExtras.cmake.in | 3 +-- src/corelib/Qt5CoreMacros.cmake | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index d4abc5f271..a5cab880ba 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -71,8 +71,7 @@ set(_qt5_corelib_extra_includes) # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") -set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") -set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}) +set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 9c81754302..c10880f787 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -281,10 +281,6 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.9) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG) - - if (Qt5_POSITION_INDEPENDENT_CODE) - set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE}) - endif() endforeach() endmacro() endif() -- cgit v1.2.3 From 6255859ebf19b38c864cd6dbaf2878e0116535a4 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 27 May 2015 16:17:19 +0200 Subject: Fix cmake auto tests failing with cmake 2.8.11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit 3eca75de67b3fd2c890715b30c7899cebc096fe9 the use of _EXECUTABLE_COMPILE_FLAGS becomes mandatory for 2.8.11 or older. Therefore use it in test_use_modules - that's supposed to work with all cmake versions it seems - and bump test_interface to require 2.8.12. Change-Id: I7cfb6c6f1e8a97be916d372b9d9148490926693c Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Stephen Kelly --- tests/auto/cmake/CMakeLists.txt | 5 +---- tests/auto/cmake/test_interface/CMakeLists.txt | 2 +- tests/auto/cmake/test_use_modules_function/CMakeLists.txt | 2 ++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 87d8a802f3..b68aafe956 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -126,11 +126,8 @@ if (QT_WITH_ANGLE OR (NOT WIN32 AND NOT APPLE AND NOT NO_EGL)) endif() expect_pass(test_opengl_lib) -if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) - expect_pass(test_interface) -endif() - if (NOT CMAKE_VERSION VERSION_LESS 2.8.12) + expect_pass(test_interface) expect_pass(test_interface_link_libraries) expect_pass(test_moc_macro_target) endif() diff --git a/tests/auto/cmake/test_interface/CMakeLists.txt b/tests/auto/cmake/test_interface/CMakeLists.txt index a8af92da63..bd3217a497 100644 --- a/tests/auto/cmake/test_interface/CMakeLists.txt +++ b/tests/auto/cmake/test_interface/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8.11) +cmake_minimum_required(VERSION 2.8.12) project(test_interface) diff --git a/tests/auto/cmake/test_use_modules_function/CMakeLists.txt b/tests/auto/cmake/test_use_modules_function/CMakeLists.txt index bfcdd9d1d7..be05c75054 100644 --- a/tests/auto/cmake/test_use_modules_function/CMakeLists.txt +++ b/tests/auto/cmake/test_use_modules_function/CMakeLists.txt @@ -12,5 +12,7 @@ add_executable(three three.cpp) find_package(Qt5Core) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") + qt5_use_modules(two Test) qt5_use_modules(three Gui Test) -- cgit v1.2.3 From 9d662d9d2f33d75d3fbf682ee9fadc291ecae5cb Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 27 May 2015 12:47:12 +0200 Subject: Mention cmake changes in ChangeLog for -fPIE -> -fPIC changes This is a follow-up change to commit 3eca75de67b3fd2c890715b30c7899cebc096fe9 to mention changes required to CMakeLists.txt for users of Qt. Change-Id: I1c9ed162427cdc620f998ccf266d59886901c28d Reviewed-by: Lars Knoll --- dist/changes-5.4.2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dist/changes-5.4.2 b/dist/changes-5.4.2 index 5827187e9e..29d3c6346d 100644 --- a/dist/changes-5.4.2 +++ b/dist/changes-5.4.2 @@ -41,6 +41,10 @@ information about a particular change. Qt's option "reduce relocations" is active. Note that Clang is known to generate incompatible code even with -fPIC if the -flto option is active. + Applications using qmake or cmake >= 2.8.12 as their build system will + adapt automatically. Applications using an older release of cmake need to + change their CMakeLists.txt to add Qt5Core_EXECUTABLE_COMPILE_FLAGS to + CMAKE_CXX_FLAGS. **************************************************************************** * Library * -- cgit v1.2.3 From 95b6c4fed6521aa2212cab67cb8a6e5553e86117 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 May 2015 11:21:35 -0700 Subject: Make qglobal.h only complain for GCC >= 5 about -fPIE Commit 3eca75de67b3fd2c890715b30c7899cebc096fe9 introduced the #error nagging about use of -fPIE, but it makes the transition quite difficult for people using other buildsystems. So let's give people a grace period and enforce only for GCC >= 5. Clang is affected, but differently. The problem only happens with -flto -- that is, it happens when the linker detects that it's creating a final executable. Maybe -Wl,-pie would fix it. Change-Id: If4d5ac8db0ed4a84a3eaffff13e275edc29a72b7 Reviewed-by: Simon Hausmann Reviewed-by: Dmitry Shachnev --- src/corelib/global/qglobal.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 4547877da6..d9742408a3 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1047,7 +1047,8 @@ Q_CORE_EXPORT int qrand(); # define QT_NO_SHAREDMEMORY #endif -#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && (!defined(__PIC__) || defined(__PIE__)) +#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && \ + (!defined(__PIC__) || (defined(__PIE__) && defined(Q_CC_GNU) && Q_CC_GNU >= 500)) # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ "Compile your code with -fPIC (-fPIE is not enough)." #endif -- cgit v1.2.3 From e3983c87280ade48b243d9c60bed639713851be9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 28 May 2015 21:20:55 +0200 Subject: Revert some changes in light of GCC 4 -fPIE reversal The -fPIE option is now accepted when using GCC 4, which means it is available for backward compatibility for clients using CMake 2.8.11 or older which makes use of the POSITION_INDEPENDENT_CODE feature. Conditionally use that feature for old versions of cmake with GCC 4. Restore the tests for those versions, and clarify the situation in the ChangeLog. Change-Id: I5a06b155dda7db559d86841a2b34fd8ed95acbd0 Reviewed-by: Thiago Macieira --- dist/changes-5.4.2 | 20 +++++++++++++------- src/corelib/Qt5CoreConfigExtras.cmake.in | 8 +++++++- src/corelib/Qt5CoreMacros.cmake | 6 ++++++ tests/auto/cmake/CMakeLists.txt | 5 ++++- tests/auto/cmake/test_interface/CMakeLists.txt | 2 +- .../cmake/test_use_modules_function/CMakeLists.txt | 2 -- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/dist/changes-5.4.2 b/dist/changes-5.4.2 index 29d3c6346d..1a34898011 100644 --- a/dist/changes-5.4.2 +++ b/dist/changes-5.4.2 @@ -37,14 +37,20 @@ information about a particular change. - On x86 and x86-64 systems with ELF binaries (especially Linux), due to a new optimization in GCC 5.x in combination with a recent version of GNU binutils, compiling Qt applications with -fPIE is no longer - enough. Applications now need to be compiled with the -fPIC option if - Qt's option "reduce relocations" is active. Note that Clang is known - to generate incompatible code even with -fPIC if the -flto option is - active. + enough with GCC 5.x. Applications now need to be compiled with + the -fPIC option if Qt's option "reduce relocations" is active. For + backward compatibility only, Qt accepts the use of -fPIE for GCC 4.x + versions. + Note that Clang is known to generate incompatible code even with -fPIC if + the -flto option is active. Applications using qmake or cmake >= 2.8.12 as their build system will - adapt automatically. Applications using an older release of cmake need to - change their CMakeLists.txt to add Qt5Core_EXECUTABLE_COMPILE_FLAGS to - CMAKE_CXX_FLAGS. + adapt automatically. Applications using an older release of cmake in + combination with GCC 5.x need to change their CMakeLists.txt to add + Qt5Core_EXECUTABLE_COMPILE_FLAGS to CMAKE_CXX_FLAGS. In particular, + applications using cmake >= 2.8.9 and < 2.8.11 will continue to build + with the -fPIE option and invoke the special compatibility mode if using + GCC 4.x. + **************************************************************************** * Library * diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index a5cab880ba..65fd1f9383 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -71,7 +71,13 @@ set(_qt5_corelib_extra_includes) # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") -set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) +if (CMAKE_VERSION VERSION_LESS 2.8.12 + AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" + OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)) + set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") +else() + set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) +endif() !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index c10880f787..cfbb381df5 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -281,6 +281,12 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.9) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG) + if (Qt5_POSITION_INDEPENDENT_CODE + AND (CMAKE_VERSION VERSION_LESS 2.8.12 + AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" + OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))) + set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE}) + endif() endforeach() endmacro() endif() diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index b68aafe956..87d8a802f3 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -126,8 +126,11 @@ if (QT_WITH_ANGLE OR (NOT WIN32 AND NOT APPLE AND NOT NO_EGL)) endif() expect_pass(test_opengl_lib) -if (NOT CMAKE_VERSION VERSION_LESS 2.8.12) +if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) expect_pass(test_interface) +endif() + +if (NOT CMAKE_VERSION VERSION_LESS 2.8.12) expect_pass(test_interface_link_libraries) expect_pass(test_moc_macro_target) endif() diff --git a/tests/auto/cmake/test_interface/CMakeLists.txt b/tests/auto/cmake/test_interface/CMakeLists.txt index bd3217a497..a8af92da63 100644 --- a/tests/auto/cmake/test_interface/CMakeLists.txt +++ b/tests/auto/cmake/test_interface/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 2.8.11) project(test_interface) diff --git a/tests/auto/cmake/test_use_modules_function/CMakeLists.txt b/tests/auto/cmake/test_use_modules_function/CMakeLists.txt index be05c75054..bfcdd9d1d7 100644 --- a/tests/auto/cmake/test_use_modules_function/CMakeLists.txt +++ b/tests/auto/cmake/test_use_modules_function/CMakeLists.txt @@ -12,7 +12,5 @@ add_executable(three three.cpp) find_package(Qt5Core) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") - qt5_use_modules(two Test) qt5_use_modules(three Gui Test) -- cgit v1.2.3 From 386aca1ba4da3383cd6b6253a7240417ff2d91a0 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Fri, 22 May 2015 09:13:51 +1000 Subject: Fix no bearermanagement build As pointed out in the bug, it also fixes API use when configured with no bearermanagement. Task-number: QTBUG-46239 Change-Id: Ief8df85ad6acf61e8d5bb3eed54e7d6ecb84c1a0 Reviewed-by: Alex Blasche --- src/network/access/qnetworkaccessmanager.cpp | 41 +++++++++++++------------- src/plugins/bearer/corewlan/qcorewlanengine.mm | 3 ++ 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 52d56fb071..14db4554bb 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -961,6 +961,27 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess } } +/*! + \internal + + Returns the network session currently in use. + This can be changed at any time, ownership remains with the QNetworkAccessManager +*/ +const QWeakPointer QNetworkAccessManagerPrivate::getNetworkSession(const QNetworkAccessManager *q) +{ + return q->d_func()->networkSessionWeakRef; +} + +QSharedPointer QNetworkAccessManagerPrivate::getNetworkSession() const +{ + if (networkSessionStrongRef) + return networkSessionStrongRef; + return networkSessionWeakRef.toStrongRef(); +} + +#endif // QT_NO_BEARERMANAGEMENT + + #ifndef QT_NO_SSL /*! \since 5.2 @@ -1021,26 +1042,6 @@ void QNetworkAccessManager::connectToHost(const QString &hostName, quint16 port) get(request); } -/*! - \internal - - Returns the network session currently in use. - This can be changed at any time, ownership remains with the QNetworkAccessManager -*/ -const QWeakPointer QNetworkAccessManagerPrivate::getNetworkSession(const QNetworkAccessManager *q) -{ - return q->d_func()->networkSessionWeakRef; -} - -QSharedPointer QNetworkAccessManagerPrivate::getNetworkSession() const -{ - if (networkSessionStrongRef) - return networkSessionStrongRef; - return networkSessionWeakRef.toStrongRef(); -} - -#endif // QT_NO_BEARERMANAGEMENT - /*! \since 4.7 diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 2b38409723..3cee70044f 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -52,6 +52,7 @@ #include #include +#ifndef QT_NO_BEARERMANAGEMENT extern "C" { // Otherwise it won't find CWKeychain* symbols at link time #import @@ -896,3 +897,5 @@ quint64 QCoreWlanEngine::getBytes(const QString &interfaceName, bool b) } QT_END_NAMESPACE + +#endif -- cgit v1.2.3