diff --git a/clients/vscode-hlasmplugin/CHANGELOG.md b/clients/vscode-hlasmplugin/CHANGELOG.md
index 41871802c..4ebe75df4 100644
--- a/clients/vscode-hlasmplugin/CHANGELOG.md
+++ b/clients/vscode-hlasmplugin/CHANGELOG.md
@@ -27,6 +27,7 @@
- Library diagnostics point to a respective configuration file
- Invalid substring may be generated when conditional assembly string contains multibyte UTF-8 characters
- Utilize alignment information during dependency evaluation
+- Incorrect evaluation of the T attribute in EQU statement
## [1.4.0](https://github.com/eclipse/che-che4z-lsp-for-hlasm/compare/1.3.0...1.4.0) (2022-08-30)
diff --git a/parser_library/src/context/ordinary_assembly/CMakeLists.txt b/parser_library/src/context/ordinary_assembly/CMakeLists.txt
index 0cc555c43..27bd794c0 100644
--- a/parser_library/src/context/ordinary_assembly/CMakeLists.txt
+++ b/parser_library/src/context/ordinary_assembly/CMakeLists.txt
@@ -21,6 +21,8 @@ target_sources(parser_library PRIVATE
dependant.h
dependency_collector.cpp
dependency_collector.h
+ dependency_solver_redirect.cpp
+ dependency_solver_redirect.h
location_counter.cpp
location_counter.h
location_counter_data.cpp
diff --git a/parser_library/src/context/ordinary_assembly/dependency_solver_redirect.cpp b/parser_library/src/context/ordinary_assembly/dependency_solver_redirect.cpp
new file mode 100644
index 000000000..3f6f93480
--- /dev/null
+++ b/parser_library/src/context/ordinary_assembly/dependency_solver_redirect.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2022 Broadcom.
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Broadcom, Inc. - initial API and implementation
+ */
+
+#include "dependency_solver_redirect.h"
+
+#include "context/using.h"
+
+namespace hlasm_plugin::parser_library::context {
+
+const symbol* dependency_solver_redirect::get_symbol(id_index name) const { return m_base->get_symbol(name); }
+
+std::optional
dependency_solver_redirect::get_loctr() const { return m_base->get_loctr(); }
+
+id_index dependency_solver_redirect::get_literal_id(const std::shared_ptr& lit)
+{
+ return m_base->get_literal_id(lit);
+}
+
+bool dependency_solver_redirect::using_active(id_index label, const section* sect) const
+{
+ return m_base->using_active(label, sect);
+}
+
+using_evaluate_result dependency_solver_redirect::using_evaluate(
+ id_index label, const section* owner, int32_t offset, bool long_offset) const
+{
+ return m_base->using_evaluate(label, owner, offset, long_offset);
+}
+
+std::variant dependency_solver_redirect::get_symbol_candidate(id_index name) const
+{
+ return m_base->get_symbol_candidate(name);
+}
+
+std::string dependency_solver_redirect::get_opcode_attr(id_index symbol) const
+{
+ return m_base->get_opcode_attr(symbol);
+}
+
+} // namespace hlasm_plugin::parser_library::context
diff --git a/parser_library/src/context/ordinary_assembly/dependency_solver_redirect.h b/parser_library/src/context/ordinary_assembly/dependency_solver_redirect.h
new file mode 100644
index 000000000..14687cd74
--- /dev/null
+++ b/parser_library/src/context/ordinary_assembly/dependency_solver_redirect.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2022 Broadcom.
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Broadcom, Inc. - initial API and implementation
+ */
+
+#ifndef HLASMPLUGIN_PARSERLIBRARY_CONTEXT_DEPENDENCY_SOLVER_REDIRECT_H
+#define HLASMPLUGIN_PARSERLIBRARY_CONTEXT_DEPENDENCY_SOLVER_REDIRECT_H
+
+#include "dependable.h"
+
+namespace hlasm_plugin::parser_library::context {
+
+class dependency_solver_redirect : public dependency_solver
+{
+ dependency_solver* m_base;
+
+public:
+ const symbol* get_symbol(id_index name) const override;
+ std::optional get_loctr() const override;
+ id_index get_literal_id(const std::shared_ptr& lit) override;
+ bool using_active(id_index label, const section* sect) const override;
+ using_evaluate_result using_evaluate(
+ id_index label, const section* owner, int32_t offset, bool long_offset) const override;
+ std::variant get_symbol_candidate(id_index name) const override;
+ std::string get_opcode_attr(id_index symbol) const override;
+
+protected:
+ explicit dependency_solver_redirect(dependency_solver& base)
+ : m_base(&base)
+ {}
+
+ ~dependency_solver_redirect() = default;
+};
+
+} // namespace hlasm_plugin::parser_library::context
+
+#endif
diff --git a/parser_library/src/processing/instruction_sets/asm_processor.cpp b/parser_library/src/processing/instruction_sets/asm_processor.cpp
index 25607c91a..079ca01e2 100644
--- a/parser_library/src/processing/instruction_sets/asm_processor.cpp
+++ b/parser_library/src/processing/instruction_sets/asm_processor.cpp
@@ -124,6 +124,23 @@ void asm_processor::process_LOCTR(rebuilt_statement stmt)
lib_info);
}
+struct override_symbol_candidates final : public context::dependency_solver_redirect
+{
+ std::variant get_symbol_candidate(
+ context::id_index name) const override
+ {
+ if (auto r = dependency_solver_redirect::get_symbol_candidate(name);
+ std::holds_alternative(r) && std::get(r) == nullptr)
+ return context::symbol_candidate { false };
+ else
+ return r;
+ }
+
+ explicit override_symbol_candidates(context::dependency_solver& solver)
+ : dependency_solver_redirect(solver)
+ {}
+};
+
void asm_processor::process_EQU(rebuilt_statement stmt)
{
auto loctr = hlasm_ctx.ord_ctx.align(context::no_align, lib_info);
@@ -159,9 +176,10 @@ void asm_processor::process_EQU(rebuilt_statement stmt)
auto asm_op = ops[2]->access_asm();
auto expr_op = asm_op->access_expr();
- if (expr_op && !expr_op->has_dependencies(dep_solver, nullptr))
+ override_symbol_candidates dep_solver_override(dep_solver);
+ if (expr_op && !expr_op->has_dependencies(dep_solver_override, nullptr))
{
- auto t_value = expr_op->expression->evaluate(dep_solver, *this);
+ auto t_value = expr_op->expression->evaluate(dep_solver_override, *this);
if (t_value.value_kind() == context::symbol_value_kind::ABS && t_value.get_abs() >= 0
&& t_value.get_abs() <= 255)
t_attr = (context::symbol_attributes::type_attr)t_value.get_abs();
@@ -179,9 +197,10 @@ void asm_processor::process_EQU(rebuilt_statement stmt)
auto asm_op = ops[1]->access_asm();
auto expr_op = asm_op->access_expr();
- if (expr_op && !expr_op->has_dependencies(dep_solver, nullptr))
+ override_symbol_candidates dep_solver_override(dep_solver);
+ if (expr_op && !expr_op->has_dependencies(dep_solver_override, nullptr))
{
- auto length_value = expr_op->expression->evaluate(dep_solver, *this);
+ auto length_value = expr_op->expression->evaluate(dep_solver_override, *this);
if (length_value.value_kind() == context::symbol_value_kind::ABS && length_value.get_abs() >= 0
&& length_value.get_abs() <= 65535)
length_attr = (context::symbol_attributes::len_attr)length_value.get_abs();
diff --git a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp
index 82a42aa37..162a010f1 100644
--- a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp
+++ b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.cpp
@@ -104,47 +104,14 @@ template class data_def_postponed_statement;
template class data_def_dependency;
template class data_def_dependency;
-const context::symbol* data_def_dependency_solver::get_symbol(context::id_index name) const
-{
- return base.get_symbol(name);
-}
-
std::optional data_def_dependency_solver::get_loctr() const
{
if (loctr)
return *loctr + (int)(operands_bit_length / 8);
- if (auto l = base.get_loctr(); l.has_value())
+ if (auto l = dependency_solver_redirect::get_loctr(); l.has_value())
return l.value() + (int)(operands_bit_length / 8);
return std::nullopt;
}
-context::id_index data_def_dependency_solver::get_literal_id(
- const std::shared_ptr& dd)
-{
- return base.get_literal_id(dd);
-}
-
-bool data_def_dependency_solver::using_active(context::id_index label, const context::section* sect) const
-{
- return base.using_active(label, sect);
-}
-
-context::using_evaluate_result data_def_dependency_solver::using_evaluate(
- context::id_index label, const context::section* owner, int32_t offset, bool long_offset) const
-{
- return base.using_evaluate(label, owner, offset, long_offset);
-}
-
-std::variant data_def_dependency_solver::get_symbol_candidate(
- context::id_index name) const
-{
- return base.get_symbol_candidate(name);
-}
-
-std::string data_def_dependency_solver::get_opcode_attr(context::id_index name) const
-{
- return base.get_opcode_attr(name);
-}
-
} // namespace hlasm_plugin::parser_library::processing
diff --git a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.h b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.h
index 15b0e557b..de933c67f 100644
--- a/parser_library/src/processing/instruction_sets/data_def_postponed_statement.h
+++ b/parser_library/src/processing/instruction_sets/data_def_postponed_statement.h
@@ -17,6 +17,7 @@
#include "checking/data_definition/data_def_type_base.h"
#include "context/ordinary_assembly/dependable.h"
+#include "context/ordinary_assembly/dependency_solver_redirect.h"
#include "postponed_statement_impl.h"
namespace hlasm_plugin::parser_library::processing {
@@ -60,26 +61,16 @@ class data_def_postponed_statement final : public postponed_statement_impl
const std::vector>& get_dependencies() const { return m_dependencies; }
};
-struct data_def_dependency_solver final : public context::dependency_solver
+struct data_def_dependency_solver final : public context::dependency_solver_redirect
{
data_def_dependency_solver(context::dependency_solver& base, const context::address* loctr)
- : base(base)
+ : dependency_solver_redirect(base)
, loctr(loctr)
{}
- context::dependency_solver& base;
const context::address* loctr;
uint64_t operands_bit_length = 0;
-
- const context::symbol* get_symbol(context::id_index name) const override;
std::optional get_loctr() const override;
- context::id_index get_literal_id(const std::shared_ptr& dd) override;
- bool using_active(context::id_index label, const context::section* sect) const override;
- context::using_evaluate_result using_evaluate(
- context::id_index label, const context::section* owner, int32_t offset, bool long_offset) const override;
- std::variant get_symbol_candidate(
- context::id_index name) const override;
- std::string get_opcode_attr(context::id_index name) const override;
};
} // namespace hlasm_plugin::parser_library::processing
diff --git a/parser_library/test/processing/equ_test.cpp b/parser_library/test/processing/equ_test.cpp
index f28d89e08..f5d3b6adf 100644
--- a/parser_library/test/processing/equ_test.cpp
+++ b/parser_library/test/processing/equ_test.cpp
@@ -254,3 +254,21 @@ A EQU ,0
EXPECT_TRUE(matches_message_codes(a.diags(), { "A132" }));
}
+
+TEST(EQU, t_attr_non_existing_symbol)
+{
+ std::string input = R"(
+A DS A
+B EQU A,*-A,T'TYPO
+)";
+
+ analyzer a(input);
+ a.analyze();
+ a.collect_diags();
+
+ EXPECT_TRUE(a.diags().empty());
+ auto b = get_symbol(a.hlasm_ctx(), "B");
+ ASSERT_TRUE(b);
+
+ EXPECT_EQ(b->attributes().type(), ebcdic_encoding::a2e['U']);
+}