Sure there are solutions to mitigate stack-based buffer overflows, heap-based buffer overflows, return-to-libc attacks, data-only attacks, double free, invalid memory de-referencing, etc. (that’s what I have been doing years ago during my PhD in low-level security). But they are expensive at runtime (to the point that there’s no more reason to use a low-level language) and they are pure heuristics.
If that’s easy for you, let the world know you have a solution. We will all be grateful to your contribution :)
Jokes apart, after 5 years of research my colleagues and I realized that if you can’t move detection and mitigations to the compiler level and change the programming paradigm, it’s a losing game. Rust is doing exactly that: changing the programming paradigm (with lifetime, ownership and borrow checker, etc.), and letting the compiler bust your dangerous code.
If you can’t deal with syntax that is complicated enough to save you in production, then enjoy your interpreted language. One should always use the right language for the right purpose.
I’d leave other “opinionated” conclusions (about kernels, gcc (really?) and the likes) to football games and horse racing.