aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/cplusplus
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2022-08-24 16:23:33 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2022-08-25 08:09:23 +0000
commitfa13f48c2b37f91690ba12e8f1b3162db7c3cb5c (patch)
tree4f5215123738e46c2f66c32b024db0615da2657b /src/libs/3rdparty/cplusplus
parent3172bba63c1234497fed360ba52d1c2588fc2132 (diff)
CPlusPlus: Fix mis-parsing array-related constructs
... as structured bindings. Also add a safety check to Bind that might be needed for invalid code. Amends ca00b874a7. Change-Id: I7b174b80ad97ed7424f1e369b876c99acf7e95d2 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src/libs/3rdparty/cplusplus')
-rw-r--r--src/libs/3rdparty/cplusplus/Bind.cpp3
-rw-r--r--src/libs/3rdparty/cplusplus/Parser.cpp43
-rw-r--r--src/libs/3rdparty/cplusplus/Parser.h4
3 files changed, 30 insertions, 20 deletions
diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp
index 2f3f465c8e..64af5b893a 100644
--- a/src/libs/3rdparty/cplusplus/Bind.cpp
+++ b/src/libs/3rdparty/cplusplus/Bind.cpp
@@ -3343,7 +3343,8 @@ bool Bind::visit(DecompositionDeclaratorAST *ast)
{
for (auto it = ast->identifiers->begin(); it != ast->identifiers->end(); ++it)
name(*it);
- *_decompositionDeclarator = ast;
+ if (_decompositionDeclarator)
+ *_decompositionDeclarator = ast;
return false;
}
diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp
index 9938fa9dde..024573b918 100644
--- a/src/libs/3rdparty/cplusplus/Parser.cpp
+++ b/src/libs/3rdparty/cplusplus/Parser.cpp
@@ -1618,7 +1618,7 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp
node = ast;
return true;
}
- } else if (const auto decl = parseDecompositionDeclarator()) {
+ } else if (const auto decl = parseDecompositionDeclarator(decl_specifier_list)) {
DeclaratorAST *ast = new (_pool) DeclaratorAST;
ast->attribute_list = attributes;
ast->ptr_operator_list = ptr_operators;
@@ -1630,19 +1630,21 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp
return false;
}
-DecompositionDeclaratorAST *Parser::parseDecompositionDeclarator()
+DecompositionDeclaratorAST *Parser::parseDecompositionDeclarator(
+ SpecifierListAST *decl_specifier_list)
{
- if (LA() != T_LBRACKET)
+ if (!_languageFeatures.cxx11Enabled || LA() != T_LBRACKET || !hasAuto(decl_specifier_list))
return nullptr;
consumeToken();
const auto decl = new (_pool) DecompositionDeclaratorAST;
for (NameListAST **iter = &decl->identifiers; ; iter = &(*iter)->next) {
- NameAST *name_ast = nullptr;
- if (!parseName(name_ast)) {
+ if (LA() != T_IDENTIFIER) {
error(cursor(), "expected an identifier");
return nullptr;
}
+ SimpleNameAST * const name_ast = new (_pool) SimpleNameAST;
+ name_ast->identifier_token = consumeToken();
*iter = new (_pool) NameListAST;
(*iter)->value = name_ast;
@@ -1681,6 +1683,18 @@ static bool maybeCppInitializer(DeclaratorAST *declarator)
return true;
}
+bool Parser::hasAuto(SpecifierListAST *decl_specifier_list) const
+{
+ for (SpecifierListAST *iter = decl_specifier_list; iter; iter = iter->next) {
+ SpecifierAST *spec = iter->value;
+ if (SimpleSpecifierAST *simpleSpec = spec->asSimpleSpecifier()) {
+ if (_translationUnit->tokenKind(simpleSpec->specifier_token) == T_AUTO)
+ return true;
+ }
+ }
+ return false;
+}
+
bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *declaringClass)
{
DEBUG_THIS_RULE();
@@ -1753,19 +1767,9 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif
parseRefQualifier(ast->ref_qualifier_token);
parseExceptionSpecification(ast->exception_specification);
- if (_languageFeatures.cxx11Enabled && ! node->ptr_operator_list && LA() == T_ARROW) {
- // only allow if there is 1 type spec, which has to be 'auto'
- bool hasAuto = false;
- for (SpecifierListAST *iter = decl_specifier_list; !hasAuto && iter; iter = iter->next) {
- SpecifierAST *spec = iter->value;
- if (SimpleSpecifierAST *simpleSpec = spec->asSimpleSpecifier()) {
- if (_translationUnit->tokenKind(simpleSpec->specifier_token) == T_AUTO)
- hasAuto = true;
- }
- }
-
- if (hasAuto)
- parseTrailingReturnType(ast->trailing_return_type);
+ if (_languageFeatures.cxx11Enabled && ! node->ptr_operator_list && LA() == T_ARROW
+ && hasAuto(decl_specifier_list)) {
+ parseTrailingReturnType(ast->trailing_return_type);
}
parseOverrideFinalQualifiers(ast->cv_qualifier_list);
@@ -2809,6 +2813,9 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_sp
}
} else if (node->core_declarator && (LA() == T_EQUAL || (_languageFeatures.cxx11Enabled && !isFunctionDeclarator && LA() == T_LBRACE) || (! declaringClass && LA() == T_LPAREN))) {
parseInitializer(node->initializer, &node->equal_token);
+ } else if (node->core_declarator && node->core_declarator->asDecompositionDeclarator()) {
+ error(cursor(), "structured binding needs initializer");
+ return false;
}
return true;
}
diff --git a/src/libs/3rdparty/cplusplus/Parser.h b/src/libs/3rdparty/cplusplus/Parser.h
index 3a3b00fdf6..499a854490 100644
--- a/src/libs/3rdparty/cplusplus/Parser.h
+++ b/src/libs/3rdparty/cplusplus/Parser.h
@@ -79,7 +79,7 @@ public:
bool parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *declaringClass = nullptr);
bool parseDeclarationStatement(StatementAST *&node);
bool parseCoreDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *declaringClass);
- DecompositionDeclaratorAST *parseDecompositionDeclarator();
+ DecompositionDeclaratorAST *parseDecompositionDeclarator(SpecifierListAST *decl_specifier_list);
bool parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *declaringClass = nullptr);
bool parseDeleteExpression(ExpressionAST *&node);
bool parseDoStatement(StatementAST *&node);
@@ -317,6 +317,8 @@ public:
void clearTemplateArgumentList() { _templateArgumentList.clear(); }
private:
+ bool hasAuto(SpecifierListAST *decl_specifier_list) const;
+
TranslationUnit *_translationUnit;
Control *_control;
MemoryPool *_pool;