Files
Marco Elver 68908a7981 [AllocToken] Propagate !alloc_token through inlined allocation wrappers (#198535)
Simple inline allocation wrappers have been preventing AllocToken
coverage for such callsites. Instead of converting such inline wrappers
to macros, we can support covering standard allocation calls in inline
allocation wrappers when inlined.

When an allocation wrapper with malloc/alloc_size attributes is inlined,
propagate its call-site !alloc_token onto return-value producing calls
exposed by inlining, so the late AllocToken pass assigns the correct
type-derived token even in default (non-extended) mode.

Propagation is restricted to calls producing the return-value(s) that
the wrapper actually returns. This keeps unrelated calls in the wrapper
body unchanged, which matters under -fsanitize-alloc-token-extended,
where any !alloc_token-carrying call is instrumented.
2026-05-20 16:18:41 +02:00

28 lines
1.0 KiB
C

// RUN: %clang_cc1 -O -fsanitize=alloc-token -fsanitize-alloc-token-extended -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --implicit-check-not=__alloc_token
// RUN: %clang_cc1 -O -fsanitize=alloc-token -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --implicit-check-not=__alloc_token
typedef __typeof(sizeof(int)) size_t;
void *sink;
void *malloc(size_t size);
void *external_ptr_helper(void);
void external_void_helper(void);
__attribute__((malloc, always_inline)) inline void *wrapper(size_t size) {
sink = external_ptr_helper();
external_void_helper();
return malloc(size);
}
// CHECK-LABEL: @test_inlined_wrapper(
// CHECK: call ptr @external_ptr_helper()
// CHECK: call void @external_void_helper()
// CHECK: call{{.*}} @__alloc_token_malloc(i64 noundef 4, i64 2689373973731826898){{.*}} !alloc_token [[META_INT:![0-9]+]]
void test_inlined_wrapper(void) {
sink = wrapper(sizeof(int));
}
// CHECK: declare{{.*}} @__alloc_token_malloc(
// CHECK: [[META_INT]] = !{!"int", i1 false}