summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus/CppDocument.cpp
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2017-01-06 16:50:37 +0100
committerNikolai Kosjar <nikolai.kosjar@qt.io>2017-01-09 15:38:33 +0000
commitfe0a091802ee8840fc8026befe19b27f91eef1e8 (patch)
treeebfa5f6fde03b3d80cdd7f8d217eedaab81686aa /src/libs/cplusplus/CppDocument.cpp
parentd3f725f39dc89ffb13cb3a51249c6637b178251b (diff)
downloadqt-creator-fe0a091802ee8840fc8026befe19b27f91eef1e8.tar.gz
C++: Fix use-after-free crash when handling auto expressions
The Control of the Document "exprDoc" in ResolveExpression::visit( SimpleNameAST*ast) owns names that are passed on further as part of the LookupItems. However, the life time of that Document and thus the Control ends in that function. Fix by using the appropriate Control object. Task-number: QTCREATORBUG-16731 Change-Id: I5a7af0a67613fff79f7e07865801585c13bb9b45 Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'src/libs/cplusplus/CppDocument.cpp')
-rw-r--r--src/libs/cplusplus/CppDocument.cpp28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index 80476dd8b1..93f3654e4f 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -286,8 +286,10 @@ Document::~Document()
{
delete _translationUnit;
_translationUnit = 0;
- delete _control->diagnosticClient();
- delete _control;
+ if (_control) {
+ delete _control->diagnosticClient();
+ delete _control;
+ }
_control = 0;
}
@@ -296,6 +298,25 @@ Control *Document::control() const
return _control;
}
+Control *Document::swapControl(Control *newControl)
+{
+ if (newControl) {
+ const StringLiteral *fileId = newControl->stringLiteral(_translationUnit->fileId()->chars(),
+ _translationUnit->fileId()->size());
+ const auto newTranslationUnit = new TranslationUnit(newControl, fileId);
+ newTranslationUnit->setLanguageFeatures(_translationUnit->languageFeatures());
+ delete _translationUnit;
+ _translationUnit = newTranslationUnit;
+ } else {
+ delete _translationUnit;
+ _translationUnit = 0;
+ }
+
+ Control *oldControl = _control;
+ _control = newControl;
+ return oldControl;
+}
+
unsigned Document::revision() const
{
return _revision;
@@ -696,7 +717,8 @@ void Document::releaseSourceAndAST()
if (!_keepSourceAndASTCount.deref()) {
_source.clear();
_translationUnit->release();
- _control->squeeze();
+ if (_control)
+ _control->squeeze();
}
}