forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			107 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -O0 %s -o - 2>&1 -std=c++11 | FileCheck %s
 | 
						|
 | 
						|
namespace templates {
 | 
						|
void *my_malloc(int N) __attribute__((alloc_size(1)));
 | 
						|
void *my_calloc(int N, int M) __attribute__((alloc_size(1, 2)));
 | 
						|
 | 
						|
struct MyType {
 | 
						|
  int arr[4];
 | 
						|
};
 | 
						|
 | 
						|
template <typename T> int callMalloc();
 | 
						|
 | 
						|
template <typename T, int N> int callCalloc();
 | 
						|
 | 
						|
// CHECK-LABEL: define i32 @_ZN9templates6testItEv()
 | 
						|
int testIt() {
 | 
						|
  // CHECK: call i32 @_ZN9templates10callMallocINS_6MyTypeEEEiv
 | 
						|
  // CHECK: call i32 @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv
 | 
						|
  return callMalloc<MyType>() + callCalloc<MyType, 4>();
 | 
						|
}
 | 
						|
 | 
						|
// CHECK-LABEL: define linkonce_odr i32
 | 
						|
// @_ZN9templates10callMallocINS_6MyTypeEEEiv
 | 
						|
template <typename T> int callMalloc() {
 | 
						|
  static_assert(sizeof(T) == 16, "");
 | 
						|
  // CHECK: ret i32 16
 | 
						|
  return __builtin_object_size(my_malloc(sizeof(T)), 0);
 | 
						|
}
 | 
						|
 | 
						|
// CHECK-LABEL: define linkonce_odr i32
 | 
						|
// @_ZN9templates10callCallocINS_6MyTypeELi4EEEiv
 | 
						|
template <typename T, int N> int callCalloc() {
 | 
						|
  static_assert(sizeof(T) * N == 64, "");
 | 
						|
  // CHECK: ret i32 64
 | 
						|
  return __builtin_object_size(my_malloc(sizeof(T) * N), 0);
 | 
						|
}
 | 
						|
}
 | 
						|
 | 
						|
namespace templated_alloc_size {
 | 
						|
using size_t = unsigned long;
 | 
						|
 | 
						|
// We don't need bodies for any of these, because they're only used in
 | 
						|
// __builtin_object_size, and that shouldn't need anything but a function
 | 
						|
// decl with alloc_size on it.
 | 
						|
template <typename T>
 | 
						|
T *my_malloc(size_t N = sizeof(T)) __attribute__((alloc_size(1)));
 | 
						|
 | 
						|
template <typename T>
 | 
						|
T *my_calloc(size_t M, size_t N = sizeof(T)) __attribute__((alloc_size(2, 1)));
 | 
						|
 | 
						|
template <size_t N>
 | 
						|
void *dependent_malloc(size_t NT = N) __attribute__((alloc_size(1)));
 | 
						|
 | 
						|
template <size_t N, size_t M>
 | 
						|
void *dependent_calloc(size_t NT = N, size_t MT = M)
 | 
						|
    __attribute__((alloc_size(1, 2)));
 | 
						|
 | 
						|
template <typename T, size_t M>
 | 
						|
void *dependent_calloc2(size_t NT = sizeof(T), size_t MT = M)
 | 
						|
    __attribute__((alloc_size(1, 2)));
 | 
						|
 | 
						|
// CHECK-LABEL: define i32 @_ZN20templated_alloc_size6testItEv
 | 
						|
int testIt() {
 | 
						|
  // 122 = 4 + 5*4 + 6 + 7*8 + 4*9
 | 
						|
  // CHECK: ret i32 122
 | 
						|
  return __builtin_object_size(my_malloc<int>(), 0) +
 | 
						|
         __builtin_object_size(my_calloc<int>(5), 0) +
 | 
						|
         __builtin_object_size(dependent_malloc<6>(), 0) +
 | 
						|
         __builtin_object_size(dependent_calloc<7, 8>(), 0) +
 | 
						|
         __builtin_object_size(dependent_calloc2<int, 9>(), 0);
 | 
						|
}
 | 
						|
} // namespace templated_alloc_size
 | 
						|
 | 
						|
// Be sure that an ExprWithCleanups doesn't deter us.
 | 
						|
namespace alloc_size_with_cleanups {
 | 
						|
struct Foo {
 | 
						|
  ~Foo();
 | 
						|
};
 | 
						|
 | 
						|
void *my_malloc(const Foo &, int N) __attribute__((alloc_size(2)));
 | 
						|
 | 
						|
// CHECK-LABEL: define i32 @_ZN24alloc_size_with_cleanups6testItEv
 | 
						|
int testIt() {
 | 
						|
  int *const p = (int *)my_malloc(Foo{}, 3);
 | 
						|
  // CHECK: ret i32 3
 | 
						|
  return __builtin_object_size(p, 0);
 | 
						|
}
 | 
						|
} // namespace alloc_size_with_cleanups
 | 
						|
 | 
						|
class C {
 | 
						|
public:
 | 
						|
  void *my_malloc(int N) __attribute__((alloc_size(2)));
 | 
						|
  void *my_calloc(int N, int M) __attribute__((alloc_size(2, 3)));
 | 
						|
};
 | 
						|
 | 
						|
// CHECK-LABEL: define i32 @_Z16callMemberMallocv
 | 
						|
int callMemberMalloc() {
 | 
						|
  // CHECK: ret i32 16
 | 
						|
  return __builtin_object_size(C().my_malloc(16), 0);
 | 
						|
}
 | 
						|
 | 
						|
// CHECK-LABEL: define i32 @_Z16callMemberCallocv
 | 
						|
int callMemberCalloc() {
 | 
						|
  // CHECK: ret i32 32
 | 
						|
  return __builtin_object_size(C().my_calloc(16, 2), 0);
 | 
						|
}
 |