forked from qt-creator/qt-creator
C++: Fix crash on invalid class name
Task-number: QTCREATORBUG-7462 Change-Id: Ic1df4b535c5a617efa707110138c76e6e7ef1e4b Reviewed-by: Robert Löhning <robert.loehning@nokia.com> Reviewed-by: Leandro Melo <leandro.melo@nokia.com>
This commit is contained in:
35
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
35
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -1851,6 +1851,8 @@ bool Bind::visit(SimpleDeclarationAST *ast)
|
|||||||
name = elabTypeSpec->name->name;
|
name = elabTypeSpec->name->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensureValidClassName(&name, sourceLocation);
|
||||||
|
|
||||||
ForwardClassDeclaration *decl = control()->newForwardClassDeclaration(sourceLocation, name);
|
ForwardClassDeclaration *decl = control()->newForwardClassDeclaration(sourceLocation, name);
|
||||||
setDeclSpecifiers(decl, type);
|
setDeclSpecifiers(decl, type);
|
||||||
_scope->addMember(decl);
|
_scope->addMember(decl);
|
||||||
@@ -2882,20 +2884,7 @@ bool Bind::visit(ClassSpecifierAST *ast)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the unqualified class name
|
ensureValidClassName(&className, sourceLocation);
|
||||||
const QualifiedNameId *q = className->asQualifiedNameId();
|
|
||||||
const Name *unqualifiedClassName = q ? q->name() : className;
|
|
||||||
|
|
||||||
if (! unqualifiedClassName) // paranoia check
|
|
||||||
className = 0;
|
|
||||||
else if (! (unqualifiedClassName->isNameId() || unqualifiedClassName->isTemplateNameId())) {
|
|
||||||
translationUnit()->error(sourceLocation, "expected a class-name");
|
|
||||||
|
|
||||||
className = unqualifiedClassName->identifier();
|
|
||||||
|
|
||||||
if (q && className)
|
|
||||||
className = control()->qualifiedNameId(q->base(), className);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Class *klass = control()->newClass(sourceLocation, className);
|
Class *klass = control()->newClass(sourceLocation, className);
|
||||||
@@ -3124,6 +3113,24 @@ bool Bind::visit(ArrayDeclaratorAST *ast)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bind::ensureValidClassName(const Name **name, unsigned sourceLocation)
|
||||||
|
{
|
||||||
|
if (!*name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const QualifiedNameId *qName = (*name)->asQualifiedNameId();
|
||||||
|
if (qName)
|
||||||
|
*name = qName->name();
|
||||||
|
|
||||||
|
if (!(*name)->isNameId() && !(*name)->isTemplateNameId()) {
|
||||||
|
translationUnit()->error(sourceLocation, "expected a class-name");
|
||||||
|
|
||||||
|
*name = (*name)->identifier();
|
||||||
|
if (qName)
|
||||||
|
*name = control()->qualifiedNameId(qName->base(), *name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int Bind::visibilityForAccessSpecifier(int tokenKind)
|
int Bind::visibilityForAccessSpecifier(int tokenKind)
|
||||||
{
|
{
|
||||||
switch (tokenKind) {
|
switch (tokenKind) {
|
||||||
|
2
src/libs/3rdparty/cplusplus/Bind.h
vendored
2
src/libs/3rdparty/cplusplus/Bind.h
vendored
@@ -274,6 +274,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
static const int kMaxDepth;
|
static const int kMaxDepth;
|
||||||
|
|
||||||
|
void ensureValidClassName(const Name **name, unsigned sourceLocation);
|
||||||
|
|
||||||
Scope *_scope;
|
Scope *_scope;
|
||||||
ExpressionTy _expression;
|
ExpressionTy _expression;
|
||||||
const Name *_name;
|
const Name *_name;
|
||||||
|
Reference in New Issue
Block a user