forked from qt-creator/qt-creator
		
	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: Eike Ziller <eike.ziller@nokia.com>
This commit is contained in:
		
				
					committed by
					
						
						Eike Ziller
					
				
			
			
				
	
			
			
			
						parent
						
							efa91f005b
						
					
				
				
					commit
					c5097ed183
				
			@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user