Commit f27aa09a authored by Nikolai Kosjar's avatar Nikolai Kosjar Committed by Orgad Shaneh
Browse files

C++: Fix crash on auto deduction with debug enabled



By adding the expression document to the bindings object.

Since ResolveExpression is always initialized with the context of a
TypeOfExpression object, the symbols and names in the expression
document will at least live as long as the most outer TypeOfExpression
object.

Done-with: Orgad Shaneh <orgads@gmail.com>
Task-number: QTCREATORBUG-14253
Change-Id: Ia97c7401a2ada9a36113a04cf39e2283393421dd
Reviewed-by: default avatarOrgad Shaneh <orgads@gmail.com>
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@theqtcompany.com>
parent 8ae18a9c
......@@ -119,6 +119,10 @@ public:
QSharedPointer<Control> control() const
{ return _control; }
/// Adds an expression document in order to keep their symbols and names alive
void addExpressionDocument(Document::Ptr document)
{ _expressionDocuments.append(document); }
bool expandTemplates() const
{ return _expandTemplates; }
void setExpandTemplates(bool expandTemplates)
......@@ -185,6 +189,7 @@ private:
Snapshot _snapshot;
QSharedPointer<Control> _control;
QList<Document::Ptr> _expressionDocuments;
QSet<Namespace *> _processed;
QList<LookupScope *> _entities;
LookupScope *_globalNamespace;
......
......@@ -611,32 +611,14 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
Document::Ptr exprDoc =
documentForExpression(exprTyper.preprocessedExpression(initializer));
exprDoc->check();
_context.bindings()->addExpressionDocument(exprDoc);
DeduceAutoCheck deduceAuto(ast->name->identifier(), exprDoc->translationUnit());
if (deduceAuto._block)
continue;
const QList<LookupItem> &typeItems = exprTyper(extractExpressionAST(exprDoc), exprDoc,
decl->enclosingScope());
if (typeItems.empty())
continue;
Clone cloner(_context.bindings()->control().data());
for (int n = 0; n < typeItems.size(); ++ n) {
FullySpecifiedType newType = cloner.type(typeItems[n].type(), 0);
if (n == 0) {
item.setType(newType);
item.setScope(typeItems[n].scope());
item.setBinding(typeItems[n].binding());
} else {
LookupItem newItem(item);
newItem.setType(newType);
newItem.setScope(typeItems[n].scope());
newItem.setBinding(typeItems[n].binding());
newCandidates.push_back(newItem);
}
}
newCandidates += exprTyper(extractExpressionAST(exprDoc), exprDoc,
decl->enclosingScope());
} else {
item.setType(item.declaration()->type());
item.setScope(item.declaration()->enclosingScope());
......
......@@ -105,7 +105,7 @@ QList<LookupItem> TypeOfExpression::operator()(ExpressionAST *expression,
m_scope = scope;
m_documents.append(document);
m_bindings->addExpressionDocument(document);
m_lookupContext = LookupContext(document, m_thisDocument, m_snapshot, m_bindings);
Q_ASSERT(!m_bindings.isNull());
m_lookupContext.setExpandTemplates(m_expandTemplates);
......@@ -122,7 +122,7 @@ QList<LookupItem> TypeOfExpression::reference(ExpressionAST *expression,
m_scope = scope;
m_documents.append(document);
m_bindings->addExpressionDocument(document);
m_lookupContext = LookupContext(document, m_thisDocument, m_snapshot, m_bindings);
Q_ASSERT(!m_bindings.isNull());
m_lookupContext.setExpandTemplates(m_expandTemplates);
......
......@@ -135,7 +135,6 @@ public:
}
private:
void processEnvironment(Document::Ptr doc, Environment *env,
QSet<QString> *processed) const;
......@@ -148,15 +147,8 @@ private:
Scope *m_scope;
LookupContext m_lookupContext;
mutable QSharedPointer<Environment> m_environment;
bool m_expandTemplates;
// FIXME: This is a temporary hack to avoid dangling pointers.
// Keep the expression documents and thus all the symbols and
// their types alive until they are not needed any more.
QList<Document::Ptr> m_documents;
QSet<const Declaration *> m_autoDeclarationsBeingResolved;
bool m_expandTemplates;
};
ExpressionAST CPLUSPLUS_EXPORT *extractExpressionAST(Document::Ptr doc);
......
Supports Markdown
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