That happens because the string is static. If you rewrite that so s is an argument to writable(), it will segfault.

Although, I am curious if that optimization could happen across compilation units via LTO...

I'm not sure what you mean. In `writable()`, there's no read-only data; `s` is a non-const char array (it has to be static because the function returns a pointer to it). The string literal is only there to tell the compiler how to initialize the array, `s` is not actually the string literal.

If you change `writable()` to receive a `const char *` (and then cast it to `char *` to write), then clang will be forced to compile it with a store (even though it sees you storing to a `const char *`) because it doesn't know if the function will be called with a pointer to actual read-only data or just a pointer to writable data that was gratuitously converted to `const`.

> because it doesn't know if the function will be called with a pointer to actual read-only data or just a pointer to writable data that was gratuitously

That's exactly my point yeah, the optimization you described is only possible because you gave the compiler extra knowledge about the argument to that function (because it was static in the same compilation unit). It's artificial, typically that won't be the case.

Ah, I understand you now, you're right.

I remember there was a lot of confusion when llvm started removing stores to read-only memory[1], some people got angry because it broke some kernel code (that only worked because being in a kernel the memory page wasn't actually marked as read-only) and thought it would break any code that cast away a `const`, which is very common and valid as long as it was gratuitously `const`, as you say.

[1] https://releases.llvm.org/9.0.0/docs/ReleaseNotes.html#notew...