aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-17 17:57:40 +0200
committerEugen Wissner <belka@caraus.de>2026-07-17 17:57:40 +0200
commit349e84c693c1444606e877f4d8cdc1a39aa91634 (patch)
treecd382dbac860cf8e78b8725a1c9b6ce9bc1fcd32
parent4f260c5e98def6bd1b3498d4085de5080cca7641 (diff)
downloadelna-349e84c693c1444606e877f4d8cdc1a39aa91634.tar.gz
Reject const in const nesting
-rw-r--r--boot/name_analysis.cc15
-rw-r--r--include/elna/boot/name_analysis.h12
-rw-r--r--testsuite/compilable/const_alias.elna10
-rw-r--r--testsuite/fail_compilation/double_const.elna7
4 files changed, 44 insertions, 0 deletions
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index 48251cd..5255878 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -70,6 +70,16 @@ namespace elna::boot
return "const must be written before the array size, not after";
}
+ double_const_error::double_const_error(const source_position position)
+ : error(position)
+ {
+ }
+
+ std::string double_const_error::what() const
+ {
+ return "Duplicate 'const' qualifier is not allowed";
+ }
+
// Members of a constant aggregate are constant themselves.
static type qualify_member_type(const type& element, const type& aggregate)
{
@@ -179,6 +189,11 @@ namespace elna::boot
void name_analysis_visitor::visit(constant_type_expression *expression)
{
walking_visitor::visit(expression);
+
+ if (this->current_type.get<constant_type>() != nullptr)
+ {
+ add_error<double_const_error>(expression->position());
+ }
this->current_type = type(std::make_shared<constant_type>(this->current_type));
}
diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h
index feef3bf..40bdf16 100644
--- a/include/elna/boot/name_analysis.h
+++ b/include/elna/boot/name_analysis.h
@@ -81,6 +81,18 @@ namespace elna::boot
};
/**
+ * Direct \c const \c const T is not valid — write it once.
+ * Merging through an alias is fine (C++ rule).
+ */
+ class double_const_error : public error
+ {
+ public:
+ explicit double_const_error(const source_position position);
+
+ std::string what() const override;
+ };
+
+ /**
* Origin of a field in a composite type.
*/
struct field_origin
diff --git a/testsuite/compilable/const_alias.elna b/testsuite/compilable/const_alias.elna
new file mode 100644
index 0000000..9cb9ffb
--- /dev/null
+++ b/testsuite/compilable/const_alias.elna
@@ -0,0 +1,10 @@
+type
+ CI = const Int
+ CCI = const CI
+
+var
+ x: CCI
+ y: const CI
+
+begin
+end.
diff --git a/testsuite/fail_compilation/double_const.elna b/testsuite/fail_compilation/double_const.elna
new file mode 100644
index 0000000..204a7f7
--- /dev/null
+++ b/testsuite/fail_compilation/double_const.elna
@@ -0,0 +1,7 @@
+proc f()
+var
+ x: const const Int (* @Error Duplicate 'const' qualifier is not allowed *)
+begin
+return
+
+end.