Commit 29055f9f authored by Nikolai Kosjar's avatar Nikolai Kosjar
Browse files

C++: Fix crash due to dangling pointer



ResolveExpression used the wrong Control object, which was deleted by
~LookupContext() in TypeOfExpression::operator()). ~Control() led to the
dangling pointer.

Task-number: QTCREATORBUG-8890
Done-with: Erik Verbruggen <erik.verbruggen@digia.com>

Change-Id: Ic07947ee54087446b730e4d3ec4bef29defa4495
Reviewed-by: default avatarErik Verbruggen <erik.verbruggen@digia.com>
parent de489ad4
......@@ -548,7 +548,7 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
if (typeItems.empty())
continue;
CPlusPlus::Clone cloner(_context.control().data());
CPlusPlus::Clone cloner(_context.bindings()->control().data());
for (int n = 0; n < typeItems.size(); ++ n) {
FullySpecifiedType newType = cloner.type(typeItems[n].type(), 0);
......@@ -1061,7 +1061,8 @@ ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &bas
FullySpecifiedType ResolveExpression::instantiate(const Name *className, Symbol *candidate) const
{
return DeprecatedGenTemplateInstance::instantiate(className, candidate, _context.control());
return DeprecatedGenTemplateInstance::instantiate(className, candidate,
_context.bindings()->control());
}
bool ResolveExpression::visit(PostIncrDecrAST *ast)
......
......@@ -176,6 +176,8 @@ private slots:
void test_checksymbols_StaticUse();
void test_checksymbols_VariableHasTheSameNameAsEnumUse();
void test_checksymbols_NestedClassOfEnclosingTemplateUse();
void test_checksymbols_QTCREATORBUG8890_danglingPointer();
};
void tst_CheckSymbols::test_checksymbols_TypeUse()
......@@ -442,5 +444,56 @@ void tst_CheckSymbols::test_checksymbols_NestedClassOfEnclosingTemplateUse()
TestData::check(source, expectedUses);
}
void tst_CheckSymbols::test_checksymbols_QTCREATORBUG8890_danglingPointer()
{
const QByteArray source =
"template<class T> class QList {\n"
" public:\n"
" T operator[](int);\n"
"};\n"
"\n"
"template<class T> class QPointer {\n"
" public:\n"
" T& operator->();\n"
"};\n"
"\n"
"class Foo {\n"
" void foo() {}\n"
"};\n"
"\n"
"void f()\n"
"{\n"
" QList<QPointer<Foo> > list;\n"
" list[0]->foo();\n"
" list[0]->foo(); // Crashed because of this 'extra' line.\n"
"}\n"
;
const QList<Use> expectedUses = QList<Use>()
<< Use(1, 16, 1, SemanticInfo::TypeUse)
<< Use(1, 25, 5, SemanticInfo::TypeUse)
<< Use(3, 9, 1, SemanticInfo::TypeUse)
<< Use(3, 11, 8, SemanticInfo::FunctionUse)
<< Use(6, 16, 1, SemanticInfo::TypeUse)
<< Use(6, 25, 8, SemanticInfo::TypeUse)
<< Use(8, 9, 1, SemanticInfo::TypeUse)
<< Use(8, 12, 8, SemanticInfo::FunctionUse)
<< Use(11, 7, 3, SemanticInfo::TypeUse)
<< Use(12, 10, 3, SemanticInfo::FunctionUse)
<< Use(15, 6, 1, SemanticInfo::FunctionUse)
<< Use(17, 5, 5, SemanticInfo::TypeUse)
<< Use(17, 11, 8, SemanticInfo::TypeUse)
<< Use(17, 20, 3, SemanticInfo::TypeUse)
<< Use(17, 27, 4, SemanticInfo::LocalUse)
<< Use(18, 5, 4, SemanticInfo::LocalUse)
<< Use(18, 14, 3, SemanticInfo::FunctionUse)
<< Use(19, 5, 4, SemanticInfo::LocalUse)
<< Use(19, 14, 3, SemanticInfo::FunctionUse)
;
TestData::check(source, expectedUses);
}
QTEST_APPLESS_MAIN(tst_CheckSymbols)
#include "tst_checksymbols.moc"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment