diff options
-rw-r--r-- | runtime/klee-libc/__cxa_atexit.c | 5 | ||||
-rw-r--r-- | test/Runtime/klee-libc/cxa_thread_atexit_impl.c | 20 |
2 files changed, 25 insertions, 0 deletions
diff --git a/runtime/klee-libc/__cxa_atexit.c b/runtime/klee-libc/__cxa_atexit.c index 990b645d..eb0c3e41 100644 --- a/runtime/klee-libc/__cxa_atexit.c +++ b/runtime/klee-libc/__cxa_atexit.c @@ -47,3 +47,8 @@ int __cxa_atexit(void (*fn)(void*), return 0; } +// This variant is part of more recent glibc versions and +// is required by the Rust standard library +int __cxa_thread_atexit_impl(void (*fn)(void*), void *arg, void *dso_handle) { + return __cxa_atexit(fn, arg, dso_handle); +} diff --git a/test/Runtime/klee-libc/cxa_thread_atexit_impl.c b/test/Runtime/klee-libc/cxa_thread_atexit_impl.c new file mode 100644 index 00000000..18dc7e08 --- /dev/null +++ b/test/Runtime/klee-libc/cxa_thread_atexit_impl.c @@ -0,0 +1,20 @@ +// RUN: %clang %s -emit-llvm %O0opt -c -o %t1.bc +// RUN: rm -rf %t.klee-out +// RUN: %klee --output-dir=%t.klee-out --exit-on-error --libc=klee %t1.bc + +// just make sure __cxa_thread_atexit_impl works ok + +#include <assert.h> + +extern int __cxa_thread_atexit_impl(void (*)(void*), void*, void *); + +static int x; // a global whose address we can take + +void boo(void *h) { + assert(h == (void*)&x); +} + +int main() { + __cxa_thread_atexit_impl(boo, (void*)&x, (void*)0); + return 0; +} |