CPlusPlus: Allow empty argument list in member initialization

Fixes: QTCREATORBUG-30797
Change-Id: I6de0f05e071a5e73317d7a8e3d035e23e23a41aa
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2024-08-07 13:14:02 +02:00
parent 61931fd709
commit dceabc0e0a
3 changed files with 19 additions and 11 deletions

View File

@@ -20,7 +20,6 @@
#include "Parser.h"
#include "Token.h"
#include "Lexer.h"
#include "Control.h"
#include "AST.h"
#include "Literals.h"
@@ -30,7 +29,6 @@
#include <unordered_map>
#include <utility>
#include <string>
#include <cstdio> // for putchar
#if defined(__INTEL_COMPILER) && !defined(va_copy)
@@ -3088,7 +3086,7 @@ bool Parser::parseInitializer0x(ExpressionAST *&node, int *equals_token)
}
else if (LA() == T_LPAREN) {
return parseExpressionListParen(node);
return parseExpressionListParen(node, false);
}
return false;
@@ -3258,7 +3256,7 @@ bool Parser::parseMemInitializer(MemInitializerListAST *&node)
ast->name = name;
if (LA() == T_LPAREN) {
parseExpressionListParen(ast->expression);
parseExpressionListParen(ast->expression, true);
} else if (_languageFeatures.cxx11Enabled && LA() == T_LBRACE) {
parseBracedInitList0x(ast->expression);
} else {
@@ -5452,7 +5450,7 @@ bool Parser::parseTypenameCallExpression(ExpressionAST *&node)
ast->typename_token = typename_token;
ast->name = name;
if (LA() == T_LPAREN) {
parseExpressionListParen(ast->expression);
parseExpressionListParen(ast->expression, false);
} else { // T_LBRACE
parseBracedInitList0x(ast->expression);
}
@@ -5511,7 +5509,7 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node)
(LA() == T_LPAREN || (_languageFeatures.cxx11Enabled && LA() == T_LBRACE))) {
ExpressionAST *expr = nullptr;
if (LA() == T_LPAREN) {
parseExpressionListParen(expr);
parseExpressionListParen(expr, false);
} else { // T_LBRACE
parseBracedInitList0x(expr);
}
@@ -5707,13 +5705,14 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
}
// new-placement ::= T_LPAREN expression-list T_RPAREN
bool Parser::parseExpressionListParen(ExpressionAST *&node)
bool Parser::parseExpressionListParen(ExpressionAST *&node, bool allowEmpty)
{
DEBUG_THIS_RULE();
if (LA() == T_LPAREN) {
int lparen_token = consumeToken();
ExpressionListAST *expression_list = nullptr;
if (parseExpressionList(expression_list) && LA() == T_RPAREN) {
const bool hasList = parseExpressionList(expression_list);
if ((hasList || allowEmpty) && LA() == T_RPAREN) {
int rparen_token = consumeToken();
ExpressionListParenAST *ast = new (_pool) ExpressionListParenAST;
ast->lparen_token = lparen_token;
@@ -5746,7 +5745,7 @@ bool Parser::parseNewExpression(ExpressionAST *&node)
ExpressionAST *parenExpressionList = nullptr;
if (parseExpressionListParen(parenExpressionList)) {
if (parseExpressionListParen(parenExpressionList, false)) {
int after_new_placement = cursor();
NewTypeIdAST *new_type_id = nullptr;
@@ -5839,7 +5838,7 @@ bool Parser::parseNewInitializer(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_LPAREN)
return parseExpressionListParen(node);
return parseExpressionListParen(node, false);
else if (_languageFeatures.cxx11Enabled && LA() == T_LBRACE)
return parseBracedInitList0x(node);
return false;

View File

@@ -117,7 +117,7 @@ public:
bool parseNamespaceAliasDefinition(DeclarationAST *&node);
bool parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node);
bool parseNewExpression(ExpressionAST *&node);
bool parseExpressionListParen(ExpressionAST *&node);
bool parseExpressionListParen(ExpressionAST *&node, bool allowEmpty);
bool parseNewInitializer(ExpressionAST *&node);
bool parseNewTypeId(NewTypeIdAST *&node);
bool parseOperator(OperatorAST *&node);

View File

@@ -112,6 +112,7 @@ private slots:
void templated_dtor_3();
void templated_dtor_4();
void templated_dtor_5();
void emptyMemberInitialization();
// possible declaration-or-expression statements
void call_call_1();
@@ -2061,6 +2062,14 @@ void tst_AST::invalidFunctionInitializer()
QVERIFY(diag.errorCount != 0);
}
void tst_AST::emptyMemberInitialization()
{
const std::shared_ptr<TranslationUnit> unit(parse(
"struct S\n{\n S(): i() {}\n int i;};", TranslationUnit::ParseTranlationUnit));
QVERIFY(unit->ast());
QCOMPARE(diag.errorCount, 0);
}
void tst_AST::initTestCase()
{
control.setDiagnosticClient(&diag);