summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeandro Melo <leandro.melo@nokia.com>2012-06-08 11:52:45 +0200
committerLeandro Melo <leandro.melo@nokia.com>2012-06-11 09:14:59 +0200
commita66e344b424643fce71c127fdfb0a21103ca0171 (patch)
tree389c8a40f822a552d5fdc99aaf1d44a07acbf858
parentec5c280e21ea159287621ab564a14c74582588a5 (diff)
downloadqt-creator-a66e344b424643fce71c127fdfb0a21103ca0171.tar.gz
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>
-rw-r--r--src/libs/3rdparty/cplusplus/Bind.cpp35
-rw-r--r--src/libs/3rdparty/cplusplus/Bind.h2
2 files changed, 23 insertions, 14 deletions
diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp
index 0d006911e4..6df1951b66 100644
--- a/src/libs/3rdparty/cplusplus/Bind.cpp
+++ b/src/libs/3rdparty/cplusplus/Bind.cpp
@@ -1851,6 +1851,8 @@ bool Bind::visit(SimpleDeclarationAST *ast)
name = elabTypeSpec->name->name;
}
+ ensureValidClassName(&name, sourceLocation);
+
ForwardClassDeclaration *decl = control()->newForwardClassDeclaration(sourceLocation, name);
setDeclSpecifiers(decl, type);
_scope->addMember(decl);
@@ -2882,20 +2884,7 @@ bool Bind::visit(ClassSpecifierAST *ast)
}
}
- // get the unqualified class name
- 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);
- }
+ ensureValidClassName(&className, sourceLocation);
}
Class *klass = control()->newClass(sourceLocation, className);
@@ -3124,6 +3113,24 @@ bool Bind::visit(ArrayDeclaratorAST *ast)
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)
{
switch (tokenKind) {
diff --git a/src/libs/3rdparty/cplusplus/Bind.h b/src/libs/3rdparty/cplusplus/Bind.h
index d1fff79ea5..de0cf12557 100644
--- a/src/libs/3rdparty/cplusplus/Bind.h
+++ b/src/libs/3rdparty/cplusplus/Bind.h
@@ -274,6 +274,8 @@ protected:
private:
static const int kMaxDepth;
+ void ensureValidClassName(const Name **name, unsigned sourceLocation);
+
Scope *_scope;
ExpressionTy _expression;
const Name *_name;