blob: db6588dac310ca2eecff9e83645f3a0d4990753b [file] [log] [blame]
Vedant Kumar60b8b692017-03-14 01:56:34 +00001// REQUIRES: asserts
2// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-return,returns-nonnull-attribute,nullability-arg,nonnull-attribute %s -o - -w | FileCheck %s
3
4// If both the annotation and the attribute are present, prefer the attribute,
5// since it actually affects IRGen.
6
7// CHECK-LABEL: define nonnull i32* @f1
8__attribute__((returns_nonnull)) int *_Nonnull f1(int *_Nonnull p) {
9 // CHECK: entry:
Vedant Kumar9766b302017-06-23 21:32:38 +000010 // CHECK-NEXT: [[SLOC_PTR:%.*]] = alloca i8*
Vedant Kumar60b8b692017-03-14 01:56:34 +000011 // CHECK-NEXT: [[ADDR:%.*]] = alloca i32*
Vedant Kumar9766b302017-06-23 21:32:38 +000012 // CHECK-NEXT: store i8* null, i8** [[SLOC_PTR]]
Vedant Kumar60b8b692017-03-14 01:56:34 +000013 // CHECK-NEXT: store i32* [[P:%.*]], i32** [[ADDR]]
Vedant Kumar9766b302017-06-23 21:32:38 +000014 // CHECK-NEXT: store {{.*}} [[SLOC_PTR]]
Vedant Kumar60b8b692017-03-14 01:56:34 +000015 // CHECK-NEXT: [[ARG:%.*]] = load i32*, i32** [[ADDR]]
Vedant Kumar9766b302017-06-23 21:32:38 +000016 // CHECK-NEXT: [[SLOC:%.*]] = load {{.*}} [[SLOC_PTR]]
17 // CHECK-NEXT: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC]], null
18 // CHECK-NEXT: br i1 [[SLOC_NONNULL]], label %nullcheck
19 //
20 // CHECK: nullcheck:
Vedant Kumar60b8b692017-03-14 01:56:34 +000021 // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* [[ARG]], null, !nosanitize
22 // CHECK-NEXT: br i1 [[ICMP]], label %[[CONT:.+]], label %[[HANDLE:[^,]+]]
23 // CHECK: [[HANDLE]]:
Vedant Kumar9766b302017-06-23 21:32:38 +000024 // CHECK: call void @__ubsan_handle_nonnull_return
Vedant Kumar60b8b692017-03-14 01:56:34 +000025 // CHECK-NEXT: unreachable, !nosanitize
26 // CHECK: [[CONT]]:
Vedant Kumar9766b302017-06-23 21:32:38 +000027 // CHECK-NEXT: br label %no.nullcheck
28 // CHECK: no.nullcheck:
29 // CHECK-NEXT: ret i32* [[ARG]]
Vedant Kumar60b8b692017-03-14 01:56:34 +000030 return p;
31}
32
33// CHECK-LABEL: define void @f2
34void f2(int *_Nonnull __attribute__((nonnull)) p) {}
35
36// CHECK-LABEL: define void @call_f2
37void call_f2() {
38 // CHECK: call void @__ubsan_handle_nonnull_arg_abort
39 // CHECK-NOT: call void @__ubsan_handle_nonnull_arg_abort
40 f2((void *)0);
41}
Vedant Kumar9766b302017-06-23 21:32:38 +000042
43// If the return value isn't meant to be checked, make sure we don't check it.
44// CHECK-LABEL: define i32* @f3
45int *f3(int *p) {
46 // CHECK-NOT: return.sloc
47 // CHECK-NOT: call{{.*}}ubsan
48 return p;
49}
50
51// Check for a valid "return" source location, even when there is no return
52// statement, to avoid accidentally calling the runtime.
53
54// CHECK-LABEL: define nonnull i32* @f4
55__attribute__((returns_nonnull)) int *f4() {
56 // CHECK: store i8* null, i8** [[SLOC_PTR:%.*]]
57 // CHECK: [[SLOC:%.*]] = load {{.*}} [[SLOC_PTR]]
58 // CHECK: [[SLOC_NONNULL:%.*]] = icmp ne i8* [[SLOC]], null
59 // CHECK: br i1 [[SLOC_NONNULL]], label %nullcheck
60 // CHECK: nullcheck:
61}