You can return out references and still get dangling pointers with const values. For example, you can return an iterator outside the scope it lives in and dereference that iterator for undefined behavior (use-after-free, possibly exploitable as above).
Besides, isn't "C++ is memory safe if you don't use mutation" (even if it were true—which it isn't) an extremely uninteresting statement? That's a very crippled subset of the language.
Besides, isn't "C++ is memory safe if you don't use mutation" (even if it were true—which it isn't) an extremely uninteresting statement? That's a very crippled subset of the language.