diff options
author | Erik Verbruggen <erik.verbruggen@me.com> | 2013-03-20 13:48:20 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2013-05-03 10:56:26 +0200 |
commit | 8e18adc70f4ea49eb1e20976220d79874228257d (patch) | |
tree | cbdc3f9876bae0610e6eb3282b6baf6c6300ef86 | |
parent | 6999e3c33907c0b4b09902f18dee0407c6d6293e (diff) |
C++: Fix crash in code completion.
Caused by a dangling pointer of a template instantiation which had been
cloned into the wrong control. The fix is to remove that control and
refer to the control of the bindings (which is the correct one).
Change-Id: I951a60f2e613aae1e4ac901ce99c820212018709
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
-rw-r--r-- | src/libs/cplusplus/LookupContext.cpp | 55 | ||||
-rw-r--r-- | src/libs/cplusplus/LookupContext.h | 9 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppfunctiondecldeflink.cpp | 4 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppinsertdecldef.cpp | 4 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfixes.cpp | 4 | ||||
-rw-r--r-- | src/plugins/cpptools/cppcompletionassist.cpp | 4 | ||||
-rw-r--r-- | tests/auto/cplusplus/cxx11/tst_cxx11.cpp | 2 |
7 files changed, 33 insertions, 49 deletions
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index d0041d9537..a8a65fd7b8 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -151,47 +151,42 @@ uint qHash(const FullyQualifiedName &fullyQualifiedName) // LookupContext ///////////////////////////////////////////////////////////////////// LookupContext::LookupContext() - : _control(new Control()) - , m_expandTemplates(false) + : m_expandTemplates(false) { } LookupContext::LookupContext(Document::Ptr thisDocument, const Snapshot &snapshot) - : _expressionDocument(Document::create(QLatin1String("<LookupContext>"))), - _thisDocument(thisDocument), - _snapshot(snapshot), - _control(new Control()), - m_expandTemplates(false) + : _expressionDocument(Document::create(QLatin1String("<LookupContext>"))) + , _thisDocument(thisDocument) + , _snapshot(snapshot) + , m_expandTemplates(false) { } LookupContext::LookupContext(Document::Ptr expressionDocument, Document::Ptr thisDocument, const Snapshot &snapshot) - : _expressionDocument(expressionDocument), - _thisDocument(thisDocument), - _snapshot(snapshot), - _control(new Control()), - m_expandTemplates(false) + : _expressionDocument(expressionDocument) + , _thisDocument(thisDocument) + , _snapshot(snapshot) + , m_expandTemplates(false) { } LookupContext::LookupContext(const LookupContext &other) - : _expressionDocument(other._expressionDocument), - _thisDocument(other._thisDocument), - _snapshot(other._snapshot), - _bindings(other._bindings), - _control(other._control), - m_expandTemplates(other.m_expandTemplates) + : _expressionDocument(other._expressionDocument) + , _thisDocument(other._thisDocument) + , _snapshot(other._snapshot) + , _bindings(other._bindings) + , m_expandTemplates(other.m_expandTemplates) { } -LookupContext &LookupContext::operator = (const LookupContext &other) +LookupContext &LookupContext::operator=(const LookupContext &other) { _expressionDocument = other._expressionDocument; _thisDocument = other._thisDocument; _snapshot = other._snapshot; _bindings = other._bindings; - _control = other._control; m_expandTemplates = other.m_expandTemplates; return *this; } @@ -250,7 +245,7 @@ const Name *LookupContext::minimalName(Symbol *symbol, ClassOrNamespace *target, QSharedPointer<CreateBindings> LookupContext::bindings() const { if (! _bindings) { - _bindings = QSharedPointer<CreateBindings>(new CreateBindings(_thisDocument, _snapshot, control())); + _bindings = QSharedPointer<CreateBindings>(new CreateBindings(_thisDocument, _snapshot)); _bindings->setExpandTemplates(m_expandTemplates); } @@ -262,11 +257,6 @@ void LookupContext::setBindings(QSharedPointer<CreateBindings> bindings) _bindings = bindings; } -QSharedPointer<Control> LookupContext::control() const -{ - return _control; -} - Document::Ptr LookupContext::expressionDocument() const { return _expressionDocument; } @@ -649,7 +639,7 @@ void CreateBindings::lookupInScope(const Name *name, Scope *scope, } if (templateId && (s->isDeclaration() || s->isFunction())) { - FullySpecifiedType ty = DeprecatedGenTemplateInstance::instantiate(templateId, s, _control); + FullySpecifiedType ty = DeprecatedGenTemplateInstance::instantiate(templateId, s, control()); item.setType(ty); // override the type. } @@ -1215,8 +1205,10 @@ ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNa return 0; } -CreateBindings::CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot, QSharedPointer<Control> control) - : _snapshot(snapshot), _control(control), _expandTemplates(false) +CreateBindings::CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot) + : _snapshot(snapshot) + , _control(QSharedPointer<Control>(new Control)) + , _expandTemplates(false) { _globalNamespace = allocClassOrNamespace(/*parent = */ 0); _currentClassOrNamespace = _globalNamespace; @@ -1277,11 +1269,6 @@ void CreateBindings::process(Symbol *symbol) _currentClassOrNamespace->addTodo(symbol); } -QSharedPointer<Control> CreateBindings::control() const -{ - return _control; -} - ClassOrNamespace *CreateBindings::allocClassOrNamespace(ClassOrNamespace *parent) { ClassOrNamespace *e = new ClassOrNamespace(this, parent); diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index be5fb57f69..98ff7ffdbe 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -173,7 +173,7 @@ class CPLUSPLUS_EXPORT CreateBindings: protected SymbolVisitor Q_DISABLE_COPY(CreateBindings) public: - CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot, QSharedPointer<Control> control); + CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot); virtual ~CreateBindings(); /// Returns the binding for the global namespace. @@ -187,7 +187,8 @@ public: /// Returns the Control that must be used to create temporary symbols. /// \internal - QSharedPointer<Control> control() const; + QSharedPointer<Control> control() const + { return _control; } bool expandTemplates() const { return _expandTemplates; } @@ -292,8 +293,6 @@ public: /// \internal void setBindings(QSharedPointer<CreateBindings> bindings); - QSharedPointer<Control> control() const; // ### deprecate - static QList<const Name *> fullyQualifiedName(Symbol *symbol); static QList<const Name *> path(Symbol *symbol); @@ -319,8 +318,6 @@ private: // Bindings mutable QSharedPointer<CreateBindings> _bindings; - QSharedPointer<Control> _control; - bool m_expandTemplates; }; diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp index 7d1764ac52..831d973b6b 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp @@ -621,7 +621,7 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ targetCoN = targetContext.globalNamespace(); UseMinimalNames q(targetCoN); env.enter(&q); - Control *control = sourceContext.control().data(); + Control *control = sourceContext.bindings()->control().data(); // get return type start position and declarator info from declaration DeclaratorAST *declarator = 0; @@ -667,7 +667,7 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targ targetCoN = targetContext.globalNamespace(); UseMinimalNames q(targetCoN); env.enter(&q); - Control *control = sourceContext.control().data(); + Control *control = sourceContext.bindings()->control().data(); Overview overview = overviewFromCurrentProjectStyle; // make a easy to access list of the target parameter declarations diff --git a/src/plugins/cppeditor/cppinsertdecldef.cpp b/src/plugins/cppeditor/cppinsertdecldef.cpp index 51d4558fb9..0828424710 100644 --- a/src/plugins/cppeditor/cppinsertdecldef.cpp +++ b/src/plugins/cppeditor/cppinsertdecldef.cpp @@ -259,7 +259,7 @@ public: env.switchScope(m_decl->enclosingScope()); UseMinimalNames q(targetCoN); env.enter(&q); - Control *control = assistInterface()->context().control().data(); + Control *control = assistInterface()->context().bindings()->control().data(); // rewrite the function type FullySpecifiedType tn = rewriteType(m_decl->type(), &env, control); @@ -651,7 +651,7 @@ public: env.enter(&subs); Overview printer = CppCodeStyleSettings::currentProjectCodeStyleOverview(); - Control *control = assistInterface()->context().control().data(); + Control *control = assistInterface()->context().bindings()->control().data(); QString funcDef; QString funcDecl; // We generate a declaration only in the case of a member function. QString funcCall; diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 5454753f3c..f9c04a1ad2 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -1069,7 +1069,7 @@ void TranslateStringLiteral::match(const CppQuickFixInterface &interface, QString trContext; - QSharedPointer<Control> control = interface->context().control(); + QSharedPointer<Control> control = interface->context().bindings()->control(); const Name *trName = control->identifier("tr"); // Check whether we are in a method: @@ -1471,7 +1471,7 @@ public: UseMinimalNames q(con); env.enter(&q); - Control *control = assistInterface()->context().control().data(); + Control *control = assistInterface()->context().bindings()->control().data(); FullySpecifiedType tn = rewriteType(result.first().type(), &env, control); Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview(); diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index d9e12a95ec..736722657f 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -1778,7 +1778,7 @@ bool CppCompletionAssistProcessor::completeConstructorOrFunction(const QList<CPl } if (functions.isEmpty()) { - const Name *functionCallOp = context.control()->operatorNameId(OperatorNameId::FunctionCallOp); + const Name *functionCallOp = context.bindings()->control()->operatorNameId(OperatorNameId::FunctionCallOp); foreach (const LookupItem &result, results) { FullySpecifiedType ty = result.type().simplified(); @@ -1873,7 +1873,7 @@ bool CppCompletionAssistProcessor::completeConstructorOrFunction(const QList<CPl targetCoN = context.globalNamespace(); UseMinimalNames q(targetCoN); env.enter(&q); - Control *control = context.control().data(); + Control *control = context.bindings()->control().data(); // set up signature autocompletion foreach (Function *f, functions) { diff --git a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp index 51a9f05aeb..2c78b9bd32 100644 --- a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp +++ b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp @@ -174,7 +174,7 @@ void tst_cxx11::inlineNamespaceLookup() snapshot.insert(doc); LookupContext context(doc, snapshot); - QSharedPointer<Control> control = context.control(); + QSharedPointer<Control> control = context.bindings()->control(); QList<LookupItem> results = context.lookup(control->identifier("foo"), doc->globalNamespace()); QCOMPARE(results.size(), 1); // the symbol is visible from the global scope |