gcc will compile -------------------- void f(const char *p); void g(void) { const char foo[] = "aoeuaoeuaeouaeouaoeuaoeaoxbxod"; f(foo); } ---------------------- to .cfi_startproc subq $40, %rsp .cfi_def_cfa_offset 48 movl $.LC0, %esi movl $31, %ecx leaq 1(%rsp), %rdi rep movsb leaq 1(%rsp), %rdi call f addq $40, %rsp .cfi_def_cfa_offset 8 ret .cfi_endproc No idea why it wants to copy the string before calling f.
This bug is invalid. The compiler did what you told him here. If you have the opinion for 'char s[] = "text"' would be a pointer to the constant, you are wrong.
I agree that the code is correct. The bug is because of a missing optimization, not about wrong behavior. The only use of foo is passing it function expecting a const pointer. Gcc could remove the copy and just pass a pointer to the global it created to hold the string. p.s.: how do I reopen the bug?
As missed optimization it is valid. so reopened
I believe f could do: assert (arg != "aoeuaoeuaeouaeouaoeuaoeaoxbxod"); which would then fail with the proposed optimization. It is unspecified if two string literals with the same content are distinct objects, but foo must be a distinct object (ok, with static const char foo[] = "aoeuaoeuaeouaeouaoeuaoeaoxbxod"; and -fmerge-all-constants which ignores some C requirements it doesn't have to).
Actually the copying is correct. Take: void f(const char *p); void g(int t) { const char foo[] = "aoeuaoeuaeouaeouaoeuaoeaoxbxod"; f(foo, t); if (!t) g(1); } const char *a; void f(const char *p, int t) { if (!t) a = p; else if (a == p) abort (); } void main(void) { g(0); } This program should not abort with your "optimization", it will.
In fact my testcase in comment #5 is an exact duplicate of bug 38615. *** This bug has been marked as a duplicate of bug 38615 ***
> I believe f could do: > assert (arg != "aoeuaoeuaeouaeouaoeuaoeaoxbxod"); > which would then fail with the proposed optimization. It is unspecified if > two string literals with the same content are distinct objects, but foo must be > a distinct object (ok, with static const char foo[] = > "aoeuaoeuaeouaeouaoeuaoeaoxbxod"; and -fmerge-all-constants which ignores some > C requirements it doesn't have to). Hmm, I was not aware of this. I've seen quite few cases of real world code where such local arrays was used only for direct references. It is valid to do the transform in all cases when address is not escaping and it is not used for inequality tests. We do not track the second, but we could. It is however bit tricky to do the actual promotion of automatic scalar var to static as gimplification lower initializers very early and thus we will have to reconstruct it from gimple code. Worthwhile optimization however I think. Honza