Track newmenu return value using std::shared_ptr
JoeNotCharles reports that gcc-12 (architecture unspecified) warns
because `newmenu::process_until_closed` stores the address of a stack
local into a heap-allocated structure. Switch to a less efficient
implementation that does not provoke a compiler warning:
- Store `shared_ptr<int>`, not `int *`, in the `newmenu`
- `shared_ptr::operator*()` and `shared_ptr::operator bool()` allow most
use sites to be unchanged relative to a bare pointer
- Load the return value from the `shared_ptr<int>`. If the newmenu
terminated before return, as should always happen, this is a slightly
less efficient version of the same code as before. If the newmenu was
still open despite its `exists` flag claiming otherwise, then the
returned value may be incorrect, but the read will be well-formed, the
`newmenu`'s eventual write will write to the heap-backed int (rather
than writing into the stack allocated to
`newmenu::process_until_closed`), and the memory will be freed when
both `process_until_closed` has returned and the `newmenu` has been
destroyed.
Reported-by: JoeNotCharles <10a2b2d337
>
This commit is contained in:
parent
407ab585a8
commit
27586fe0b9
|
@ -354,7 +354,7 @@ struct newmenu : newmenu_layout, window, mixin_trackable_window
|
|||
newmenu_layout(title, subtitle, filename, src, tiny_mode, tabs_flag, citem_init, draw_box), window(src, x, y, w, h)
|
||||
{
|
||||
}
|
||||
int *rval = nullptr; // Pointer to return value (for polling newmenus)
|
||||
std::shared_ptr<int> rval; // Pointer to return value (for polling newmenus)
|
||||
virtual window_event_result event_handler(const d_event &) override;
|
||||
static int process_until_closed(newmenu *);
|
||||
};
|
||||
|
|
|
@ -534,8 +534,8 @@ int newmenu_do2(const menu_title title, const menu_subtitle subtitle, const rang
|
|||
|
||||
int newmenu::process_until_closed(newmenu *const menu)
|
||||
{
|
||||
int rval = -1;
|
||||
menu->rval = &rval;
|
||||
auto rval = std::make_shared<int>(-1);
|
||||
menu->rval = rval;
|
||||
// Track to see when the window is freed
|
||||
// Doing this way in case another window is opened on top without its own polling loop
|
||||
// newmenu_do2 and simpler get their own event loop
|
||||
|
@ -546,7 +546,7 @@ int newmenu::process_until_closed(newmenu *const menu)
|
|||
/* menu is now a pointer to freed memory, and cannot be accessed
|
||||
* further
|
||||
*/
|
||||
return rval;
|
||||
return *rval;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
Loading…
Reference in a new issue