2016-12-22 10:50:20 +08:00
|
|
|
// 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();
|
|
|
|
|
2020-12-31 12:45:56 +08:00
|
|
|
// CHECK-LABEL: define{{.*}} i32 @_ZN9templates6testItEv()
|
2016-12-22 10:50:20 +08:00
|
|
|
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)));
|
|
|
|
|
2020-12-31 12:45:56 +08:00
|
|
|
// CHECK-LABEL: define{{.*}} i32 @_ZN20templated_alloc_size6testItEv
|
2016-12-22 10:50:20 +08:00
|
|
|
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);
|
|
|
|
}
|
[Attr] Fix parameter indexing for several attributes
The patch fixes a number of bugs related to parameter indexing in
attributes:
* Parameter indices in some attributes (argument_with_type_tag,
pointer_with_type_tag, nonnull, ownership_takes, ownership_holds,
and ownership_returns) are specified in source as one-origin
including any C++ implicit this parameter, were stored as
zero-origin excluding any this parameter, and were erroneously
printing (-ast-print) and confusingly dumping (-ast-dump) as the
stored values.
* For alloc_size, the C++ implicit this parameter was not subtracted
correctly in Sema, leading to assert failures or to silent failures
of __builtin_object_size to compute a value.
* For argument_with_type_tag, pointer_with_type_tag, and
ownership_returns, the C++ implicit this parameter was not added
back to parameter indices in some diagnostics.
This patch fixes the above bugs and aims to prevent similar bugs in
the future by introducing careful mechanisms for handling parameter
indices in attributes. ParamIdx stores a parameter index and is
designed to hide the stored encoding while providing accessors that
require each use (such as printing) to make explicit the encoding that
is needed. Attribute declarations declare parameter index arguments
as [Variadic]ParamIdxArgument, which are exposed as ParamIdx[*]. This
patch rewrites all attribute arguments that are processed by
checkFunctionOrMethodParameterIndex in SemaDeclAttr.cpp to be declared
as [Variadic]ParamIdxArgument. The only exception is xray_log_args's
argument, which is encoded as a count not an index.
Differential Revision: https://reviews.llvm.org/D43248
llvm-svn: 326602
2018-03-03 03:03:22 +08:00
|
|
|
} // namespace templated_alloc_size
|
2018-03-07 12:52:34 +08:00
|
|
|
|
|
|
|
// 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)));
|
|
|
|
|
2020-12-31 12:45:56 +08:00
|
|
|
// CHECK-LABEL: define{{.*}} i32 @_ZN24alloc_size_with_cleanups6testItEv
|
2018-03-07 12:52:34 +08:00
|
|
|
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
|
2018-03-13 22:51:22 +08:00
|
|
|
|
|
|
|
class C {
|
|
|
|
public:
|
|
|
|
void *my_malloc(int N) __attribute__((alloc_size(2)));
|
|
|
|
void *my_calloc(int N, int M) __attribute__((alloc_size(2, 3)));
|
|
|
|
};
|
|
|
|
|
2020-12-31 12:45:56 +08:00
|
|
|
// CHECK-LABEL: define{{.*}} i32 @_Z16callMemberMallocv
|
2018-03-13 22:51:22 +08:00
|
|
|
int callMemberMalloc() {
|
|
|
|
// CHECK: ret i32 16
|
|
|
|
return __builtin_object_size(C().my_malloc(16), 0);
|
|
|
|
}
|
|
|
|
|
2020-12-31 12:45:56 +08:00
|
|
|
// CHECK-LABEL: define{{.*}} i32 @_Z16callMemberCallocv
|
2018-03-13 22:51:22 +08:00
|
|
|
int callMemberCalloc() {
|
|
|
|
// CHECK: ret i32 32
|
|
|
|
return __builtin_object_size(C().my_calloc(16, 2), 0);
|
|
|
|
}
|