From 74e75e41fe12f19e5365a3152ffafa1a29376240 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 19 Sep 2026 23:52:00 +0200 Subject: Reject exporting symbols with the same name from 2 modules --- boot/dependency.cc | 20 ++++++++++++++++++-- boot/symbol.cc | 20 ++++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'boot') diff --git a/boot/dependency.cc b/boot/dependency.cc index 1eb5953..5053a36 100644 --- a/boot/dependency.cc +++ b/boot/dependency.cc @@ -72,7 +72,7 @@ namespace elna::boot } analysis_result analyze_semantics(std::unique_ptr& tree, - const std::vector>& imports, + const std::vector& imports, const std::shared_ptr& globals, const target_info& target, const std::filesystem::path& module_path) { @@ -90,7 +90,23 @@ namespace elna::boot } for (const auto& import : imports) { - result.value.add_import(import); + const std::vector collisions = result.value.add_import(import.symbols); + + for (const import_collision& collision : collisions) + { + symbol_declaration_error::redefinition original_definition{ + .original = collision.original->position, + .file = collision.original->file + }; + auto error = std::make_unique(import.position, + collision.name, original_definition); + + result.errors.push_back(std::move(error)); + } + } + if (!result.errors.empty()) + { + return result; } declaration_visitor declarations(result.value, target, module_path); tree->accept(&declarations); diff --git a/boot/symbol.cc b/boot/symbol.cc index 58524ad..962808a 100644 --- a/boot/symbol.cc +++ b/boot/symbol.cc @@ -17,6 +17,7 @@ along with GCC; see the file COPYING3. If not see #include "elna/boot/symbol.h" +#include #include #include #include @@ -511,9 +512,24 @@ namespace elna::boot return this->unresolved.insert({ symbol_name, std::move(forward_declaration) }).second; } - void symbol_bag::add_import(const std::shared_ptr& symbols) + std::vector symbol_bag::add_import(const std::shared_ptr& symbols) { - this->imports.push_front(symbols); + std::vector collisions; + + for (const auto& [name, imported] : *symbols) + { + std::shared_ptr original = lookup_import(name); + + // The same module imported twice hands out the same symbol, which + // doesn't conflict with itself. + if (original != nullptr && original != imported) + { + collisions.push_back({ .name = name, .original = std::move(original) }); + } + } + this->imports.push_back(symbols); + + return collisions; } bool symbol_bag::is_global() const -- cgit v1.2.3