Actually, I’m not so sure about GCC semantics any longer when digging deeper into this.
In my initial example const char x[] __attribute__ ((weak)) = "X";
gcc doesn’t use the initializer value for optimization.
But if it is changed to not be an array but rather a plain int like const int x __attribute__ ((weak)) = 42;
gcc does actually use it.
And interestingly enough we have a testcase for that very thing. “Check for bug compatibility with gcc”
https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGen/weak_constant.c
(but can’t find any relevant testcases in gcc test suite, just ones with volatile weak, which is kinda on the other end of the spectrum)
(Updated Compiler Explorer link)