From 10e947f65f19ec61e29afbaf167bf3439b5bea11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lassi=20H=C3=A4m=C3=A4l=C3=A4inen?= <lassi.m.hamalainen@gmail.com> Date: Sun, 15 Nov 2015 00:16:34 +0200 Subject: [PATCH] C++: Fix crashes with the pattern "enum class operator A" Parser parsed the pattern as an enum declaration the name of which is a conversion operator. Add check to disallow keywords after enum-key (enum, enum class, enum struct). Add tests tst_AST::enumDeclaration and invalidEnumClassDeclaration. Task-number: QTCREATORBUG-15341 Change-Id: Ia037f00184c1d7e5b0374f39331bb6748f8d90b1 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> --- src/libs/3rdparty/cplusplus/Parser.cpp | 5 +++++ tests/auto/cplusplus/ast/tst_ast.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index 6fccebb0155..901f5ac2c1f 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -1789,6 +1789,11 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node) if (_languageFeatures.cxx11Enabled && (LA() == T_CLASS || LA() == T_STRUCT)) ast->key_token = consumeToken(); + + if (tok().isKeyword()) { + error(cursor(), "expected identifier before '%s'", tok().spell()); + return false; + } parseName(ast->name); if (_languageFeatures.cxx11Enabled && LA() == T_COLON) { diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp index a2219e7cfc6..aa42b2b3ec2 100644 --- a/tests/auto/cplusplus/ast/tst_ast.cpp +++ b/tests/auto/cplusplus/ast/tst_ast.cpp @@ -208,6 +208,8 @@ private slots: void expensiveExpression(); void invalidCode_data(); void invalidCode(); + void enumDeclaration(); + void invalidEnumClassDeclaration(); }; void tst_AST::gcc_attributes_1() @@ -1982,6 +1984,28 @@ void tst_AST::invalidCode() QVERIFY(diag.errorCount != 0); } +void tst_AST::enumDeclaration() +{ + QSharedPointer<TranslationUnit> unit(parseStatement( + //Unnamed + "enum { ENUMERATOR0 };\n" + "enum Enum { ENUMERATOR1 };\n" + "enum EnumWithBase : int { ENUMERATOR2 };\n" + "enum enum : int { ENUMERATOR2a };\n" + "enum class EnumClass { ENUMERATOR3 = 10 };\n", true)); + + QVERIFY(unit->ast()); + QCOMPARE(diag.errorCount, 0); +} + +void tst_AST::invalidEnumClassDeclaration() +{ + QSharedPointer<TranslationUnit> unit(parseStatement( + "enum class operator A { };", true)); + + QVERIFY(diag.errorCount != 0); +} + void tst_AST::initTestCase() { control.setDiagnosticClient(&diag); -- GitLab