summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/alloc-size.cpp
diff options
context:
space:
mode:
authorGeorge Burgess IV <george.burgess.iv@gmail.com>2016-12-22 02:50:20 +0000
committerGeorge Burgess IV <george.burgess.iv@gmail.com>2016-12-22 02:50:20 +0000
commite37633713d93b21533d8699d0b5cf4703e3f4039 (patch)
tree21320a83b48d93d53645c55f3c1d4c5be76ffc17 /clang/test/CodeGenCXX/alloc-size.cpp
parent9ac20a1e1073cf8eb40d8efe42e17bd3b2be4682 (diff)
downloadbcm5719-llvm-e37633713d93b21533d8699d0b5cf4703e3f4039.tar.gz
bcm5719-llvm-e37633713d93b21533d8699d0b5cf4703e3f4039.zip
Add the alloc_size attribute to clang, attempt 2.
This is a recommit of r290149, which was reverted in r290169 due to msan failures. msan was failing because we were calling `isMostDerivedAnUnsizedArray` on an invalid designator, which caused us to read uninitialized memory. To fix this, the logic of the caller of said function was simplified, and we now have a `!Invalid` assert in `isMostDerivedAnUnsizedArray`, so we can catch this particular bug more easily in the future. Fingers crossed that this patch sticks this time. :) Original commit message: This patch does three things: - Gives us the alloc_size attribute in clang, which lets us infer the number of bytes handed back to us by malloc/realloc/calloc/any user functions that act in a similar manner. - Teaches our constexpr evaluator that evaluating some `const` variables is OK sometimes. This is why we have a change in test/SemaCXX/constant-expression-cxx11.cpp and other seemingly unrelated tests. Richard Smith okay'ed this idea some time ago in person. - Uniques some Blocks in CodeGen, which was reviewed separately at D26410. Lack of uniquing only really shows up as a problem when combined with our new eagerness in the face of const. llvm-svn: 290297
Diffstat (limited to 'clang/test/CodeGenCXX/alloc-size.cpp')
-rw-r--r--clang/test/CodeGenCXX/alloc-size.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/alloc-size.cpp b/clang/test/CodeGenCXX/alloc-size.cpp
new file mode 100644
index 00000000000..e93e231b70e
--- /dev/null
+++ b/clang/test/CodeGenCXX/alloc-size.cpp
@@ -0,0 +1,72 @@
+// 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);
+}
+}
OpenPOWER on IntegriCloud