https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92474
Bug ID: 92474 Summary: Sanitizer breaks tail-recursion optimization Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: Hi-Angel at yandex dot ru CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org Target Milestone: --- When `-fsanitize=address` applied, tail-call optimization does not kick in. I made a testcase below. Simplest way to demonstrate it would be to try to run executable built from the testcase with and without the option: it either crashes or not. But since it's an arguable demonstration (because how does one know if non-crashing version didn't simply did not consume enough stack), I demonstrate it with a different approach: I grep the assembly for `callq foo()`, and while the case with optimization applied has just one call to it, the case where it wasn't applied has 2 of them. # Steps to reproduce (in terms of terminal commands): $ cat test.cpp struct MyStruct { unsigned n_recurses; }; MyStruct foo(MyStruct m) { return (m.n_recurses == 0)? m : foo(MyStruct{m.n_recurses - 1}); } int main() { foo(MyStruct{999999}); } $ g++ test.cpp -o a -O3 -g $ objdump -d a | grep -E "callq.*foo" 1029: e8 12 01 00 00 callq 1140 <_Z3foo8MyStruct> $ g++ test.cpp -o a -O3 -g -fsanitize=address $ objdump -d a | grep -E "callq.*foo" ## Expected: One line with the call: 1089: e8 32 01 00 00 callq 11c0 <_Z3foo8MyStruct> ## Actual: Two lines with the call: 1089: e8 32 01 00 00 callq 11c0 <_Z3foo8MyStruct> 1293: e8 28 ff ff ff callq 11c0 <_Z3foo8MyStruct>