https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111708
Bug ID: 111708 Summary: Calling external global function instead of local static function. Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: k.frolov at samsung dot com Target Milestone: --- I have a test case, in which as I believe GCC compiler must call local static function but not external function instead. This test case work as I expect with clang compiler, with gcc in C++ mode, but in C mode I have strange behaviour when gcc tries to call external function instead of already defined local function with same name. The problem is reproducible with any available GCC version, starting from GCC 4.1 and ending with current trunk. The problem is independend from the target platform and reproducible when generating code for any platform. In following examples aarch64 is used as target platform. The problem depends on optimization options: with option "-O0" compiler behaviour changes (see below). ///// Test code (.c source): static int f(int); int main(int argc, const char *argv[]) { (void)argv; return f(argc); } static int f(int f) { int x = f; { int f(int); if (x < 1) return 0; else return f(x - 1); } } //// end of test source. Code compiled with the following compiler options: -std=c99 -Wall -Wextra -fstrict-aliasing -Wcast-align -Os With the following compilator options clang and gcc in C++ mode (with command line option "-x c") produces same output: main: mov w0, 0 ret GCC in C mode produces following output: main: cmp w0, 0 ble .L2 sub w0, w0, #1 b f .L2: mov w0, 0 ret Where "f" is some unknown and global symbol. With optimization turned off, following code is generated by GCC in C-mode: .global main .type main, %function main: stp x29, x30, [sp, -32]! mov x29, sp str w0, [sp, 28] str x1, [sp, 16] ldr w0, [sp, 28] bl f ldp x29, x30, [sp], 32 ret .type f, %function f: stp x29, x30, [sp, -48]! mov x29, sp str w0, [sp, 28] ldr w0, [sp, 28] str w0, [sp, 44] ldr w0, [sp, 44] cmp w0, 0 bgt .L4 mov w0, 0 b .L5 .L4: ldr w0, [sp, 44] sub w0, w0, #1 bl f .L5: ldp x29, x30, [sp], 48 ret As you see, external symbol "f" is not referenced anymore, as compiler defines "f" function by itself. Please note, there is neither ".local" nor ".global" instruction for fuction "f". Code generated with "-O0" in C mode is (almost, differencies exist due to symbol mangling) same as code generated with "-O0" in C++ mode. Link to godbolt site demonstrating the effect: https://godbolt.org/z/7d9GG8KvY