// Test __msan_set_indirect_call_wrapper. // RUN: %clangxx_msan -mllvm -msan-wrap-indirect-calls=__msan_wrap_indirect_call \ // RUN: -mllvm -msan-wrap-indirect-calls-fast=0 \ // RUN: -O0 -g -rdynamic -Wl,--defsym=__executable_start=0 %s -o %t && %t // This test disables -msan-wrap-indirect-calls-fast, otherwise indirect calls // inside the same module are short-circuited and are never seen by the wrapper. #include #include #include #include extern "C" void __msan_set_indirect_call_wrapper(uintptr_t); bool done_f, done_g; void f(void) { assert(!done_g); done_f = true; } void g(void) { assert(done_f); done_g = true; } typedef void (*Fn)(void); extern "C" Fn my_wrapper(Fn target) { if (target == f) return g; return target; } int main(void) { volatile Fn fp; fp = &f; fp(); __msan_set_indirect_call_wrapper((uintptr_t)my_wrapper); fp(); return !(done_f && done_g); }