107 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s2 3namespace templates {4void *my_malloc(int N) __attribute__((alloc_size(1)));5void *my_calloc(int N, int M) __attribute__((alloc_size(1, 2)));6 7struct MyType {8 int arr[4];9};10 11template <typename T> int callMalloc();12 13template <typename T, int N> int callCalloc();14 15// CHECK-LABEL: define{{.*}} i32 @_ZN9templates6testItEv()16int testIt() {17 // CHECK: call noundef i32 @_ZN9templates10callMallocINS_6MyTypeEEEiv18 // CHECK: call noundef i32 @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv19 return callMalloc<MyType>() + callCalloc<MyType, 4>();20}21 22// CHECK-LABEL: define linkonce_odr noundef i3223// @_ZN9templates10callMallocINS_6MyTypeEEEiv24template <typename T> int callMalloc() {25 static_assert(sizeof(T) == 16, "");26 // CHECK: ret i32 1627 return __builtin_object_size(my_malloc(sizeof(T)), 0);28}29 30// CHECK-LABEL: define linkonce_odr noundef i3231// @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv32template <typename T, int N> int callCalloc() {33 static_assert(sizeof(T) * N == 64, "");34 // CHECK: ret i32 6435 return __builtin_object_size(my_malloc(sizeof(T) * N), 0);36}37}38 39namespace templated_alloc_size {40using size_t = unsigned long;41 42// We don't need bodies for any of these, because they're only used in43// __builtin_object_size, and that shouldn't need anything but a function44// decl with alloc_size on it.45template <typename T>46T *my_malloc(size_t N = sizeof(T)) __attribute__((alloc_size(1)));47 48template <typename T>49T *my_calloc(size_t M, size_t N = sizeof(T)) __attribute__((alloc_size(2, 1)));50 51template <size_t N>52void *dependent_malloc(size_t NT = N) __attribute__((alloc_size(1)));53 54template <size_t N, size_t M>55void *dependent_calloc(size_t NT = N, size_t MT = M)56 __attribute__((alloc_size(1, 2)));57 58template <typename T, size_t M>59void *dependent_calloc2(size_t NT = sizeof(T), size_t MT = M)60 __attribute__((alloc_size(1, 2)));61 62// CHECK-LABEL: define{{.*}} noundef i32 @_ZN20templated_alloc_size6testItEv63int testIt() {64 // 122 = 4 + 5*4 + 6 + 7*8 + 4*965 // CHECK: ret i32 12266 return __builtin_object_size(my_malloc<int>(), 0) +67 __builtin_object_size(my_calloc<int>(5), 0) +68 __builtin_object_size(dependent_malloc<6>(), 0) +69 __builtin_object_size(dependent_calloc<7, 8>(), 0) +70 __builtin_object_size(dependent_calloc2<int, 9>(), 0);71}72} // namespace templated_alloc_size73 74// Be sure that an ExprWithCleanups doesn't deter us.75namespace alloc_size_with_cleanups {76struct Foo {77 ~Foo();78};79 80void *my_malloc(const Foo &, int N) __attribute__((alloc_size(2)));81 82// CHECK-LABEL: define{{.*}} noundef i32 @_ZN24alloc_size_with_cleanups6testItEv83int testIt() {84 int *const p = (int *)my_malloc(Foo{}, 3);85 // CHECK: ret i32 386 return __builtin_object_size(p, 0);87}88} // namespace alloc_size_with_cleanups89 90class C {91public:92 void *my_malloc(int N) __attribute__((alloc_size(2)));93 void *my_calloc(int N, int M) __attribute__((alloc_size(2, 3)));94};95 96// CHECK-LABEL: define{{.*}} noundef i32 @_Z16callMemberMallocv97int callMemberMalloc() {98 // CHECK: ret i32 1699 return __builtin_object_size(C().my_malloc(16), 0);100}101 102// CHECK-LABEL: define{{.*}} noundef i32 @_Z16callMemberCallocv103int callMemberCalloc() {104 // CHECK: ret i32 32105 return __builtin_object_size(C().my_calloc(16, 2), 0);106}107