Commit c5097ed1 authored by Leandro Melo's avatar Leandro Melo Committed by Eike Ziller
Browse files

C++: Fix crash in auto deducing mechanism



There was an inconsistency, since the AST used in ResolveExpression
was not really the same previously computed. In the particular issue
below a crash could occur, for example, when using auto in a for
range loop.

Task-number: QTCREATORBUG-7828
Change-Id: I02958f434c3cf3b50609546003fc141674ee78d5
Reviewed-by: default avatarEike Ziller <eike.ziller@nokia.com>
parent efa91f00
......@@ -460,6 +460,48 @@ bool ResolveExpression::visit(QualifiedNameAST *ast)
return false;
}
namespace {
class DeduceAutoCheck : public ASTVisitor
{
public:
DeduceAutoCheck(const Identifier *id, TranslationUnit *tu)
: ASTVisitor(tu), _id(id), _block(false)
{
accept(tu->ast());
}
virtual bool preVisit(AST *)
{
if (_block)
return false;
return true;
}
virtual bool visit(SimpleNameAST *ast)
{
if (ast->name
&& ast->name->identifier()
&& strcmp(ast->name->identifier()->chars(), _id->chars()) == 0) {
_block = true;
}
return false;
}
virtual bool visit(MemberAccessAST *ast)
{
accept(ast->base_expression);
return false;
}
const Identifier *_id;
bool _block;
};
} // namespace anonymous
bool ResolveExpression::visit(SimpleNameAST *ast)
{
QList<LookupItem> candidates = _context.lookup(ast->name, _scope);
......@@ -473,8 +515,7 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
if (item.declaration() == 0)
continue;
if (item.type().isAuto()
&& _blockedIds.find(ast->name->identifier()) == _blockedIds.end()) {
if (item.type().isAuto()) {
const Declaration *decl = item.declaration()->asDeclaration();
if (!decl)
continue;
......@@ -498,13 +539,13 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
Document::Ptr exprDoc =
documentForExpression(exprTyper.preprocessedExpression(initializer));
exprDoc->check();
ExpressionAST *exprAST = extractExpressionAST(exprDoc);
if (!exprAST)
DeduceAutoCheck deduceAuto(ast->name->identifier(), exprDoc->translationUnit());
if (deduceAuto._block)
continue;
_blockedIds.insert(ast->name->identifier());
const QList<LookupItem> &typeItems = resolve(exprAST, decl->enclosingScope());
_blockedIds.erase(ast->name->identifier());
const QList<LookupItem> &typeItems =
exprTyper(extractExpressionAST(exprDoc), exprDoc, decl->enclosingScope());
if (typeItems.empty())
continue;
......
......@@ -121,18 +121,11 @@ protected:
private:
struct IdentifierComp
{
bool operator()(const Identifier *a, const Identifier *b) const
{ return strcmp(a->chars(), b->chars()) < 0; }
};
Scope *_scope;
LookupContext _context;
Bind bind;
QList<LookupItem> _results;
bool _reference;
std::set<const Identifier *, IdentifierComp> _blockedIds; // Replace by a hash impl.
};
} // namespace CPlusPlus
......
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