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

Fangrui Song via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 14 14:45:03 PDT 2023


MaskRay added a comment.

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

> OTOH. 6.2.7.3:
>
>> A composite type can be constructed from two types that are compatible; it is a type that is compatible with both of the two types (...)
>
> 6.2.7.5:
>
>> EXAMPLE Given the following two file scope declarations:
>> int f(int (*)(), double (*)[3]);
>> int f(int (*)(char *), double (*)[]);
>> The resulting composite type for the function is:
>> int f(int (*)(char *), double (*)[3]);
>
> This suggests that `int(*)()` and `int(*)(char*)` are compatible.

Yes, I mentioned this in my previous comment. This fragment is overly strict but I think it should be fine in practice. This mismatching is uncommon and old-style (parameter-less) definitions will be unsupported in C2x anyway.
The other direction is worked around by this patch (see `!isa<FunctionNoProtoType>(PointeeType)`).

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



> 6.2.7.2:
>
>> All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.
>
> 6.3.2.3.1:
>
>> A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
>
> These are either contradicting, making 6.3.2.3.1 UB, or void* is compatible with other pointer types.

6.3.2.3.1 is about a pointer casting rule, which is different from type compatibility.
In C++, there is no C type compatibility rule, but we can still cast pointers.

To elaborate my previous comment about working around C projects, you can use the following to suppress instrumentation for all `.c` files (but not `.cc` or `.cpp`)

  # -fsanitize=undefined -fsanitize-ignorelist=a.ignorelist
  % cat a.ignorelist
  [function]
  src:*\.c


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