https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87314
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #9) > The question is how far we want to go and what we just ignore. > With -fmerge-all-constants, we can have: > const char var[] = "foobar"; > int foo (void) { return &var[0] != "foobar"; } > which will likely be now miscompiled. GCC 8 produces the following and so doesn't actually merge the constants .LC0: .string "foobar" .section .text.startup,"ax",@progbits .p2align 4,,15 .globl main .type main, @function main: .LFB0: .cfi_startproc movl $var, %eax cmpq $.LC0, %rax setne %al movzbl %al, %eax ret .cfi_endproc .LFE0: .size main, .-main .globl var .section .rodata.str1.1 .type var, @object .size var, 7 var: .string "foobar" And with -O0 it's even more obvious: var: .string "foobar" .LC0: .string "foobar" and yes, we now optimize this. > But we could even have two sources, > const char var2[] = "foobar"; > compiled with -fmerge-all-constants and > extern char var2[]; > int bar (void) { return &var2[0] != "foobar"; } > compiled with -fmerge-constants (the default). > > So, can we e.g. optimize less if we see flag_merge_all_constants and a > TREE_READONLY decl(s) (both the above first case and your const int case)? > If the decl(s) have DECL_INITIAL and bind to current TU, we could of course > check further the initializers, and ignore the nasty second case above, by > saying that > if you define vars as const and declare as non-const, it is your problem and > similarly, if you -fmerge-all-constants the defining TUs but not uses of > those decls, it is again your fault? I'd lean towards that. I didn't manage to merge the variable and the string literal, so I believe this is a theoretical issue?