diff options
author | Leandro Melo <leandro.melo@nokia.com> | 2012-09-05 14:26:11 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@nokia.com> | 2012-09-05 14:34:59 +0200 |
commit | c5097ed18389e357c1333ca7713f701d9751dce3 (patch) | |
tree | 2e374d45cf10028f3865498c82ffc28f140796e7 /src/libs/cplusplus/ResolveExpression.cpp | |
parent | efa91f005b221da4c366202280aa97ee2a8a7493 (diff) | |
download | qt-creator-c5097ed18389e357c1333ca7713f701d9751dce3.tar.gz |
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>
Diffstat (limited to 'src/libs/cplusplus/ResolveExpression.cpp')
-rw-r--r-- | src/libs/cplusplus/ResolveExpression.cpp | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index a64a61a0bc..0309c3bcf9 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -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; |