summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qvariant.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QVariant: use comparison helper macrosIvan Solovev2024-03-121-4/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | The relational operators were removed in 8652c79df0a47264a2d525424484e15744e2462b with the argument that they do not have a total order. Back than it was a valid argument, because Qt did not support any of the C++20 ordering types. Now Qt has its own implementation for all three ordering types, so we could technically add relational operators and claim that QVariant provides partial ordering. However, that could potentially lead to many bugs and/or unexpected results, if people start using QVariant as a key in std::map/QMap containers. We do not want that to happen, so we only use the helper macros to implement (in)equality operators. This commit also extends the unit tests, providing more extensive testing of (in)equality operators and the pre-existing QVariant::compare() method. Fixes: QTBUG-113234 Change-Id: I783f3b5df552da782627f4ed0a5bb1b577753a23 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Bootstrap: remove QBitArrayMarc Mutz2024-01-311-0/+4
| | | | | | | | | | It appears to be used only in qlalr, which is, however, not bootstrapped. Pick-to: 6.7 6.6 6.5 6.2 Change-Id: Idc16d957bf687238c7b0ee603d8b092e2048ef18 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Doc: Fix \fn template arguments for Qt CoreLuca Di Sera2023-11-301-5/+5
| | | | | | | | | Upcoming changes to QDoc require accurate definition for template arguments in \fn commands. Task-number: QTBUG-118080 Change-Id: I64d50919bc6ffab61ef5ead553d1da99d63a9f21 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* Doc: Fix template information for QVariant membersLuca Di Sera2023-11-131-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When QDoc parses a project, it parses the source code to extract the user-provided documentation and perform sanity checkings based on the code itself on it. When QDoc parses an "\fn" command as part of this process, it tries to understand, based on its intermediate representation built on the information extracted from the code-base, which "documentable element" the "\fn" refers to. When QDoc performs this "matching" process, it takes into consideration only a certain amount of information. For example, no checking is performed over the template declaration of a callable. Due to some upcoming documentation, where two callables are indistinguishable to the current process, as they differ only in their template declaration, QDoc will start to take into consideration the template declaration of a callable when matching. This implies that an "\fn" command should now provide information parity, with regards to template declaration for callables, with the code-base so that QDoc can perform the match correctly. The documentation for of the members of `QVariant` is not in sync with the intended target template declaration. Hence, add the missing information to the relevant "\fn" commands. Task-number: QTBUG-118080 Change-Id: I9ec1a09091afbb17bc37bfc1dee8f738f01619e9 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QVariant: add fromMetaTypeGiuseppe D'Angelo2023-09-201-13/+48
| | | | | | | | | | | | | | | | | | | | | | The QVariant(QMetaType) constructor is a major anti-pattern: unlike *every* other QVariant's constructor, it doesn't build a QVariant holding the QMetaType object, but a QVariant of the specified type. Introduce a named constructor for this use case instead. In principle, this should lead to a deprecation of the QMetaType constructor... except that it's used everywhere, so I can't do it at this time. Drive-by, improve the documentation of the QVariant(QMetaType) constructor (since it's basically c&p for the new fromMetaType function). [ChangeLog][QtCore][QVariant] Added the QVariant::fromMetaType named constructor, that builds a QVariant of a given QMetaType. Change-Id: I4a499526bd0fe98eed0c1a3e91bcfc21efa9e352 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Doc: Fix documentation issuesTopi Reinio2023-09-111-0/+8
| | | | | | | | | | | | | | | | | | | | Fix the following QDoc warnings: * warning: Can't link to 'QRhiWidget::sampleConut' * warning: Can't link to '`Q_NODISCARD_CTOR' * warning: Invalid '\relates' (already a member of 'QEventLoopLocker') * warning: Unknown command '\relatesalso' * warning: Undocumented parameter 'separator' in QLocale::name() * warning: clang couldn't find function when parsing \fn void QRhiWidget::framePresented() In QAtomicPointer, work around the issue of QDoc not supporting multiple \relates command for a single topic by adding a see-also link to the global qYieldCpu() function. Document the qvariant_cast() overload taking an rvalue reference. Change-Id: I2528eee666149a97a14be059bbed537636d7aa0d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QVariant: de-duplicate customConstructShared()Thiago Macieira2023-08-291-16/+0
| | | | | | | | | | | | | | | | | Commit 3ad9f94ff2de3a1f812bb0139ff31e31d5ffb529 (Feb 2023) moved it to qvariant_p.h but commit 79ae79d05c65019233cf9ae9e77ef59d90e75ac2 (authored Sep 2022 but committed June 2023) brought it back, probably by accident due to conflict resolution during rebasing. For some reason, no compiler in our CI complains about it, but ICX 2023 (based on unrelased Clang versions) did: variant_p.h(101,23): error: call to 'customConstructShared' is ambiguous Pick-to: 6.6 Fixes: QTBUG-116496 Change-Id: Ifa1111900d6945ea8e05fffd177eab656a2dc507 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Deprecate Q_ASSUME()Thiago Macieira2023-08-141-1/+1
| | | | | | | | | | | | | | | | | | | | We've known for a long time that this is producing worse code with GCC because of how we implemented in Q_ASSUME_IMPL(). So bite the bullet and actually deprecate the macro, replacing all extant Q_ASSUME() with Q_ASSERT(). The replacement is in C++23. Backporting the support onto Q_ASSUME_IMPL was previously rejected by reviewers. [ChangeLog][Deprecation Notice] The Q_ASSUME() macro is deprecated. This macro has different side-effects depending on the compiler used (GCC compared to Clang and MSVC), and there are certain conditions under which GCC is known to produce worse code than if the macro was absent. To give a hint to the compiler for optimizations, use the C++23 [[assume]] attribute. Change-Id: I80612a7d275c41f1baf0fffd177a3a4ad819fb2d Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QVariant: always compare floating point with double precisionVolker Hilsheimer2023-07-051-11/+11
| | | | | | | | | | | | | | | | | | | When Qt is configured with `-qreal float`, then we should still compare QVariants containing floating point values with the full precision of the stored type, and not cast to qreal (ie. float). Cast all floating point types up to double, which is the highest- precision floating point type we support in Qt. This might have a small performance impact when compiling with `-qreal float`, if the FPU does not perform well with double-precision floating point values. We don't test any `-qreal float` configurations in CI, so not adding a unit test for this. Fixes: QTBUG-114991 Pick-to: 6.6 6.5 6.2 Change-Id: I198ec2c39913b501ef2fe99ae3048b160baa1fd8 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Doc: Adjust \fn signature for QVariant::value()Topi Reinio2023-06-141-1/+1
| | | | | | | | Fixes QDoc warning: clang couldn't find function when parsing \fn template<typename T> T QVariant::value() const. Change-Id: I0e331c5895497bd2c9e691a580929e25cc14dc6c Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QVariant: add rvalue overload of fromStdVariant()Marc Mutz2023-06-021-0/+6
| | | | | | | | | | | | | | | | | | | Extract Method fromStdVariantImpl() to share the otherwise more-or-less identical implementation between the two overloads. Don't use a constrained template version of fromStdVariantImpl() as fromStdVariant(), because the constraint would have to be very complex to continue allowing subclasses of std::variant to be passed. As a drive-by, mark the valueless_by_exception() path Q_UNLIKELY. [ChangeLog][QtCore][QVariant] Added overload of fromStdVariant() taking rvalue std::variant<>s. Fixes: QTBUG-114134 Change-Id: Ia1c7ae93ab421e6689dc9f2d8d0c2295b23cbbf6 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant::fromValue: Add rvalue optimizationFabian Kosmale2023-06-021-5/+69
| | | | | | | | | | | | | | | | | | When passing an rvalue-reference to QVariant, there is no reason to make a copy if the type is moveable. Moreover, we know that the pointer which we construct from the object passed to fromValue non-null. We make use of both facts by parametrizing custom_construct on non-nullness and availability of a move-ctor, and then dispatching to the suitable template. We need to keep the const T& overload, as otherwise code which explicitly specializes fromValue and passes a const lvalue to it would stop to compile. [ChangeLog][QtCore][QVariant] Added fromValue() overload taking rvalues. Change-Id: I44fb757d516ef364fe7967bc103b3f98278b4919 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: fix shadowing of QVariant::Type/ListMarc Mutz2023-06-021-7/+7
| | | | | | | | | | | | | | QDoc mis-interprets the Type and List template arguments as referring to the QVariant::Type enum and its List enumerator, resp. To fix, rename the template parameters from Type to T and from List to U. Task-number: QTBUG-112187 Change-Id: Ib4093acdd84cc86a0f85dcc5046b6e7da7885a44 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QVariant: Support emplaceFabian Kosmale2023-06-021-0/+63
| | | | | | | | | | | | | | [ChangeLog][QtCore][QVariant] Implemented in-place construction for QVariant. The constructor taking std::in_place_type<Type> constructs an object of type Type directly inside QVariant's storage, without any further copy or move operations. QVariant::emplace() does the same when replacing the content of an existing QVariant and tries to reuse previously-allocated memory. Fixes: QTBUG-112187 Change-Id: I16614ad701fa3bb583976ed2001bb312f119a51f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QVariant: simplify condition guarding customClear() callsMarc Mutz2023-05-311-2/+2
| | | | | | | | | | | | | | Due to short-cut evaluation of the built-in op||, we can do the following transformation: - (X && Y) || !X + !X || Y Pick-to: 6.5 Change-Id: Ia5ae1dd60bdb663aa4648c09372be1598591110d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QVariant: remove outdated docs about reimplementing clear()Marc Mutz2023-05-311-5/+0
| | | | | | | | | QVariant::clear() hasn't been virtual since at least Qt 4... Pick-to: 6.5 6.2 5.15 Change-Id: If6b5669d91f8d9c7ed2d152d18852a8d6f8e491a Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: Add support for in-place constructionFabian Kosmale2023-04-271-0/+37
| | | | | | | | | | This avoids constructing an object just to copy (later: move) it into a QVariant. ChangeLog will be in a follow-up change adding emplace support. Task-number: QTBUG-112187 Change-Id: I444e580c7d8927d41b3d21d5a521e7c475119e4c Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Doc: Use \relates for functions in the global scopeTopi Reinio2023-03-281-0/+2
| | | | | | | | | | | | | | | | | | | | | | This addresses the recent warnings introduced by a change to QDoc: qkeysequence.h:32: (qdoc) warning: No documentation generated for function 'qHash' in global scope. qmap.h:1557: (qdoc) warning: No documentation generated for function 'operator+' in global scope. qmap.h:1565: (qdoc) warning: No documentation generated for function 'operator+=' in global scope. qvariant.h:582: (qdoc) warning: No documentation generated for function 'operator>>' in global scope. qvariant.h:590: (qdoc) warning: No documentation generated for function 'operator<<' in global scope. Also, mark qt_win_hasPackageIdentity() declared in qfunctions_win_p.h as \internal. Pick-to: 6.5 Change-Id: Idc9c813370ff3133ac9dc3bf809976b0ece88811 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Implement [variant.get] for QVariant [2/2]: get()Marc Mutz2023-03-241-0/+19
| | | | | | | | | | | | | | | | | | | | | | | | | This second patch of the series implements get(). Unlike other get() implementations in Qt, don't use my trick with the constrained friend free function here. Instead, provide the four overloads manually, like mandated by the standard library for std::variant (and, indeed, tuple), such that these functions can also be used on subclasses of QVariant. [ChangeLog][QtCore][QVariant] Implemented the type-based std::variant access protocol (get<T>()/get_if<T>()) to allow easier access to the contained element than the previous solution of casting data(), as well as to allow generic code to treat QVariant and std::variant the same. The holds_alternative<T>() function is not provided, since it's the same as get_if<T> != nullptr. The index-based variant access functions (get<I>()/get_if<I>()) are also not provided, because, unlike std::variant, QVariant does not have a bounded number of alternative types, and QMetaType IDs are not (all) compile-time constants. Fixes: QTBUG-111598 Change-Id: Id7bc41f7d91761b3483ec5604f1a4685c8079844 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Implement [variant.get] for QVariant [1/2]: get_if()Marc Mutz2023-03-241-2/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | QVariant supports non-default-constructible payloads, in principle (QTBUG-105140). And fromValue() works with such types, but value() insists on providing a wide contract and therefore accidentally requires default-constructible. We can now invent other "Qt-ish" API like optional::value_or() or a value() that returns optional<T>, but we should first get the interface in that generic code must use, and which at the same time is the most versatile, because it gives write access to the element stored in the variant: [variant.get], consisting of get_if(), get(), and holds_alternative(). The latter is the same as get_if() != nullptr, so we won't provide it. This first patch implements get_if(), adds test for it. As a Hidden Friend supposed to be called with explicit template arguments, we run into the problem that wg21.link/P0846 solved for C++20. Add the usual work-around, and check it works. The ChangeLog will be on the last patch. Task-number: QTBUG-111598 Change-Id: I23f57ea2de3946944810c5552c68a7a3060a44f2 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QVariant: ensure the type custom is registered on constructionThiago Macieira2023-03-231-0/+1
| | | | | | | | | | | | | | I must have broken this in the 6.5 work I did for QMetaType and QVariant, but I haven't searched which commit exactly did it. Our QVariant tests are old and thus only checked the type ID, which meant that they caused the registration by the act of asking for the ID in the first place; this commit adds a couple of explicit checks for the type registered by name before the ID. Fixes: QTBUG-112205 Pick-to: 6.5 6.5.0 Change-Id: Idd5e1bb52be047d7b4fffffd174f1b14d90fd7a3 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: fix comparisons between strings and integer 0Giuseppe D'Angelo2023-03-101-1/+1
| | | | | | | | | | | | | | | | | | | | | | 250ca8d5f8bb3771695ae8eccb8d9b469003d840 changed the qConvertToNumber to have a std::optional return instead of a boolean out-argument. In doing so a code path that was supposed to report a failure (string could not be converted to an integer) accidentally starting reporting success (and converting the string to 0). The problem is that the `ok` check from QString::toLongLong was accidentally dropped in the refactoring; previously the function set `ok` to false and returned 0, now the function just returns 0. Instead, amend that return to return nullopt (because the conversion has failed). Change-Id: Iaedef5463f3ec500a97bd4c9bbddf977f66df61a Pick-to: 6.5 6.5.0 Fixes: QTBUG-111867 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QVariant: Move some inline methods into a private headerUlf Hermann2023-02-221-69/+1
| | | | | | | | | | We want to be able to use those from qtdeclarative. Clearly, they are intended to be inline. Task-number: QTBUG-108789 Change-Id: I3560e9b58213c4f41dbf6553021f3d6187960e8b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QtCore: Disambiguate static variablesFriedemann Kleint2023-02-021-3/+3
| | | | | | | | | They cause clashes in CMake Unity (Jumbo) builds. Pick-to: 6.5 Task-number: QTBUG-109394 Change-Id: I5f1fbee07872a742a78adc9864fe00c710ca24d0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Docs: adjust docs after the QLatin1String to QLatin1StringView renameAhmad Samir2023-01-051-1/+2
| | | | | | | | | | | | | Unify wording as "{Latin-1,UTF-16} string viewed by \a str". Drive-by change: Fix a grammatical error, it's "a US-ASCII", not an (because it's pronounced by the letter name "U" which is pronounced like "you", so "a" not "an"). Task-number: QTBUG-108711 Pick-to: 6.5 Change-Id: Iff763f4008341c35317bb3d7a2a228767ff6a648 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QMetaType: fix value-initialization in a corner caseGiuseppe D'Angelo2022-12-301-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a type is trivially default constructible, QMetaType (and QVariant) think that it can be built and value-initialized by zero-filling a region of storage and then "blessing" that storage as an actual instance of the type to build. This is done as an optimization. This doesn't work for all trivially constructible types. For instance, on the Itanium C++ ABI, pointers to data members are actually value-initialized (= zero-initialized, = initialized to null) with the value -1: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#data-member-pointers This means that a type like struct A { int A::*ptr; }; is trivially constructible, but its value initialization is not equivalent to zero-filling its storage. Since C++ does not offer a type trait we can use for the detection that we want to do here, and since we have also decided that Q_PRIMITIVE_TYPE isn't that trait (it just means trivially copyable / destructible), I'm rolling out a custom type trait for the purpose. This type trait is private for the moment being (there's no Q_DECLARE_TYPEINFO for it), and limited to the subset of scalar types that we know can be value-initialized by memset(0) into their storage (basically, all of them, except for pointers to data members). The fix tries to keep the pre-existing semantics of `QMetaType::NeedsConstruction`. Before, the flag was set for types which were not trivially default constructible. That included types that aren't default constructible, or types that cannot do so trivially. I've left that meaning unchanged, and simply amended the "trivial" part with the custom trait. A fix there (to clarify the semantics) can be done as a separate change. Change-Id: Id8da6acb913df83fc87e5d37e2349a4628e72e91 Pick-to: 6.5 Fixes: QTBUG-109594 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* qfloat16: make it a built-in metatypeThiago Macieira2022-11-281-1/+3
| | | | | | | | | | | I've reserved the IDs for int128, uint128, bfloat16, and float128, because the mask in qvariant.cpp's qIsNumericType() requires primitives to be less than 64 to operate properly. Added a QMetaType/QDataStream test to confirm it is indeed built-in. Change-Id: I3d74c753055744deb8acfffd17247f7f57bada02 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
* Fix typo in documentation for QVariant::nameToTypeNicolas Fella2022-11-251-1/+1
| | | | | | | | Pick-to: 6.4 6.2 Change-Id: I69742b9e597012329de5f5f742d4972ea7575775 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QVariant: add support for numeric comparisons for char16_t and char32_tThiago Macieira2022-11-091-1/+7
| | | | | Change-Id: I3d74c753055744deb8acfffd17248af45fd20556 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: fix comparison of enums to numericsThiago Macieira2022-11-091-4/+38
| | | | | | | | | | qIsNumericType does not return true for enum types, which meant we never called numericCompare() or numericEquals() when one of the types was an enum. Task-number: QTBUG-108188 Change-Id: I3d74c753055744deb8acfffd172449c68af19367 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: simplify getting integer contents by using the type sizeThiago Macieira2022-11-091-40/+31
| | | | | | | | | | | This reduces the chances of mistakes in forgetting a type. Plus, this makes it easier to add char16_t and char32_t. Drive-by change some type().id() code that doesn't need the ID for user types to typeInterface()->typeId. Change-Id: I3d74c753055744deb8acfffd17248aa81bf8ce55 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: move the NaN comparison into the spaceShip functionThiago Macieira2022-11-091-2/+4
| | | | | | | Note: NaN = not Not A Naan Change-Id: I3d74c753055744deb8acfffd17248a02f7968121 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: use QPartialOrdering for the internal comparison functionsThiago Macieira2022-11-091-33/+16
| | | | | | | | | | | | Avoids having to have a convertOptionalToPartialOrdering() function to convert back. std::optional<int> is 64 bits on any platform, though it's returned in registers for the IA-64 C++ ABI. Unfortunately, that's not the case for Windows. Change-Id: I3d74c753055744deb8acfffd172480eee189b3b2 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: merge the equality and ordering compare functionsThiago Macieira2022-11-091-36/+2
| | | | | | | | | | As we're not doing any deep analysis, the code is almost exactly the same anyway. It is possible to simplify further by avoiding the signed/unsigned conversion rules, but it's not worth the effort. Instead, we can share code. Change-Id: I3d74c753055744deb8acfffd17248a5c51cbbfcb Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: make a major simplification in the numeric comparisonThiago Macieira2022-11-091-49/+30
| | | | | | | | | | | | | | The code implementing the C++ rules of type promotion and conversion was too pedantic. There's no need to follow the letter of the standard, not when we can now assume that everything is two's complement (this was true for all architectures we supported when I wrote this code in 2014, but wasn't required by the standard). So we can reduce this to fewer comparisons and fewer rules, using the size of the type, not just the type ID. Change-Id: I3d74c753055744deb8acfffd172446b02444c0c0 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: get rid of output argument to qConvertTo{Real,}NumberThiago Macieira2022-11-091-63/+41
| | | | | Change-Id: I3d74c753055744deb8acfffd1724476a2e0e5a49 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Long live Q_UNREACHABLE_RETURN()!Marc Mutz2022-10-151-4/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a combination of Q_UNREACHABLE() with a return statement. ATM, the return statement is unconditionally included. If we notice that some compilers warn about return after __builtin_unreachable(), then we can map Q_UNREACHABLE_RETURN(...) to Q_UNREACHABLE() without having to touch all the code that uses explicit Q_UNREACHABLE() + return. The fact that Boost has BOOST_UNREACHABLE_RETURN() indicates that there are compilers that complain about a lack of return after Q_UNREACHABLE (we know that MSVC, ICC, and GHS are among them), as well as compilers that complained about a return being present (Coverity). Take this opportunity to properly adapt to Coverity, by leaving out the return statement on this compiler. Apply the macro around the code base, using a clang-tidy transformer rule: const std::string unr = "unr", val = "val", ret = "ret"; auto makeUnreachableReturn = cat("Q_UNREACHABLE_RETURN(", ifBound(val, cat(node(val)), cat("")), ")"); auto ignoringSwitchCases = [](auto stmt) { return anyOf(stmt, switchCase(subStmt(stmt))); }; makeRule( stmt(ignoringSwitchCases(stmt(isExpandedFromMacro("Q_UNREACHABLE")).bind(unr)), nextStmt(returnStmt(optionally(hasReturnValue(expr().bind(val)))).bind(ret))), {changeTo(node(unr), cat(makeUnreachableReturn, ";")), // TODO: why is the ; lost w/o this? changeTo(node(ret), cat(""))}, cat("use ", makeUnreachableReturn)) ); where nextStmt() is copied from some upstream clang-tidy check's private implementation and subStmt() is a private matcher that gives access to SwitchCase's SubStmt. A.k.a. qt-use-unreachable-return. There were some false positives, suppressed them with NOLINTNEXTLINE. They're not really false positiives, it's just that Clang sees the world in one way and if conditonal compilation (#if) differs for other compilers, Clang doesn't know better. This is an artifact of matching two consecutive statements. I haven't figured out how to remove the empty line left by the deletion of the return statement, if it, indeed, was on a separate line, so post-processed the patch to remove all the lines matching ^\+ *$ from the diff: git commit -am meep git reset --hard HEAD^ git diff HEAD..HEAD@{1} | sed '/^\+ *$/d' | recountdiff - | patch -p1 [ChangeLog][QtCore][QtAssert] Added Q_UNREACHABLE_RETURN() macro. Change-Id: I9782939f16091c964f25b7826e1c0dbd13a71305 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QVariant/Doc: expand what toList & toMap conversions may succeedThiago Macieira2022-10-111-5/+14
| | | | | | | | | | | | | I don't know when conversion through sequential and associative iteratables was added, probably some time in the 5.x. QString and QByteArray got conversions to sequential iteratables for Qt 6.1 with commit c9a11022692f9a4bd36beb0cd001686694a48915. Since that was intentional, I'm just documenting reality. Fixes: QTBUG-107246 Pick-to: 6.2 6.3 6.4 Change-Id: Id8d5e3999fe94b03acc1fffd171b863b1a0ead68 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QVariant/Doc: document that you must register types before op>>Thiago Macieira2022-08-261-3/+13
| | | | | | | | | | | | But not before ::fromValue, since that registers automatically. Take the opportunity to add the \relates to the two streaming operators to QDataStream, so the documentation shows up *somewhere* at all. Pick-to: 6.4 Task-number: QTBUG-105469 Change-Id: Ic6547f8247454b47baa8fffd170eb8ffc31feb5d Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QVariant: pass the size and alignment to PrivateShared::create()Thiago Macieira2022-08-031-10/+5
| | | | | | | | Instead of having that function load those from memory. This allows us to pass constant expressions in QVariant::Private s constructor Change-Id: I3859764fed084846bcb0fffd17045ddd62553710 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: don't leak PrivateShared if the constructor throwsThiago Macieira2022-08-031-9/+22
| | | | | | | | This means we can't do a tail-call from customConstruct when PrivateShared is in use. But the case without that is still a tail-call. Change-Id: I3859764fed084846bcb0fffd17045d144181ea84 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: make many more QtCore types nothrow-copyableThiago Macieira2022-07-301-11/+21
| | | | | | | | | | | | | | | All of those are implicitly-shared Qt data types whose copy constructors can't throw and have wide contracts (there aren't even any assertions for validity in any of them). These are all types with a QVariant implicit constructor, except for QCborValue, which is updated on this list so QJsonValue (which has a QVariant constructor) is also legitimately noexcept. To ensure we haven't made a mistake, the Private constructor checks again. Change-Id: I3859764fed084846bcb0fffd17044d8319a45e1f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: update the noexcept content for a few typesThiago Macieira2022-07-301-10/+17
| | | | | | | | | | | | | | Commit 2f0a625fd4036b71286dfa7de4c9d795025164e7 added noexcept for these, but didn't verify that the operation itself was noexcept. And it wasn't on 32-bit systems, because sizeof(void *) is only 4 bytes, making QVariant and QVariant::Private a mere 12 bytes. That's insufficient for QUuid and for almost all geometric types when qreal==double. We can't use sizeof() in qvariant.h because most of those classes are only forward-declared. Change-Id: I6f936da6f6e84d649f70fffd1705ce948891d06a Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QVariant: move d.get() into qNumVariantToHelperThiago Macieira2022-07-281-9/+9
| | | | | | | | | | Until we've checked the stored meta type, we don't know what the Private contains. We only formed a reference to said value, so we should be safe, but why tempt it? Change-Id: I6f936da6f6e84d649f70fffd1706095fc6228755 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Lars Knoll <lars.knoll@gmail.com>
* Remove qvariant_p.hThiago Macieira2022-07-271-1/+0
| | | | | Change-Id: I3859764fed084846bcb0fffd1704480153e34973 Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
* QVariant: prepare removal of nullptr_t special casing in Qt 7Fabian Kosmale2022-07-271-1/+2
| | | | | | | | | | customConstruct has to do an additional check to ensure that QVariant::fromValue(nullptr) returns null. We can get rid of it by special casing nullptr_t in a fromValue overload instead, reducing the amount of work that needs to happen at runtime. Change-Id: I2aea6aecfee0a9404cbd78dbea01a1d5d3047ca0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QVariant: add noexcept to Qt types with noexcept copy constructorsThiago Macieira2022-07-271-16/+16
| | | | | | | | | | | | | QHash, QString, QByteArray, and QDateTime are explicitly noexcept, while QList, QMap, and QModelIndex are implicitly noexcept because all their members are explicitly nothrow-copyable. There are a couple more Qt types that ought to be nothrow-copyable too, like QBitArray and QUrl. Change-Id: I3859764fed084846bcb0fffd17044b5ebb046ee9 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant: update constructors for trivially copyable typesThiago Macieira2022-07-271-38/+40
| | | | | | | | | | | | | Make them all noexcept and ensure they are all passed by value. Unfortunately for QRectF and QLineF, they're too big when qreal==double, so QVariant needs to allocate memory itself. Strictly speaking, they're too big for passing by value too, but the codegen is identical, so we may as well. For Qt 7, enlarging QVariant::Private would be a good idea. Change-Id: I3859764fed084846bcb0fffd17044ac379b3c1d2 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Lars Knoll <lars.knoll@gmail.com>
* QVariant::PrivateShared: move create() and free() into the .cppThiago Macieira2022-07-271-0/+27
| | | | | | | They don't need to be in the header. They're still inline though. Change-Id: I3859764fed084846bcb0fffd17044f49031feefc Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QVariant::Private: remove old typeId() functionThiago Macieira2022-07-271-14/+14
| | | | | | | Use type().id() instead. Change-Id: I3859764fed084846bcb0fffd17044f0fe10b6ff7 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>