summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qmake/generators/metamakefile.cpp4
-rw-r--r--src/corelib/global/qlibraryinfo.cpp4
-rw-r--r--src/corelib/io/qfileinfo.cpp57
-rw-r--r--src/corelib/io/qfileinfo.h19
-rw-r--r--src/gui/itemmodels/qfileinfogatherer.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp2
-rw-r--r--src/testlib/qtestcase.cpp2
-rw-r--r--src/tools/androiddeployqt/main.cpp5
-rw-r--r--tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp2
-rw-r--r--tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp2
10 files changed, 83 insertions, 17 deletions
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp
index 8d1eb1d886..8ba941c213 100644
--- a/qmake/generators/metamakefile.cpp
+++ b/qmake/generators/metamakefile.cpp
@@ -335,11 +335,11 @@ SubdirsMetaMakefileGenerator::init()
QFileInfo subdir(subdirs.at(i).toQString());
const ProKey fkey(subdirs.at(i) + ".file");
if (!project->isEmpty(fkey)) {
- subdir = project->first(fkey).toQString();
+ subdir = QFileInfo(project->first(fkey).toQString());
} else {
const ProKey skey(subdirs.at(i) + ".subdir");
if (!project->isEmpty(skey))
- subdir = project->first(skey).toQString();
+ subdir = QFileInfo(project->first(skey).toQString());
}
QString sub_name;
if(subdir.isDir())
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 990c4269e3..4cd940a7a3 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -597,8 +597,8 @@ QString qmake_abslocation();
static QString getPrefixFromHostBinDir(const char *hostBinDirToPrefixPath)
{
- const QFileInfo qmfi = QFileInfo(qmake_abslocation()).canonicalFilePath();
- return QDir::cleanPath(qmfi.absolutePath() + QLatin1Char('/')
+ const QString canonicalQMakePath = QFileInfo(qmake_abslocation()).canonicalPath();
+ return QDir::cleanPath(canonicalQMakePath + QLatin1Char('/')
+ QLatin1String(hostBinDirToPrefixPath));
}
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 8b80141a32..4b81467687 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -1621,5 +1621,62 @@ QDebug operator<<(QDebug dbg, const QFileInfo &fi)
Returns symLinkTarget() as a \c{std::filesystem::path}.
\sa symLinkTarget()
*/
+/*!
+ \macro QT_IMPLICIT_QFILEINFO_CONSTRUCTION
+ \since 6.0
+ \relates QFileInfo
+
+ Defining this macro makes most QFileInfo constructors implicit
+ instead of explicit. Since construction of QFileInfo objects is
+ expensive, one should avoid accidentally creating them, especially
+ if cheaper alternatives exist. For instance:
+
+ \badcode
+
+ QDirIterator it(dir);
+ while (it.hasNext()) {
+ // Implicit conversion from QString (returned by it.next()):
+ // may create unnecessary data strucutres and cause additional
+ // accesses to the file system. Unless this macro is defined,
+ // this line does not compile.
+
+ QFileInfo fi = it.next();
+
+ ~~~
+ }
+
+ \endcode
+
+ Instead, use the right API:
+
+ \code
+
+ QDirIterator it(dir);
+ while (it.hasNext()) {
+ it.next();
+
+ // Extract the QFileInfo from the iterator directly:
+ QFileInfo fi = it.fileInfo();
+
+ ~~~
+ }
+
+ \endcode
+
+ Construction from QString, QFile, and so on is always possible by
+ using direct initialization instead of copy initialization:
+
+ \code
+
+ QFileInfo fi1 = some_string; // Does not compile unless this macro is defined
+ QFileInfo fi2(some_string); // OK
+ QFileInfo fi3{some_string}; // Possibly better, avoids the risk of the Most Vexing Parse
+ auto fi4 = QFileInfo(some_string); // OK
+
+ \endcode
+
+ This macro is provided for compatibility reason. Its usage is not
+ recommended in new code.
+*/
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h
index 344c16abf8..90be1c2540 100644
--- a/src/corelib/io/qfileinfo.h
+++ b/src/corelib/io/qfileinfo.h
@@ -59,23 +59,32 @@ class Q_CORE_EXPORT QFileInfo
public:
explicit QFileInfo(QFileInfoPrivate *d);
+#ifdef QT_IMPLICIT_QFILEINFO_CONSTRUCTION
+#define QFILEINFO_MAYBE_EXPLICIT Q_IMPLICIT
+#else
+#define QFILEINFO_MAYBE_EXPLICIT explicit
+#endif
+
QFileInfo();
- QFileInfo(const QString &file);
- QFileInfo(const QFileDevice &file);
- QFileInfo(const QDir &dir, const QString &file);
+ QFILEINFO_MAYBE_EXPLICIT QFileInfo(const QString &file);
+ QFILEINFO_MAYBE_EXPLICIT QFileInfo(const QFileDevice &file);
+ QFILEINFO_MAYBE_EXPLICIT QFileInfo(const QDir &dir, const QString &file);
QFileInfo(const QFileInfo &fileinfo);
#ifdef Q_CLANG_QDOC
QFileInfo(const std::filesystem::path &file);
QFileInfo(const QDir &dir, const std::filesystem::path &file);
#elif QT_CONFIG(cxx17_filesystem)
template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
- QFileInfo(const T &file) : QFileInfo(QtPrivate::fromFilesystemPath(file)) { }
+ QFILEINFO_MAYBE_EXPLICIT QFileInfo(const T &file) : QFileInfo(QtPrivate::fromFilesystemPath(file)) { }
template<typename T, QtPrivate::ForceFilesystemPath<T> = 0>
- QFileInfo(const QDir &dir, const T &file) : QFileInfo(dir, QtPrivate::fromFilesystemPath(file))
+ QFILEINFO_MAYBE_EXPLICIT QFileInfo(const QDir &dir, const T &file) : QFileInfo(dir, QtPrivate::fromFilesystemPath(file))
{
}
#endif // QT_CONFIG(cxx17_filesystem)
+
+#undef QFILEINFO_MAYBE_EXPLICIT
+
~QFileInfo();
QFileInfo &operator=(const QFileInfo &fileinfo);
diff --git a/src/gui/itemmodels/qfileinfogatherer.cpp b/src/gui/itemmodels/qfileinfogatherer.cpp
index 417c3d7e42..bd368e945c 100644
--- a/src/gui/itemmodels/qfileinfogatherer.cpp
+++ b/src/gui/itemmodels/qfileinfogatherer.cpp
@@ -350,8 +350,7 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const
#ifdef Q_OS_WIN
if (m_resolveSymlinks && info.isSymLink(/* ignoreNtfsSymLinks = */ true)) {
- QFileInfo resolvedInfo(fileInfo.symLinkTarget());
- resolvedInfo = resolvedInfo.canonicalFilePath();
+ QFileInfo resolvedInfo(QFileInfo(fileInfo.symLinkTarget()).canonicalFilePath());
if (resolvedInfo.exists()) {
emit nameResolved(fileInfo.filePath(), resolvedInfo.fileName());
}
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index e9697f505b..002fccba07 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -230,7 +230,7 @@ static void sm_performSaveYourself(QXcbSessionManager *sm)
restart << argument0 << QLatin1String("-session")
<< sm->sessionId() + QLatin1Char('_') + sm->sessionKey();
- QFileInfo fi = QCoreApplication::applicationFilePath();
+ QFileInfo fi(QCoreApplication::applicationFilePath());
if (qAppName().compare(fi.fileName(), Qt::CaseInsensitive) != 0)
restart << QLatin1String("-name") << qAppName();
sm->setRestartCommand(restart);
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 992149ff20..7bca8de1b6 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -2211,7 +2211,7 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co
// 3. relative to test source.
if (found.isEmpty() && qstrncmp(file, ":/", 2) != 0) {
// srcdir is the directory containing the calling source file.
- QFileInfo srcdir = QFileInfo(QFile::decodeName(file)).path();
+ QFileInfo srcdir(QFileInfo(QFile::decodeName(file)).path());
// If the srcdir is relative, that means it is relative to the current working
// directory of the compiler at compile time, which should be passed in as `builddir'.
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 0e04f97a33..1b29fe7381 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -1561,8 +1561,9 @@ QList<QtDependency> findFilesRecursively(const Options &options, const QFileInfo
const QStringList entries = dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString &entry : entries) {
- QString s = info.absoluteFilePath() + QLatin1Char('/') + entry;
- ret += findFilesRecursively(options, s, rootPath);
+ ret += findFilesRecursively(options,
+ QFileInfo(info.absoluteFilePath() + QChar(u'/') + entry),
+ rootPath);
}
return ret;
diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
index b0b076310d..2d7c1b295a 100644
--- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
+++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
@@ -364,7 +364,7 @@ static inline QFileInfo findSh()
const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, Qt::SkipEmptyParts);
foreach (const QString &path, rawPaths) {
if (QFile::exists(path + sh))
- return path + sh;
+ return QFileInfo(path + sh);
}
return QFileInfo();
}
diff --git a/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp b/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp
index 4824973576..9e9625854e 100644
--- a/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp
+++ b/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp
@@ -126,7 +126,7 @@ void tst_QFileIconProvider::type()
static QIcon getIcon()
{
QFileIconProvider fip;
- return fip.icon(QDir::currentPath());
+ return fip.icon(QFileInfo(QDir::currentPath()));
}
void tst_QFileIconProvider::taskQTBUG_46755_QFileIconEngine_crash()