forked from qt-creator/qt-creator
C++: Fix crash when deducing auto (with invalid ids)
Task-number: QTCREATORBUG-7801 Change-Id: I61436148ed1428a50a6840ba9109310a57dabaa4 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
This commit is contained in:
@@ -88,7 +88,9 @@ static void path_helper(Symbol *symbol, QList<const Name *> *names)
|
||||
}
|
||||
}
|
||||
|
||||
static bool compareName(const Name *name, const Name *other)
|
||||
namespace CPlusPlus {
|
||||
|
||||
bool compareName(const Name *name, const Name *other)
|
||||
{
|
||||
if (name == other)
|
||||
return true;
|
||||
@@ -104,8 +106,6 @@ static bool compareName(const Name *name, const Name *other)
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace CPlusPlus {
|
||||
|
||||
bool compareFullyQualifiedName(const QList<const Name *> &path, const QList<const Name *> &other)
|
||||
{
|
||||
if (path.length() != other.length())
|
||||
|
@@ -252,6 +252,7 @@ private:
|
||||
QSharedPointer<Control> _control;
|
||||
};
|
||||
|
||||
bool CPLUSPLUS_EXPORT compareName(const Name *name, const Name *other);
|
||||
bool CPLUSPLUS_EXPORT compareFullyQualifiedName(const QList<const Name *> &path,
|
||||
const QList<const Name *> &other);
|
||||
|
||||
|
@@ -473,27 +473,38 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
|
||||
if (item.declaration() == 0)
|
||||
continue;
|
||||
|
||||
if (item.type().isAuto()) {
|
||||
if (item.type().isAuto()
|
||||
&& _blockedIds.find(ast->name->identifier()) == _blockedIds.end()) {
|
||||
const Declaration *decl = item.declaration()->asDeclaration();
|
||||
if (!decl)
|
||||
continue;
|
||||
|
||||
Document::Ptr doc = _context.snapshot().document(decl->fileName());
|
||||
|
||||
const StringLiteral *initializationString = decl->getInitializer();
|
||||
if (initializationString == 0)
|
||||
continue;
|
||||
|
||||
QByteArray initializer = QByteArray::fromRawData(initializationString->chars(), initializationString->size()).trimmed();
|
||||
const QByteArray &initializer =
|
||||
QByteArray::fromRawData(initializationString->chars(),
|
||||
initializationString->size()).trimmed();
|
||||
|
||||
// Skip lambda-function initializers
|
||||
if (initializer.length() > 0 && initializer[0] == '[')
|
||||
continue;
|
||||
|
||||
TypeOfExpression exprTyper;
|
||||
Document::Ptr doc = _context.snapshot().document(decl->fileName());
|
||||
exprTyper.init(doc, _context.snapshot(), _context.bindings());
|
||||
|
||||
QList<LookupItem> typeItems = exprTyper(initializer, decl->enclosingScope(), TypeOfExpression::Preprocess);
|
||||
Document::Ptr exprDoc =
|
||||
documentForExpression(exprTyper.preprocessedExpression(initializer));
|
||||
exprDoc->check();
|
||||
ExpressionAST *exprAST = extractExpressionAST(exprDoc);
|
||||
if (!exprAST)
|
||||
continue;
|
||||
|
||||
_blockedIds.insert(ast->name->identifier());
|
||||
const QList<LookupItem> &typeItems = resolve(exprAST, decl->enclosingScope());
|
||||
_blockedIds.erase(ast->name->identifier());
|
||||
if (typeItems.empty())
|
||||
continue;
|
||||
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include <ASTVisitor.h>
|
||||
#include <FullySpecifiedType.h>
|
||||
#include <Bind.h>
|
||||
#include <set>
|
||||
|
||||
namespace CPlusPlus {
|
||||
|
||||
@@ -118,12 +119,20 @@ protected:
|
||||
// Objective-C expressions
|
||||
virtual bool visit(ObjCMessageExpressionAST *ast);
|
||||
|
||||
|
||||
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
|
||||
|
@@ -163,23 +163,6 @@ ExpressionAST *TypeOfExpression::expressionAST() const
|
||||
return extractExpressionAST(m_lookupContext.expressionDocument());
|
||||
}
|
||||
|
||||
ExpressionAST *TypeOfExpression::extractExpressionAST(Document::Ptr doc) const
|
||||
{
|
||||
if (! doc->translationUnit()->ast())
|
||||
return 0;
|
||||
|
||||
return doc->translationUnit()->ast()->asExpression();
|
||||
}
|
||||
|
||||
Document::Ptr TypeOfExpression::documentForExpression(const QByteArray &utf8code) const
|
||||
{
|
||||
// create the expression's AST.
|
||||
Document::Ptr doc = Document::create(QLatin1String("<completion>"));
|
||||
doc->setUtf8Source(utf8code);
|
||||
doc->parse(Document::ParseExpression);
|
||||
return doc;
|
||||
}
|
||||
|
||||
void TypeOfExpression::processEnvironment(Document::Ptr doc, Environment *env,
|
||||
QSet<QString> *processed) const
|
||||
{
|
||||
@@ -210,3 +193,24 @@ QByteArray TypeOfExpression::preprocessedExpression(const QByteArray &utf8code)
|
||||
Preprocessor preproc(0, m_environment.data());
|
||||
return preproc.run("<expression>", utf8code);
|
||||
}
|
||||
|
||||
namespace CPlusPlus {
|
||||
|
||||
ExpressionAST *extractExpressionAST(Document::Ptr doc)
|
||||
{
|
||||
if (! doc->translationUnit()->ast())
|
||||
return 0;
|
||||
|
||||
return doc->translationUnit()->ast()->asExpression();
|
||||
}
|
||||
|
||||
Document::Ptr documentForExpression(const QByteArray &utf8code)
|
||||
{
|
||||
// create the expression's AST.
|
||||
Document::Ptr doc = Document::create(QLatin1String("<completion>"));
|
||||
doc->setUtf8Source(utf8code);
|
||||
doc->parse(Document::ParseExpression);
|
||||
return doc;
|
||||
}
|
||||
|
||||
} // namespace CPlusPlus
|
||||
|
@@ -122,15 +122,13 @@ public:
|
||||
Scope *scope() const;
|
||||
|
||||
ExpressionAST *expressionAST() const;
|
||||
QByteArray preprocessedExpression(const QByteArray &utf8code) const;
|
||||
|
||||
private:
|
||||
ExpressionAST *extractExpressionAST(Document::Ptr doc) const;
|
||||
Document::Ptr documentForExpression(const QByteArray &utf8code) const;
|
||||
|
||||
void processEnvironment(Document::Ptr doc, Environment *env,
|
||||
QSet<QString> *processed) const;
|
||||
|
||||
QByteArray preprocessedExpression(const QByteArray &utf8code) const;
|
||||
|
||||
private:
|
||||
Document::Ptr m_thisDocument;
|
||||
@@ -142,6 +140,9 @@ private:
|
||||
mutable QSharedPointer<Environment> m_environment;
|
||||
};
|
||||
|
||||
ExpressionAST CPLUSPLUS_EXPORT *extractExpressionAST(Document::Ptr doc);
|
||||
Document::Ptr CPLUSPLUS_EXPORT documentForExpression(const QByteArray &utf8code);
|
||||
|
||||
} // namespace CPlusPlus
|
||||
|
||||
#endif // CPLUSPLUS_TYPEOFEXPRESSION_H
|
||||
|
Reference in New Issue
Block a user