aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaximilian Goldstein <max.goldstein@qt.io>2020-05-13 15:31:51 +0200
committerMaximilian Goldstein <max.goldstein@qt.io>2020-05-20 13:46:36 +0200
commit1c0c8509da2a27858f7b25ffa71d1b19690c708c (patch)
treef574288f0275755a5691697267e58044322753bf
parentdcc65ddf83fc4ccf1127dfc002c7951d6288e0d5 (diff)
Fix 'as' binary operation using invalid types
Fixes: QTBUG-81392 Change-Id: Ic83091c547a7854b7fa86b44d93c575bd7426bae Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--src/qml/parser/qqmljs.g12
-rw-r--r--src/qml/parser/qqmljsast.cpp6
-rw-r--r--src/qml/parser/qqmljsast_p.h21
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h1
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h6
-rw-r--r--tests/auto/shared/qqmljsastdumper.cpp6
-rw-r--r--tests/auto/shared/qqmljsastdumper.h3
-rw-r--r--tools/qmlformat/dumpastvisitor.cpp6
8 files changed, 56 insertions, 5 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 67f9cc7581..8d79e48287 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -1694,6 +1694,14 @@ TypeAnnotation: T_COLON Type;
} break;
./
+
+TypeExpression: Type;
+/.
+ case $rule_number: {
+ sym(1).Expression = new (pool) AST::TypeExpression(sym(1).Type);
+ } break;
+./
+
TypeAnnotationOpt: TypeAnnotation;
TypeAnnotationOpt: ;
/.
@@ -2664,9 +2672,9 @@ RelationalExpression_In: RelationalExpression_In T_IN ShiftExpression;
} break;
./
-TypeAssertExpression_In: RelationalExpression_In T_AS Type;
+TypeAssertExpression_In: RelationalExpression_In T_AS TypeExpression;
/. case $rule_number: Q_FALLTHROUGH(); ./
-TypeAssertExpression: RelationalExpression T_AS Type;
+TypeAssertExpression: RelationalExpression T_AS TypeExpression;
/.
case $rule_number: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::As, sym(3).Expression);
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 2a34c5a66c..f1f6102297 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -157,6 +157,12 @@ BinaryExpression *BinaryExpression::binaryExpressionCast()
return this;
}
+void TypeExpression::accept0(BaseVisitor *visitor)
+{
+ visitor->visit(this);
+ visitor->endVisit(this);
+}
+
Statement *Statement::statementCast()
{
return this;
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 8c1d8a2510..700643e1df 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -217,6 +217,7 @@ public:
Kind_SwitchStatement,
Kind_TemplateLiteral,
Kind_TaggedTemplate,
+ Kind_TypeExpression,
Kind_ThisExpression,
Kind_ThrowStatement,
Kind_TildeExpression,
@@ -504,6 +505,26 @@ public:
SourceLocation rparenToken;
};
+
+class QML_PARSER_EXPORT TypeExpression : public ExpressionNode
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(TypeExpression)
+ TypeExpression(Type *t) : m_type(t) { kind = K; }
+
+ void accept0(BaseVisitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override {
+ return m_type->firstSourceLocation();
+ }
+
+ SourceLocation lastSourceLocation() const override {
+ return m_type->lastSourceLocation();
+ }
+
+ Type *m_type;
+};
+
class QML_PARSER_EXPORT ThisExpression: public LeftHandSideExpression
{
public:
diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h
index ef37e8072f..c3a9b5aa83 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -65,6 +65,7 @@ class Visitor;
class Node;
class ExpressionNode;
class Statement;
+class TypeExpression;
class ThisExpression;
class IdentifierExpression;
class NullExpression;
diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h
index 8fbdb97ee2..1e4c78c0d4 100644
--- a/src/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/parser/qqmljsastvisitor_p.h
@@ -141,6 +141,9 @@ public:
virtual void endVisit(UiRequired *) = 0;
// QQmlJS
+ virtual bool visit(TypeExpression *) = 0;
+ virtual void endVisit(TypeExpression *) = 0;
+
virtual bool visit(ThisExpression *) = 0;
virtual void endVisit(ThisExpression *) = 0;
@@ -482,6 +485,9 @@ public:
void endVisit(UiRequired *) override {}
// QQmlJS
+ bool visit(TypeExpression *) override { return true; }
+ void endVisit(TypeExpression *) override {}
+
bool visit(ThisExpression *) override { return true; }
void endVisit(ThisExpression *) override {}
diff --git a/tests/auto/shared/qqmljsastdumper.cpp b/tests/auto/shared/qqmljsastdumper.cpp
index 1292be8d5b..34c31a294c 100644
--- a/tests/auto/shared/qqmljsastdumper.cpp
+++ b/tests/auto/shared/qqmljsastdumper.cpp
@@ -421,6 +421,12 @@ void AstDumper::endVisit(UiAnnotation *) { stop("UiAnnotation"); }
void AstDumper::endVisit(UiAnnotationList *) { stop("UiAnnotationList"); }
// QQmlJS
+bool AstDumper::visit(AST::TypeExpression *el) {
+ start("TypeExpression");
+ return true;
+}
+void AstDumper::endVisit(AST::TypeExpression *) { stop("TypeExpression"); }
+
bool AstDumper::visit(AST::ThisExpression *el) {
start(QLatin1String("ThisExpression thisToken=%1")
.arg(loc(el->thisToken)));
diff --git a/tests/auto/shared/qqmljsastdumper.h b/tests/auto/shared/qqmljsastdumper.h
index 5e46e516f0..4abaea7fba 100644
--- a/tests/auto/shared/qqmljsastdumper.h
+++ b/tests/auto/shared/qqmljsastdumper.h
@@ -146,6 +146,9 @@ public:
void endVisit(AST::UiAnnotationList *) override;
// QQmlJS
+ bool visit(AST::TypeExpression *) override;
+ void endVisit(AST::TypeExpression *) override;
+
bool visit(AST::ThisExpression *) override;
void endVisit(AST::ThisExpression *) override;
diff --git a/tools/qmlformat/dumpastvisitor.cpp b/tools/qmlformat/dumpastvisitor.cpp
index e0feff4e51..07887df99a 100644
--- a/tools/qmlformat/dumpastvisitor.cpp
+++ b/tools/qmlformat/dumpastvisitor.cpp
@@ -490,9 +490,9 @@ QString DumpAstVisitor::parseExpression(ExpressionNode *expression)
auto* expr = cast<Expression*>(expression);
return parseExpression(expr->left)+", "+parseExpression(expr->right);
}
- case Node::Kind_Type: {
- auto* type = reinterpret_cast<Type*>(expression);
- return parseType(type);
+ case Node::Kind_TypeExpression: {
+ auto* type = cast<TypeExpression*>(expression);
+ return parseType(type->m_type);
}
case Node::Kind_RegExpLiteral: {
auto* regexpLiteral = cast<RegExpLiteral*>(expression);