Skip to content

RTTI hook type erasure is considered undefined behavior by clang #1424

Open
@alaviss

Description

@alaviss

Example

type
  X = object of RootObj

proc `=destroy`(x: var X) =
  discard

proc main() =
  var x: ref RootObj = (ref X)()

main()

Actual Output

Note that a recent clang version (>= 17) is required.

$ nim r --cc:clang --passC:-fsanitize=function --passL:-fsanitize=function test.nim

cache/nimskull/test_d/stdlib_system.nim.c:2046:3: runtime error: call to function eqdestroy___test_2 through pointer to incorrect function type 'void (*)(void *)'

Possible Solution

Generate generic thunks for hooks called via RTTI. For example

void eqdestroy_thunk___test_2(void* ptr) {
  eqdestroy___test_2((X*) ptr);
}

Alternatively type erase eqdestroy/eqtrace parameters, but that spells trouble if anyone uses =destroy/=trace as function pointers.

References

Many other projects are also dealing with the fallout:

Apparently this new UB warning has to do with CFI (Control Flow Integrity) protections.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcompiler/backendRelated to backend system of the compiler

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions