Skip to content

-fsanitize=cfi-icall leads to eliminated icalls with optimization levels above -O0 #111905

Open
@jwillbold

Description

@jwillbold

-fsanitize=cfi-icall does not emit CFI statements and eliminates the icall during code elimination, leading to broken binaries.

We have created a minimal example highlighting the issue. The following code gets compiled using clang 19.1.0 x86_64 and -O3 -fsanitize=cfi-icall -flto

void (*pFunc)();

int main(int argc, char** argv) {
    pFunc = argv[1];
    pFunc();
}

to

main:
 mov    rax,QWORD PTR [rsi+0x8]
 mov    QWORD PTR [rip+0x2edd],rax        # 4018 <pFunc>
 ud1    eax,DWORD PTR [eax+0x2]

When setting the -O0, it does emit the icall as expected. We created a compiler explorer example: https://godbolt.org/z/P71hx6xqs

However, we have also found that initializing the pFunc seems to stop the code elimination:

void test() {
    test();
}

//void (*pFunc)(); // Bad
void (*pFunc)() = &test; // Good

int main(int argc, char** argv) {
    pFunc = (void (*)())**argv;
    pFunc();
}

In that case the icall exists. Compiler explorer: https://godbolt.org/z/36hYWb7YW

We have also tested the previous clang version but cannot find a version where this compiles as expected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions