aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeandro Melo <[email protected]>2012-09-05 14:26:11 +0200
committerEike Ziller <[email protected]>2012-09-05 14:34:59 +0200
commitc5097ed18389e357c1333ca7713f701d9751dce3 (patch)
tree2e374d45cf10028f3865498c82ffc28f140796e7
parentefa91f005b221da4c366202280aa97ee2a8a7493 (diff)
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 <[email protected]>
-rw-r--r--src/libs/cplusplus/ResolveExpression.cpp55
-rw-r--r--src/libs/cplusplus/ResolveExpression.h7
2 files changed, 48 insertions, 14 deletions
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index a64a61a0bc1..0309c3bcf91 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;
diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h
index 3809f04afc0..6c3a47524fa 100644
--- a/src/libs/cplusplus/ResolveExpression.h
+++ b/src/libs/cplusplus/ResolveExpression.h
@@ -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