From e9b3cd548cd3e9f872344f518c01387dc6af814b Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 11 Aug 2023 17:48:47 +0200 Subject: [PATCH] CPlusPlus: Fix crash on weird-looking construct This was misparsed as a function with an initializer (e.g. "= default"), and then the empty id caused trouble later on. Fixes: QTCREATORBUG-29386 Change-Id: I85a35db544e11ad85f50e3a15b1a071b36e79cd0 Reviewed-by: Qt CI Bot Reviewed-by: David Schulz Reviewed-by: --- src/libs/3rdparty/cplusplus/Parser.cpp | 5 +++++ tests/auto/cplusplus/ast/tst_ast.cpp | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index 6bf19f59829..395556777dd 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -3020,6 +3020,11 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp if (!_languageFeatures.cxx11Enabled || LA(2) == T_NUMERIC_LITERAL) { parseInitializer(node->initializer, &node->equal_token); } else { + if (LA(2) != T_NUMERIC_LITERAL && LA(2) != T_DEFAULT && LA(2) != T_DELETE) { + error(cursor(), "expected 'default', 'delete' or '0', got '%s'", tok(2).spell()); + return false; + } + node->equal_token = consumeToken(); IdExpressionAST *id_expr = new (_pool) IdExpressionAST; diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp index fc1ab3538e8..5790cb090ac 100644 --- a/tests/auto/cplusplus/ast/tst_ast.cpp +++ b/tests/auto/cplusplus/ast/tst_ast.cpp @@ -190,6 +190,7 @@ private slots: void enumDeclaration(); void invalidEnumClassDeclaration(); void invalidEnumWithDestructorId(); + void invalidFunctionInitializer(); }; void tst_AST::gcc_attributes_1() @@ -2052,6 +2053,14 @@ void tst_AST::invalidEnumWithDestructorId() QVERIFY(diag.errorCount != 0); } +void tst_AST::invalidFunctionInitializer() +{ + QSharedPointer unit(parse( + "int main() { a t=b; c d(e)=\"\"; }", TranslationUnit::ParseTranlationUnit, false, false, true)); + + QVERIFY(diag.errorCount != 0); +} + void tst_AST::initTestCase() { control.setDiagnosticClient(&diag);