1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s 2 3 namespace templates { 4 void *my_malloc(int N) __attribute__((alloc_size(1))); 5 void *my_calloc(int N, int M) __attribute__((alloc_size(1, 2))); 6 7 struct MyType { 8 int arr[4]; 9 }; 10 11 template <typename T> int callMalloc(); 12 13 template <typename T, int N> int callCalloc(); 14 15 // CHECK-LABEL: define i32 @_ZN9templates6testItEv() 16 int testIt() { 17 // CHECK: call i32 @_ZN9templates10callMallocINS_6MyTypeEEEiv 18 // CHECK: call i32 @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv 19 return callMalloc<MyType>() + callCalloc<MyType, 4>(); 20 } 21 22 // CHECK-LABEL: define linkonce_odr i32 23 // @_ZN9templates10callMallocINS_6MyTypeEEEiv 24 template <typename T> int callMalloc() { 25 static_assert(sizeof(T) == 16, ""); 26 // CHECK: ret i32 16 27 return __builtin_object_size(my_malloc(sizeof(T)), 0); 28 } 29 30 // CHECK-LABEL: define linkonce_odr i32 31 // @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv 32 template <typename T, int N> int callCalloc() { 33 static_assert(sizeof(T) * N == 64, ""); 34 // CHECK: ret i32 64 35 return __builtin_object_size(my_malloc(sizeof(T) * N), 0); 36 } 37 } 38 39 namespace templated_alloc_size { 40 using size_t = unsigned long; 41 42 // We don't need bodies for any of these, because they're only used in 43 // __builtin_object_size, and that shouldn't need anything but a function 44 // decl with alloc_size on it. 45 template <typename T> 46 T *my_malloc(size_t N = sizeof(T)) __attribute__((alloc_size(1))); 47 48 template <typename T> 49 T *my_calloc(size_t M, size_t N = sizeof(T)) __attribute__((alloc_size(2, 1))); 50 51 template <size_t N> 52 void *dependent_malloc(size_t NT = N) __attribute__((alloc_size(1))); 53 54 template <size_t N, size_t M> 55 void *dependent_calloc(size_t NT = N, size_t MT = M) 56 __attribute__((alloc_size(1, 2))); 57 58 template <typename T, size_t M> 59 void *dependent_calloc2(size_t NT = sizeof(T), size_t MT = M) 60 __attribute__((alloc_size(1, 2))); 61 62 // CHECK-LABEL: define i32 @_ZN20templated_alloc_size6testItEv 63 int testIt() { 64 // 122 = 4 + 5*4 + 6 + 7*8 + 4*9 65 // CHECK: ret i32 122 66 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_size 73 74 // Be sure that an ExprWithCleanups doesn't deter us. 75 namespace alloc_size_with_cleanups { 76 struct Foo { 77 ~Foo(); 78 }; 79 80 void *my_malloc(const Foo &, int N) __attribute__((alloc_size(2))); 81 82 // CHECK-LABEL: define i32 @_ZN24alloc_size_with_cleanups6testItEv 83 int testIt() { 84 int *const p = (int *)my_malloc(Foo{}, 3); 85 // CHECK: ret i32 3 86 return __builtin_object_size(p, 0); 87 } 88 } // namespace alloc_size_with_cleanups 89 90 class C { 91 public: 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 i32 @_Z16callMemberMallocv 97 int callMemberMalloc() { 98 // CHECK: ret i32 16 99 return __builtin_object_size(C().my_malloc(16), 0); 100 } 101 102 // CHECK-LABEL: define i32 @_Z16callMemberCallocv 103 int callMemberCalloc() { 104 // CHECK: ret i32 32 105 return __builtin_object_size(C().my_calloc(16, 2), 0); 106 } 107