[PATCH] D148827: -fsanitize=function: support C

Fangrui Song via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 14 13:57:46 PDT 2023


MaskRay added a comment.

In D148827#4422498 <https://reviews.llvm.org/D148827#4422498>, @glandium wrote:

> In D148827#4379764 <https://reviews.llvm.org/D148827#4379764>, @MaskRay wrote:
>
>> These cases are UB and should be caught. It's not an excuse that they use C.
>
> Are they really though?

They are.

>   struct A {
>     int a;
>   };
>   
>   int foo(struct A *a) { return 42; }
>   
>   int bar(void *a) { return foo(a); }
>   
>   int main(void) {
>     struct A a;
>     bar(&a);
>     int (*qux)(void *) = (int (*)(void *))foo;
>     qux(&a); // If this is UB, why isn't the call to foo from bar?
>     return 0;
>   }
>
> Likewise for `int foo()` and `int bar(void)`/`int (*qux)(void)`.
> Likewise for `struct A* foo(void)` and `void *bar(void)`/`void *(*qux)(void)` (surprisingly, clang doesn't emit this error for `struct A* foo()` and `void* bar()`/`void*(*qux)()`)

C11 6.5.2.2p9 (as mentioned in the patch summary)

> If the function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function, the behavior is undefined.

`void *` and `struct A*` are not compatible per 6.7..6.1p2

> For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.

For old-style (parameter-less) definitions (warned by `-Wstrict-prototypes` unless `-std=c2x`), we have the following behaviors:

  int foo() { return 42; } // old-style (parameter-less) definition, warned by -Wstrict-prototypes unless -std=c2x
  int bar(int a) { return 42; }
  
  int main(void) {
    //int (*qux)(int) = (int (*)(int))foo;
    //qux(42);  // rejected by -fsanitize=function
    int (*qux)() = (int (*)())foo;
    qux(); // not rejected by -fsanitize=function
    return 0;
  }

If you enable `-fsanitize=undefined` for some C proijects with the UB, you can consider suppressing them with `ubsan_ignorelist.txt` or enabling `-fno-sanitize=function` for the C files.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148827/new/

https://reviews.llvm.org/D148827



More information about the cfe-commits mailing list