From e75ad281fcccc71013a6287edb3190c3c27be11a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 22 Jan 2022 11:30:48 +0100 Subject: [PATCH] Elaborate enums in the order they have been declared enums for a scope are stored in a std::set. This means when iterating over the enums during elaboration it is possible that they are elaborated in a different order than they have been declared in. This causes problems if one enum references items of the other enum. E.g. ``` enum { A } a; enum { B = A } b; ``` In the current implementation whether this works or not depends on the pointer values of the enum_type_t for `a` and `b`, which can change between environments. To make sure that enums are elaborated in the same order use a std::vector instead of a std::set. Signed-off-by: Lars-Peter Clausen --- PExpr.cc | 2 +- PScope.h | 2 +- elab_scope.cc | 4 ++-- pform.cc | 8 +++++--- pform_dump.cc | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/PExpr.cc b/PExpr.cc index e60a3fbba..842bdc311 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -390,7 +390,7 @@ PEIdent::~PEIdent() static bool find_enum_constant(LexicalScope*scope, perm_string name) { - for (set::const_iterator cur = scope->enum_sets.begin() ; + for (vector::const_iterator cur = scope->enum_sets.begin() ; cur != scope->enum_sets.end() ; ++ cur) { for (list::const_iterator idx = (*cur)->names->begin() ; idx != (*cur)->names->end() ; ++ idx) { diff --git a/PScope.h b/PScope.h index e500a7e02..fd573350e 100644 --- a/PScope.h +++ b/PScope.h @@ -139,7 +139,7 @@ class LexicalScope { std::list elab_tasks; // Enumeration sets. - std::set enum_sets; + std::vector enum_sets; // A count of the generate constructs in this scope. This is // used to automatically name unnamed generate blocks, as diff --git a/elab_scope.cc b/elab_scope.cc index b145bb887..244e1bed1 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -393,7 +393,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope, } static void elaborate_scope_enumerations(Design*des, NetScope*scope, - const set&enum_types) + const vector&enum_types) { if (debug_scopes) { cerr << scope->get_fileline() << ": " << __func__ << ": " @@ -402,7 +402,7 @@ static void elaborate_scope_enumerations(Design*des, NetScope*scope, << endl; } - for (set::const_iterator cur = enum_types.begin() + for (vector::const_iterator cur = enum_types.begin() ; cur != enum_types.end() ; ++ cur) { enum_type_t*curp = *cur; elaborate_scope_enumeration(des, scope, curp); diff --git a/pform.cc b/pform.cc index 1ee8de7d9..3abce4071 100644 --- a/pform.cc +++ b/pform.cc @@ -829,8 +829,10 @@ static void pform_put_wire_in_scope(perm_string name, PWire*net) void pform_put_enum_type_in_scope(enum_type_t*enum_set) { - if (lexical_scope->enum_sets.count(enum_set)) - return; + if (std::find(lexical_scope->enum_sets.begin(), + lexical_scope->enum_sets.end(), enum_set) != + lexical_scope->enum_sets.end()) + return; set enum_names; list::const_iterator cur; @@ -846,7 +848,7 @@ void pform_put_enum_type_in_scope(enum_type_t*enum_set) } } - lexical_scope->enum_sets.insert(enum_set); + lexical_scope->enum_sets.push_back(enum_set); } PWire*pform_get_make_wire_in_scope(const struct vlltype&, perm_string name, diff --git a/pform_dump.cc b/pform_dump.cc index b563e9041..32c4fb9d8 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -1544,7 +1544,7 @@ void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const void LexicalScope::dump_enumerations_(ostream&out, unsigned indent) const { - for (set::const_iterator cur = enum_sets.begin() + for (vector::const_iterator cur = enum_sets.begin() ; cur != enum_sets.end() ; ++ cur) { out << setw(indent) << "" << "enum {" << endl;