fix(eo): fix null pointer and dangling pointer bugs in eoForge

eoForgeOperator no-arg specialization: instantiate_ptr() constructed an
empty shared_ptr instead of a new Op instance, always returning nullptr.
Fix: std::shared_ptr<Op>() → std::make_shared<Op>().

eoForgeMap::setup(): after deleting the old operator, emplace() silently
no-ops when the key already exists, leaving a dangling pointer in the map
and leaking the new allocation. Fix: assign through at() instead.
This commit is contained in:
Eremey Valetov 2026-02-28 20:39:17 -05:00
commit a710faebd3

View file

@ -203,7 +203,7 @@ class eoForgeOperator<Itf,Op> : public eoForgeInterface<Itf>
std::shared_ptr<Itf> instantiate_ptr( bool no_cache = true ) override std::shared_ptr<Itf> instantiate_ptr( bool no_cache = true ) override
{ {
if(no_cache or _instantiated == nullptr) { if(no_cache or _instantiated == nullptr) {
_instantiated_ptr = std::shared_ptr<Op>(); _instantiated_ptr = std::make_shared<Op>();
} }
return _instantiated_ptr; return _instantiated_ptr;
} }
@ -479,7 +479,7 @@ class eoForgeMap : public std::map<std::string,eoForgeInterface<Itf>*>
delete this->at(name); // Silent on nullptr. delete this->at(name); // Silent on nullptr.
auto pfo = new eoForgeOperator<Itf,Op,std::decay_t<Args>...>( auto pfo = new eoForgeOperator<Itf,Op,std::decay_t<Args>...>(
std::forward<Args>(args)...); std::forward<Args>(args)...);
this->emplace({name, pfo}); this->at(name) = pfo;
} }
/** Specialization for empty constructors. /** Specialization for empty constructors.
@ -489,7 +489,7 @@ class eoForgeMap : public std::map<std::string,eoForgeInterface<Itf>*>
{ {
delete this->at(name); delete this->at(name);
auto pfo = new eoForgeOperator<Itf,Op>; auto pfo = new eoForgeOperator<Itf,Op>;
this->emplace({name, pfo}); this->at(name) = pfo;
} }
virtual ~eoForgeMap() virtual ~eoForgeMap()