From 014d7ac65417ed9b5ffb85cca24d16564ff5005a Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Thu, 5 Sep 2019 09:58:30 +0200 Subject: Q{Shared,Weak}Pointer: Reduce overload sets in implicit conversions Only allow implicit conversions when the types involved are compatible. That means, only allow construction and copy assignment when the type X* is convertible to type T*. This is done using SFINAE and the std::is_convertible type trait, which makes the previous QSHAREDPOINTER_VERIFY_AUTO_CAST obsolete. This patch fixes compilation when a function is overloaded with Q{Shared,Weak}Pointer of different, incompatible types. Previously, this resulted in a compilation error due to an ambiguous overload. Change-Id: I069d22f3582e69842f14284d4f27827326597ca2 Fixes: QTBUG-75222 Reviewed-by: Thiago Macieira --- src/corelib/tools/qsharedpointer_impl.h | 51 +++++++++++++-------------------- 1 file changed, 20 insertions(+), 31 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index bccf8c5740..f2158436fd 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -69,21 +69,6 @@ QT_END_NAMESPACE QT_BEGIN_NAMESPACE - -// Macro QSHAREDPOINTER_VERIFY_AUTO_CAST -// generates a compiler error if the following construct isn't valid: -// T *ptr1; -// X *ptr2 = ptr1; -// -#ifdef QT_NO_DEBUG -# define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X) qt_noop() -#else - -template inline void qt_sharedpointer_cast_check(T *) { } -# define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X) \ - qt_sharedpointer_cast_check(static_cast(0)) -#endif - // // forward declarations // @@ -293,6 +278,9 @@ template class QSharedPointer { typedef T *QSharedPointer:: *RestrictedBool; typedef QtSharedPointer::ExternalRefCountData Data; + template + using IfCompatible = typename std::enable_if::value, bool>::type; + public: typedef T Type; typedef T element_type; @@ -316,11 +304,11 @@ public: Q_DECL_CONSTEXPR QSharedPointer(std::nullptr_t) Q_DECL_NOTHROW : value(nullptr), d(nullptr) { } - template + template = true> inline explicit QSharedPointer(X *ptr) : value(ptr) // noexcept { internalConstruct(ptr, QtSharedPointer::NormalDeleter()); } - template + template = true> inline QSharedPointer(X *ptr, Deleter deleter) : value(ptr) // throws { internalConstruct(ptr, deleter); } @@ -349,7 +337,7 @@ public: return *this; } - template + template = true> QSharedPointer(QSharedPointer &&other) Q_DECL_NOTHROW : value(other.value), d(other.d) { @@ -357,7 +345,7 @@ public: other.value = nullptr; } - template + template = true> QSharedPointer &operator=(QSharedPointer &&other) Q_DECL_NOTHROW { QSharedPointer moved(std::move(other)); @@ -367,11 +355,11 @@ public: #endif - template + template = true> QSharedPointer(const QSharedPointer &other) Q_DECL_NOTHROW : value(other.value), d(other.d) { if (d) ref(); } - template + template = true> inline QSharedPointer &operator=(const QSharedPointer &other) { QSharedPointer copy(other); @@ -379,11 +367,11 @@ public: return *this; } - template + template = true> inline QSharedPointer(const QWeakPointer &other) : value(nullptr), d(nullptr) { *this = other; } - template + template = true> inline QSharedPointer &operator=(const QWeakPointer &other) { internalSet(other.d, other.value); return *this; } @@ -553,6 +541,8 @@ class QWeakPointer { typedef T *QWeakPointer:: *RestrictedBool; typedef QtSharedPointer::ExternalRefCountData Data; + template + using IfCompatible = typename std::enable_if::value, bool>::type; public: typedef T element_type; @@ -574,14 +564,14 @@ public: #ifndef QT_NO_QOBJECT // special constructor that is enabled only if X derives from QObject #if QT_DEPRECATED_SINCE(5, 0) - template + template = true> QT_DEPRECATED inline QWeakPointer(X *ptr) : d(ptr ? Data::getAndRef(ptr) : nullptr), value(ptr) { } #endif #endif #if QT_DEPRECATED_SINCE(5, 0) - template + template = true> QT_DEPRECATED inline QWeakPointer &operator=(X *ptr) { return *this = QWeakPointer(ptr); } #endif @@ -619,11 +609,11 @@ public: return *this; } - template + template = true> inline QWeakPointer(const QWeakPointer &o) : d(nullptr), value(nullptr) { *this = o; } - template + template = true> inline QWeakPointer &operator=(const QWeakPointer &o) { // conversion between X and T could require access to the virtual table @@ -640,14 +630,13 @@ public: bool operator!=(const QWeakPointer &o) const Q_DECL_NOTHROW { return !(*this == o); } - template + template = true> inline QWeakPointer(const QSharedPointer &o) : d(nullptr), value(nullptr) { *this = o; } - template + template = true> inline QWeakPointer &operator=(const QSharedPointer &o) { - QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid internalSet(o.d, o.data()); return *this; } @@ -684,7 +673,7 @@ public: { return *this = QWeakPointer(ptr, true); } #ifndef QT_NO_QOBJECT - template + template = true> inline QWeakPointer(X *ptr, bool) : d(ptr ? Data::getAndRef(ptr) : nullptr), value(ptr) { } #endif -- cgit v1.2.3 From 55427858e3f9d98dc7a75638c54a4fffde6be73a Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Wed, 20 Mar 2019 15:39:59 +0200 Subject: QStandardPaths: Correct handling for XDG_RUNTIME_DIR Always try to create the runtime directory and never change the permissions of an existing directory. Conform to the XDG Base Directory Specification: "If, when attempting to write a file, the destination directory is non-existent an attempt should be made to create it with permission 0700. If the destination directory exists already the permissions should not be changed." Fixes: QTBUG-68338 Change-Id: Iaf854d69225fc46e43abae86232d749e5c247df0 Reviewed-by: David Faure Reviewed-by: Thiago Macieira --- src/corelib/io/qstandardpaths_unix.cpp | 51 +++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index 3d4a349c8c..cc656954d9 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -120,54 +120,59 @@ QString QStandardPaths::writableLocation(StandardLocation type) } case RuntimeLocation: { - const uint myUid = uint(geteuid()); // http://standards.freedesktop.org/basedir-spec/latest/ + const uint myUid = uint(geteuid()); + // since the current user is the owner, set both xxxUser and xxxOwner + const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser + | QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner; QFileInfo fileInfo; QString xdgRuntimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR")); if (xdgRuntimeDir.isEmpty()) { const QString userName = QFileSystemEngine::resolveUserName(myUid); xdgRuntimeDir = QDir::tempPath() + QLatin1String("/runtime-") + userName; fileInfo.setFile(xdgRuntimeDir); - if (!fileInfo.isDir()) { - if (!QDir().mkdir(xdgRuntimeDir)) { - qWarning("QStandardPaths: error creating runtime directory %s: %s", qPrintable(xdgRuntimeDir), qPrintable(qt_error_string(errno))); - return QString(); - } - } #ifndef Q_OS_WASM qWarning("QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '%s'", qPrintable(xdgRuntimeDir)); #endif } else { fileInfo.setFile(xdgRuntimeDir); - if (!fileInfo.exists()) { - qWarning("QStandardPaths: XDG_RUNTIME_DIR points to non-existing path '%s', " - "please create it with 0700 permissions.", qPrintable(xdgRuntimeDir)); - return QString(); - } + } + if (fileInfo.exists()) { if (!fileInfo.isDir()) { qWarning("QStandardPaths: XDG_RUNTIME_DIR points to '%s' which is not a directory", qPrintable(xdgRuntimeDir)); return QString(); } + } else { + QFileSystemEntry entry(xdgRuntimeDir); + if (!QFileSystemEngine::createDirectory(entry, false)) { + if (errno != EEXIST) { + qWarning("QStandardPaths: error creating runtime directory %s: %s", + qPrintable(xdgRuntimeDir), qPrintable(qt_error_string(errno))); + return QString(); + } + } else { + QSystemError error; + if (!QFileSystemEngine::setPermissions(entry, wantedPerms, error)) { + qWarning("QStandardPaths: could not set correct permissions on runtime directory %s: %s", + qPrintable(xdgRuntimeDir), qPrintable(error.toString())); + return QString(); + } + } } // "The directory MUST be owned by the user" if (fileInfo.ownerId() != myUid) { - qWarning("QStandardPaths: wrong ownership on runtime directory %s, %d instead of %d", qPrintable(xdgRuntimeDir), - fileInfo.ownerId(), myUid); + qWarning("QStandardPaths: wrong ownership on runtime directory %s, %d instead of %d", + qPrintable(xdgRuntimeDir), fileInfo.ownerId(), myUid); return QString(); } // "and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700." - // since the current user is the owner, set both xxxUser and xxxOwner - const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser - | QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner; if (fileInfo.permissions() != wantedPerms) { - QFile file(xdgRuntimeDir); - if (!file.setPermissions(wantedPerms)) { - qWarning("QStandardPaths: could not set correct permissions on runtime directory %s: %s", - qPrintable(xdgRuntimeDir), qPrintable(file.errorString())); - return QString(); - } + qWarning("QStandardPaths: wrong permissions on runtime directory %s, %x instead of %x", + qPrintable(xdgRuntimeDir), uint(fileInfo.permissions()), uint(wantedPerms)); + return QString(); } + return xdgRuntimeDir; } default: -- cgit v1.2.3 From 689405fb5ce5a2ff7446e1d110a7686184270f89 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 10 Oct 2019 17:17:29 +0200 Subject: Use arrays rather than assigning literals to char* (warning-fix) Integrity has a hack, to let us link to the library mmap is in, that depends on two extern "C" symbols of type char *; but assigning a string literal to a char * variable as initializer is a const-ness violation (as the Integrity compiler does point out), so change the two variables to be char[] instead of char *, so that the literals populate (and determine the size of) the arrays, instead. Change-Id: Iab34fb378bc0522e14539592ead066f068751ad0 Reviewed-by: Qt CI Bot Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 30a44aeef8..78ad2a5421 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -110,8 +110,8 @@ extern "C" { // without full system POSIX. # pragma weak shm_area_password # pragma weak shm_area_name - char *shm_area_password = "dummy"; - char *shm_area_name = "dummy"; + char shm_area_password[] = "dummy"; + char shm_area_name[] = "dummy"; } #endif -- cgit v1.2.3 From 50481fb909c2bbbc26a193e23783e5b0151168b9 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 10 Oct 2019 17:29:17 +0200 Subject: QEndian: do not use "raw" constexpr Use the Qt's macros instead, since constexpr support may be revoked on certain compilers. Amends d26289ffb43a5fcf34e855db1dfbf42aa03c4f5a. Change-Id: I62354b14b57ae5fcbf3f1186ddb48bcf26535e90 Reviewed-by: Edward Welbourne --- src/corelib/global/qendian.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index 615f523888..5cd9d3160b 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -327,9 +327,9 @@ public: return pre; } - static constexpr QSpecialInteger max() + static Q_DECL_CONSTEXPR QSpecialInteger max() { return QSpecialInteger(std::numeric_limits::max()); } - static constexpr QSpecialInteger min() + static Q_DECL_CONSTEXPR QSpecialInteger min() { return QSpecialInteger(std::numeric_limits::min()); } }; @@ -373,8 +373,8 @@ public: QLEInteger &operator ++(int); QLEInteger &operator --(int); - static constexpr QLEInteger max(); - static constexpr QLEInteger min(); + static Q_DECL_CONSTEXPR QLEInteger max(); + static Q_DECL_CONSTEXPR QLEInteger min(); }; template @@ -400,8 +400,8 @@ public: QBEInteger &operator ++(int); QBEInteger &operator --(int); - static constexpr QBEInteger max(); - static constexpr QBEInteger min(); + static Q_DECL_CONSTEXPR QBEInteger max(); + static Q_DECL_CONSTEXPR QBEInteger min(); }; #else -- cgit v1.2.3