Don't leave m_rootProjectNode in moved-out state

After calling FileApiReader::generateProjectTree(), the
m_rootProjectNode was left in a moved-out state, meaning
that it was in a corrupted state. However, it was still
possible, that later FileApiReader::resetData() was called
for the same instance of FileApiReader, so a call to
m_rootProjectNode.reset() was executed on an invalid object.
This might lead to a crash.

The fix is to use std::exchange instead and we are leaving
the m_rootProjectNode in a valid, default-constructed state.

We do the same for other members, for consistency.

Task-number: QTCREATORBUG-25837
Change-Id: I5812e410d11c8a3fd5a7c9db002d2ef244ae89cd
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
Jarek Kobus
2021-06-08 18:06:40 +02:00
parent ef9ba20704
commit 150cc88db1

View File

@@ -187,9 +187,7 @@ QSet<FilePath> FileApiReader::projectFilesToWatch() const
QList<CMakeBuildTarget> FileApiReader::takeBuildTargets(QString &errorMessage){ QList<CMakeBuildTarget> FileApiReader::takeBuildTargets(QString &errorMessage){
Q_UNUSED(errorMessage) Q_UNUSED(errorMessage)
auto result = std::move(m_buildTargets); return std::exchange(m_buildTargets, {});
m_buildTargets.clear();
return result;
} }
CMakeConfig FileApiReader::takeParsedConfiguration(QString &errorMessage) CMakeConfig FileApiReader::takeParsedConfiguration(QString &errorMessage)
@@ -197,9 +195,7 @@ CMakeConfig FileApiReader::takeParsedConfiguration(QString &errorMessage)
if (m_lastCMakeExitCode != 0) if (m_lastCMakeExitCode != 0)
errorMessage = tr("CMake returned error code: %1").arg(m_lastCMakeExitCode); errorMessage = tr("CMake returned error code: %1").arg(m_lastCMakeExitCode);
CMakeConfig cache = m_cache; return std::exchange(m_cache, {});
m_cache.clear();
return cache;
} }
QString FileApiReader::ctestPath() const QString FileApiReader::ctestPath() const
@@ -227,16 +223,14 @@ std::unique_ptr<CMakeProjectNode> FileApiReader::generateProjectTree(
addHeaderNodes(m_rootProjectNode.get(), m_knownHeaders, allFiles); addHeaderNodes(m_rootProjectNode.get(), m_knownHeaders, allFiles);
} }
addFileSystemNodes(m_rootProjectNode.get(), allFiles); addFileSystemNodes(m_rootProjectNode.get(), allFiles);
return std::move(m_rootProjectNode); return std::exchange(m_rootProjectNode, {});
} }
RawProjectParts FileApiReader::createRawProjectParts(QString &errorMessage) RawProjectParts FileApiReader::createRawProjectParts(QString &errorMessage)
{ {
Q_UNUSED(errorMessage) Q_UNUSED(errorMessage)
RawProjectParts result = std::move(m_projectParts); return std::exchange(m_projectParts, {});
m_projectParts.clear();
return result;
} }
void FileApiReader::startState() void FileApiReader::startState()