@@ -142,7 +142,10 @@ void static_lifetime_init(
142142 dest.add (std::move (*code));
143143 }
144144
145- // now call designated "initialization" functions
145+ // now call designated "initialization" functions; compute required order
146+ // first
147+ std::map<mp_integer, std::list<std::reference_wrapper<const symbolt>>>
148+ constructors_by_priority;
146149
147150 for (const std::string &id : symbols)
148151 {
@@ -156,8 +159,42 @@ void static_lifetime_init(
156159 code_type.return_type ().id () == ID_constructor &&
157160 code_type.parameters ().empty ())
158161 {
162+ const exprt &priority = static_cast <const exprt &>(
163+ code_type.return_type ().find (ID_constructor_priority));
164+ if (priority.id () == ID_default)
165+ constructors_by_priority[-1 ].push_back (symbol);
166+ else
167+ {
168+ std::optional<mp_integer> priority_int_opt =
169+ numeric_cast<mp_integer>(priority);
170+ DATA_INVARIANT (
171+ priority_int_opt.has_value () && *priority_int_opt >= 0 ,
172+ " constructor priority expected to be non-negative integer" );
173+ constructors_by_priority[*priority_int_opt].push_back (symbol);
174+ }
175+ }
176+ }
177+
178+ // append all constructors with priority "default" to the otherwise
179+ // lowest-priority constructor list
180+ if (
181+ constructors_by_priority.size () > 1 &&
182+ constructors_by_priority.begin ()->first == -1 )
183+ {
184+ auto &dest_list = std::prev (constructors_by_priority.end ())->second ;
185+ dest_list.splice (dest_list.end (), constructors_by_priority.begin ()->second );
186+ }
187+
188+ for (const auto &priority_pair : constructors_by_priority)
189+ {
190+ for (const auto &sym_ref : priority_pair.second )
191+ {
192+ const code_typet &code_type = to_code_type (sym_ref.get ().type );
159193 dest.add (code_expressiont{side_effect_expr_function_callt{
160- symbol.symbol_expr (), {}, code_type.return_type (), source_location}});
194+ sym_ref.get ().symbol_expr (),
195+ {},
196+ code_type.return_type (),
197+ source_location}});
161198 }
162199 }
163200}
0 commit comments