From a2f49306d97304efaddd129308333d9bf3aa36c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Th=C3=A9venoux?= Date: Mon, 18 Sep 2023 11:25:44 +0200 Subject: [PATCH] Qualified expressions as code statements A qualified expression that appears as a statement denotes a machine code insertion, in GNAT, it is parsed as a parameterless procedure call. In that case, explicitly bind the type variable to none. --- ada/ast.py | 16 +++++++++- .../name_resolution/qual_expr_stmt/test.adb | 11 +++++++ .../name_resolution/qual_expr_stmt/test.out | 32 +++++++++++++++++++ .../name_resolution/qual_expr_stmt/test.yaml | 2 ++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 testsuite/tests/name_resolution/qual_expr_stmt/test.adb create mode 100644 testsuite/tests/name_resolution/qual_expr_stmt/test.out create mode 100644 testsuite/tests/name_resolution/qual_expr_stmt/test.yaml diff --git a/ada/ast.py b/ada/ast.py index b5632da05..3d77e768f 100644 --- a/ada/ast.py +++ b/ada/ast.py @@ -19286,7 +19286,21 @@ def xref_equation(): & Bind(Self.prefix.ref_var, typ) & Bind(Self.suffix.expected_type_var, typ) & Entity.suffix.matches_expected_type - & Bind(Self.type_var, typ) + & Bind( + Self.type_var, + If( + # A qualified expression that appears as a statement + # denotes a machine code insertion, in GNAT, it is parsed + # as a parameterless procedure call. In that case, + # Self.type_var shouldn't denote any type. Note that we are + # more flexible than Ada since we allow any type to be code + # statements whereas Ada restricts that to types defined in + # package `System.Machine_Code` (see :rmlink:`13.8`). + Entity.parent.is_a(T.CallStmt), + No(AdaNode.entity), + typ + ) + ) ) # TODO: once we manage to turn prefix into a subtype indication, remove diff --git a/testsuite/tests/name_resolution/qual_expr_stmt/test.adb b/testsuite/tests/name_resolution/qual_expr_stmt/test.adb new file mode 100644 index 000000000..a95c38a3e --- /dev/null +++ b/testsuite/tests/name_resolution/qual_expr_stmt/test.adb @@ -0,0 +1,11 @@ +with Machine_Code; use Machine_Code; + +procedure Test is + procedure Code is + begin + Asm_Insn'(Asm ("nop")); + pragma Test_Statement; + end Code; +begin + Code; +end Test; diff --git a/testsuite/tests/name_resolution/qual_expr_stmt/test.out b/testsuite/tests/name_resolution/qual_expr_stmt/test.out new file mode 100644 index 000000000..b9e15d414 --- /dev/null +++ b/testsuite/tests/name_resolution/qual_expr_stmt/test.out @@ -0,0 +1,32 @@ +Analyzing test.adb +################## + +Resolving xrefs for node +***************************************************** + +Expr: + references: + type: None + expected type: None +Expr: + references: + type: None + expected type: None +Expr: + type: + expected type: +Expr: + references: + type: + expected type: +Expr: + references: + type: + expected type: None +Expr: + references: None + type: + expected type: + + +Done. diff --git a/testsuite/tests/name_resolution/qual_expr_stmt/test.yaml b/testsuite/tests/name_resolution/qual_expr_stmt/test.yaml new file mode 100644 index 000000000..173e325ff --- /dev/null +++ b/testsuite/tests/name_resolution/qual_expr_stmt/test.yaml @@ -0,0 +1,2 @@ +driver: name-resolution +input_sources: [test.adb]