summaryrefslogtreecommitdiff
path: root/test/CodeGen/pass-object-size.c
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:02:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:02:28 +0000
commit7442d6faa2719e4e7d33a7021c406c5a4facd74d (patch)
treec72b9241553fc9966179aba84f90f17bfa9235c3 /test/CodeGen/pass-object-size.c
parentb52119637f743680a99710ce5fdb6646da2772af (diff)
Diffstat (limited to 'test/CodeGen/pass-object-size.c')
-rw-r--r--test/CodeGen/pass-object-size.c57
1 files changed, 53 insertions, 4 deletions
diff --git a/test/CodeGen/pass-object-size.c b/test/CodeGen/pass-object-size.c
index 6f5827befa714..f5c12317ec323 100644
--- a/test/CodeGen/pass-object-size.c
+++ b/test/CodeGen/pass-object-size.c
@@ -343,16 +343,26 @@ void test12(void *const p __attribute__((pass_object_size(3)))) {
// CHECK-LABEL: define void @test13
void test13() {
- // Ensuring that we don't lower objectsize if the expression has side-effects
char c[10];
+ unsigned i = 0;
char *p = c;
// CHECK: @llvm.objectsize
ObjectSize0(p);
- // CHECK-NOT: @llvm.objectsize
- ObjectSize0(++p);
- ObjectSize0(p++);
+ // Allow side-effects, since they always need to happen anyway. Just make sure
+ // we don't perform them twice.
+ // CHECK: = add
+ // CHECK-NOT: = add
+ // CHECK: @llvm.objectsize
+ // CHECK: call i32 @ObjectSize0
+ ObjectSize0(p + ++i);
+
+ // CHECK: = add
+ // CHECK: @llvm.objectsize
+ // CHECK-NOT: = add
+ // CHECK: call i32 @ObjectSize0
+ ObjectSize0(p + i++);
}
// There was a bug where variadic functions with pass_object_size would cause
@@ -369,3 +379,42 @@ void test14(char *c) {
// CHECK: call void (i8*, i64, ...) @my_sprintf
my_sprintf(c, 1, 2, 3);
}
+
+void pass_size_unsigned(unsigned *const PS(0));
+
+// Bug: we weren't lowering to the proper @llvm.objectsize for pointers that
+// don't turn into i8*s, which caused crashes.
+// CHECK-LABEL: define void @test15
+void test15(unsigned *I) {
+ // CHECK: @llvm.objectsize.i64.p0i32
+ // CHECK: call void @pass_size_unsigned
+ pass_size_unsigned(I);
+}
+
+void pass_size_as1(__attribute__((address_space(1))) void *const PS(0));
+
+void pass_size_unsigned_as1(
+ __attribute__((address_space(1))) unsigned *const PS(0));
+
+// CHECK-LABEL: define void @test16
+void test16(__attribute__((address_space(1))) unsigned *I) {
+ // CHECK: call i64 @llvm.objectsize.i64.p1i8
+ // CHECK: call void @pass_size_as1
+ pass_size_as1(I);
+ // CHECK: call i64 @llvm.objectsize.i64.p1i32
+ // CHECK: call void @pass_size_unsigned_as1
+ pass_size_unsigned_as1(I);
+}
+
+// This used to cause assertion failures, since we'd try to emit the statement
+// expression (and definitions for `a`) twice.
+// CHECK-LABEL: define void @test17
+void test17(char *C) {
+ // Check for 65535 to see if we're emitting this pointer twice.
+ // CHECK: 65535
+ // CHECK-NOT: 65535
+ // CHECK: @llvm.objectsize.i64.p0i8(i8* [[PTR:%[^,]+]],
+ // CHECK-NOT: 65535
+ // CHECK: call i32 @ObjectSize0(i8* [[PTR]]
+ ObjectSize0(C + ({ int a = 65535; a; }));
+}