1 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s 2 3 void p2unsigned(unsigned **ptr) { 4 // CHECK-LABEL: define void @p2unsigned(i32** noundef %ptr) 5 // CHECK-NEXT: entry: 6 // CHECK-NEXT: %ptr.addr = alloca i32**, align 8 7 // CHECK-NEXT: store i32** %ptr, i32*** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0:!.+]] 8 // CHECK-NEXT: [[BASE:%.+]] = load i32**, i32*** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 9 // CHECK-NEXT: store i32* null, i32** [[BASE]], align 8, !tbaa [[ANY_POINTER_0]] 10 // CHECK-NEXT: ret void 11 // 12 *ptr = 0; 13 } 14 15 void p2unsigned_volatile(unsigned *volatile *ptr) { 16 // CHECK-LABEL: define void @p2unsigned_volatile(i32** noundef %ptr) 17 // CHECK-NEXT: entry: 18 // CHECK-NEXT: %ptr.addr = alloca i32**, align 8 19 // CHECK-NEXT: store i32** %ptr, i32*** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 20 // CHECK-NEXT: [[BASE:%.+]] = load i32**, i32*** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 21 // CHECK-NEXT: store volatile i32* null, i32** [[BASE]], align 8, !tbaa [[ANY_POINTER_0]] 22 // CHECK-NEXT: ret void 23 // 24 *ptr = 0; 25 } 26 27 void p3int(int ***ptr) { 28 // CHECK-LABEL: define void @p3int(i32*** noundef %ptr) 29 // CHECK-NEXT: entry: 30 // CHECK-NEXT: %ptr.addr = alloca i32***, align 8 31 // CHECK-NEXT: store i32*** %ptr, i32**** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 32 // CHECK-NEXT: [[BASE_0:%.+]] = load i32***, i32**** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 33 // CHECK-NEXT: [[BASE_1:%.+]] = load i32**, i32*** [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]] 34 // CHECK-NEXT: store i32* null, i32** [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]] 35 // CHECK-NEXT: ret void 36 // 37 **ptr = 0; 38 } 39 40 void p4char(char ****ptr) { 41 // CHECK-LABEL: define void @p4char(i8**** noundef %ptr) 42 // CHECK-NEXT: entry: 43 // CHECK-NEXT: %ptr.addr = alloca i8****, align 8 44 // CHECK-NEXT: store i8**** %ptr, i8***** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 45 // CHECK-NEXT: [[BASE_0:%.+]] = load i8****, i8***** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 46 // CHECK-NEXT: [[BASE_1:%.+]] = load i8***, i8**** [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]] 47 // CHECK-NEXT: [[BASE_2:%.+]] = load i8**, i8*** [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]] 48 // CHECK-NEXT: store i8* null, i8** [[BASE_2]], align 8, !tbaa [[ANY_POINTER_0]] 49 // CHECK-NEXT: ret void 50 // 51 ***ptr = 0; 52 } 53 54 void p4char_const1(const char ****ptr) { 55 // CHECK-LABEL: define void @p4char_const1(i8**** noundef %ptr) 56 // CHECK-NEXT: entry: 57 // CHECK-NEXT: %ptr.addr = alloca i8****, align 8 58 // CHECK-NEXT: store i8**** %ptr, i8***** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 59 // CHECK-NEXT: [[BASE_0:%.+]] = load i8****, i8***** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 60 // CHECK-NEXT: [[BASE_1:%.+]] = load i8***, i8**** [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]] 61 // CHECK-NEXT: [[BASE_2:%.+]] = load i8**, i8*** [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]] 62 // CHECK-NEXT: store i8* null, i8** [[BASE_2]], align 8, !tbaa [[ANY_POINTER_0]] 63 // CHECK-NEXT: ret void 64 // 65 ***ptr = 0; 66 } 67 68 void p4char_const2(const char **const **ptr) { 69 // CHECK-LABEL: define void @p4char_const2(i8**** noundef %ptr) 70 // CHECK-NEXT: entry: 71 // CHECK-NEXT: %ptr.addr = alloca i8****, align 8 72 // CHECK-NEXT: store i8**** %ptr, i8***** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 73 // CHECK-NEXT: [[BASE_0:%.+]] = load i8****, i8***** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 74 // CHECK-NEXT: [[BASE_1:%.+]] = load i8***, i8**** [[BASE_0]], align 8, !tbaa [[ANY_POINTER_0]] 75 // CHECK-NEXT: [[BASE_2:%.+]] = load i8**, i8*** [[BASE_1]], align 8, !tbaa [[ANY_POINTER_0]] 76 // CHECK-NEXT: store i8* null, i8** [[BASE_2]], align 8, !tbaa [[ANY_POINTER_0]] 77 // CHECK-NEXT: ret void 78 // 79 ***ptr = 0; 80 } 81 82 struct S1 { 83 int x; 84 int y; 85 }; 86 87 void p2struct(struct S1 **ptr) { 88 // CHECK-LABEL: define void @p2struct(%struct.S1** noundef %ptr) 89 // CHECK-NEXT: entry: 90 // CHECK-NEXT: %ptr.addr = alloca %struct.S1**, align 8 91 // CHECK-NEXT: store %struct.S1** %ptr, %struct.S1*** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 92 // CHECK-NEXT: [[BASE:%.+]] = load %struct.S1**, %struct.S1*** %ptr.addr, align 8, !tbaa [[ANY_POINTER_0]] 93 // CHECK-NEXT: store %struct.S1* null, %struct.S1** [[BASE]], align 8, !tbaa [[ANY_POINTER_0]] 94 // CHECK-NEXT: ret void 95 // 96 *ptr = 0; 97 } 98 99 // CHECK: [[ANY_POINTER_0]] = !{[[ANY_POINTER:!.+]], [[ANY_POINTER]], i64 0} 100 // CHECK: [[ANY_POINTER]] = !{!"any pointer", [[CHAR:!.+]], i64 0} 101 // CHECK: [[CHAR]] = !{!"omnipotent char", [[TBAA_ROOT:!.+]], i64 0} 102 // CHECK: [[TBAA_ROOT]] = !{!"Simple C/C++ TBAA"} 103 // 104