QLocale: fix unintended copy [2/2]: QCalendarBackend::dateTimeToString()

Coverity complained that 'text' was copied when it could have been
moved.

This is correct, but not trivial to understand: If, in a ternary
expression, one of the legs is an rvalue and the other is an lvalue,
then the ternary expression is also an rvalue. So the return statement
invokes the QString move constructor.

But, of course, the lvalue isn't being moved from in this case.
Instead, lvalue-to-rvalue conversion materializes a temporary QString
as a copy of lvalue, and _that_ is moved instead. This is what happens
with 'text' and why Coverity complains about a copy.

Note that this is purely due to the use of the ternary: If we write a
normal if, then the lvalue leg returns a local object and we get a
move from it for free. In fact, the structure of the lambda is such
that NRVO should kick in, so neither copy nor move, but direct
construction into the caller-supplied storage of the return object.

To fix, rewrite the code using a normal if statement, taking care to
not break the NRVO the rest of the function so carefully tries to
maintain.

This likely also fixes CID-469957 where Coverity complains that this
lambda's implicit auto return type causes a copy and - incorrectly!
- suggests to explicitly return const QString& (which would return a
reference to a local object).

Amends 1b909695a6.

Coverity-Id: 469949
Coverity-Id: 469957
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ia858fd6bddbb51d824b29b0e60d26c18c1c7fb5d
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Marc Mutz 2025-08-02 07:23:43 +02:00
parent cd96362492
commit 5b1e49a7e2
1 changed files with 3 additions and 1 deletions

View File

@ -3996,7 +3996,9 @@ QString QCalendarBackend::dateTimeToString(QStringView format, const QDateTime &
text = when.toOffsetFromUtc(when.offsetFromUtc()).timeZoneAbbreviation();
if (text.isEmpty()) // Notably including type != Offset
text = when.timeZoneAbbreviation();
return type == Offset ? offsetFromAbbreviation(std::move(text)) : text;
if (type == Offset)
text = offsetFromAbbreviation(std::move(text));
return text;
};
used = true;