1 // RUN: %clang_cc1 -Wno-int-conversion -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,NULL-INVALID 2 // RUN: %clang_cc1 -Wno-int-conversion -triple i386-unknown-unknown %s -emit-llvm -fno-delete-null-pointer-checks -o - | FileCheck %s -check-prefixes=CHECK,NULL-VALID 3 4 int b(char* x); 5 6 // Extremely basic VLA test 7 void a(int x) { 8 char arry[x]; 9 arry[0] = 10; 10 b(arry); 11 } 12 13 int c(int n) 14 { 15 return sizeof(int[n]); 16 } 17 18 int f0(int x) { 19 int vla[x]; 20 return vla[x-1]; 21 } 22 23 void 24 f(int count) 25 { 26 int a[count]; 27 28 do { } while (0); 29 30 if (a[0] != 3) { 31 } 32 } 33 34 void g(int count) { 35 // Make sure we emit sizes correctly in some obscure cases 36 int (*a[5])[count]; 37 int (*b)[][count]; 38 } 39 40 // CHECK-LABEL: define{{.*}} void @f_8403108 41 void f_8403108(unsigned x) { 42 // CHECK: call ptr @llvm.stacksave.p0() 43 char s1[x]; 44 while (1) { 45 // CHECK: call ptr @llvm.stacksave.p0() 46 char s2[x]; 47 if (1) 48 break; 49 // CHECK: call void @llvm.stackrestore.p0(ptr 50 } 51 // CHECK: call void @llvm.stackrestore.p0(ptr 52 } 53 54 // pr7827 55 void function(short width, int data[][width]) {} // expected-note {{passing argument to parameter 'data' here}} 56 57 void test(void) { 58 int bork[4][13]; 59 // CHECK: call void @function(i16 noundef signext 1, ptr noundef null) 60 function(1, 0); 61 // CHECK: call void @function(i16 noundef signext 1, ptr noundef inttoptr 62 function(1, 0xbadbeef); // expected-warning {{incompatible integer to pointer conversion passing}} 63 // CHECK: call void @function(i16 noundef signext 1, ptr noundef {{.*}}) 64 function(1, bork); 65 } 66 67 void function1(short width, int data[][width][width]) {} 68 void test1(void) { 69 int bork[4][13][15]; 70 // CHECK: call void @function1(i16 noundef signext 1, ptr noundef {{.*}}) 71 function1(1, bork); 72 // CHECK: call void @function(i16 noundef signext 1, ptr noundef {{.*}}) 73 function(1, bork[2]); 74 } 75 76 static int GLOB; 77 int test2(int n) 78 { 79 GLOB = 0; 80 char b[1][n+3]; /* Variable length array. */ 81 // CHECK: [[tmp_1:%.*]] = load i32, ptr @GLOB, align 4 82 // CHECK-NEXT: add nsw i32 [[tmp_1]], 1 83 __typeof__(b[GLOB++]) c; 84 return GLOB; 85 } 86 87 // http://llvm.org/PR8567 88 // CHECK-LABEL: define{{.*}} double @test_PR8567 89 double test_PR8567(int n, double (*p)[n][5]) { 90 // CHECK: [[NV:%.*]] = alloca i32, align 4 91 // CHECK-NEXT: [[PV:%.*]] = alloca ptr, align 4 92 // CHECK-NEXT: store 93 // CHECK-NEXT: store 94 // CHECK-NEXT: [[N:%.*]] = load i32, ptr [[NV]], align 4 95 // CHECK-NEXT: [[P:%.*]] = load ptr, ptr [[PV]], align 4 96 // CHECK-NEXT: [[T0:%.*]] = mul nsw i32 1, [[N]] 97 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [5 x double], ptr [[P]], i32 [[T0]] 98 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [5 x double], ptr [[T1]], i32 2 99 // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [5 x double], ptr [[T2]], i32 0, i32 3 100 // CHECK-NEXT: [[T4:%.*]] = load double, ptr [[T3]] 101 // CHECK-NEXT: ret double [[T4]] 102 return p[1][2][3]; 103 } 104 105 int test4(unsigned n, char (*p)[n][n+1][6]) { 106 // CHECK-LABEL: define{{.*}} i32 @test4( 107 // CHECK: [[N:%.*]] = alloca i32, align 4 108 // CHECK-NEXT: [[P:%.*]] = alloca ptr, align 4 109 // CHECK-NEXT: [[P2:%.*]] = alloca ptr, align 4 110 // CHECK-NEXT: store i32 111 // CHECK-NEXT: store ptr 112 113 // VLA captures. 114 // CHECK-NEXT: [[DIM0:%.*]] = load i32, ptr [[N]], align 4 115 // CHECK-NEXT: [[T0:%.*]] = load i32, ptr [[N]], align 4 116 // CHECK-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1 117 118 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[P]], align 4 119 // CHECK-NEXT: [[T1:%.*]] = load i32, ptr [[N]], align 4 120 // CHECK-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2 121 // CHECK-NEXT: [[T3:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] 122 // CHECK-NEXT: [[T4:%.*]] = mul nsw i32 [[T2]], [[T3]] 123 // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds nuw [6 x i8], ptr [[T0]], i32 [[T4]] 124 // CHECK-NEXT: [[T6:%.*]] = load i32, ptr [[N]], align 4 125 // CHECK-NEXT: [[T7:%.*]] = udiv i32 [[T6]], 4 126 // CHECK-NEXT: [[T8:%.*]] = sub i32 0, [[T7]] 127 // CHECK-NEXT: [[T9:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] 128 // CHECK-NEXT: [[T10:%.*]] = mul nsw i32 [[T8]], [[T9]] 129 // CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds [6 x i8], ptr [[T5]], i32 [[T10]] 130 // CHECK-NEXT: store ptr [[T11]], ptr [[P2]], align 4 131 __typeof(p) p2 = (p + n/2) - n/4; 132 133 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[P2]], align 4 134 // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[P]], align 4 135 // CHECK-NEXT: [[T2:%.*]] = ptrtoint ptr [[T0]] to i32 136 // CHECK-NEXT: [[T3:%.*]] = ptrtoint ptr [[T1]] to i32 137 // CHECK-NEXT: [[T4:%.*]] = sub i32 [[T2]], [[T3]] 138 // CHECK-NEXT: [[T5:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]] 139 // CHECK-NEXT: [[T6:%.*]] = mul nuw i32 6, [[T5]] 140 // CHECK-NEXT: [[T7:%.*]] = sdiv exact i32 [[T4]], [[T6]] 141 // CHECK-NEXT: ret i32 [[T7]] 142 return p2 - p; 143 } 144 145 void test5(void) 146 { 147 // CHECK-LABEL: define{{.*}} void @test5( 148 int a[5], i = 0; 149 // CHECK: [[A:%.*]] = alloca [5 x i32], align 4 150 // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 151 // CHECK-NEXT: [[CL:%.*]] = alloca ptr, align 4 152 // CHECK-NEXT: store i32 0, ptr [[I]], align 4 153 154 (typeof(++i, (int (*)[i])a)){&a} += 0; 155 // CHECK-NEXT: [[Z:%.*]] = load i32, ptr [[I]], align 4 156 // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Z]], 1 157 // CHECK-NEXT: store i32 [[INC]], ptr [[I]], align 4 158 // CHECK-NEXT: [[O:%.*]] = load i32, ptr [[I]], align 4 159 // CHECK-NEXT: [[AR:%.*]] = getelementptr inbounds [5 x i32], ptr [[A]], i32 0, i32 0 160 // CHECK-NEXT: store ptr [[A]], ptr [[CL]] 161 // CHECK-NEXT: [[TH:%.*]] = load ptr, ptr [[CL]] 162 // CHECK-NEXT: [[VLAIX:%.*]] = mul nsw i32 0, [[O]] 163 // CHECK-NEXT: [[ADDPTR:%.*]] = getelementptr inbounds i32, ptr [[TH]], i32 [[VLAIX]] 164 // CHECK-NEXT: store ptr [[ADDPTR]], ptr [[CL]] 165 } 166 167 void test6(void) 168 { 169 // CHECK-LABEL: define{{.*}} void @test6( 170 int n = 20, **a, i=0; 171 // CHECK: [[N:%.*]] = alloca i32, align 4 172 // CHECK-NEXT: [[A:%.*]] = alloca ptr, align 4 173 // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 174 (int (**)[i]){&a}[0][1][5] = 0; 175 // CHECK-NEXT: [[CL:%.*]] = alloca ptr, align 4 176 // CHECK-NEXT: store i32 20, ptr [[N]], align 4 177 // CHECK-NEXT: store i32 0, ptr [[I]], align 4 178 // CHECK-NEXT: [[Z:%.*]] = load i32, ptr [[I]], align 4 179 // CHECK-NEXT: store ptr [[A]], ptr [[CL]] 180 // CHECK-NEXT: [[T:%.*]] = load ptr, ptr [[CL]] 181 // CHECK-NEXT: [[IX:%.*]] = getelementptr inbounds ptr, ptr [[T]], i32 0 182 // CHECK-NEXT: [[TH:%.*]] = load ptr, ptr [[IX]], align 4 183 // CHECK-NEXT: [[F:%.*]] = mul nsw i32 1, [[Z]] 184 // CHECK-NEXT: [[IX1:%.*]] = getelementptr inbounds i32, ptr [[TH]], i32 [[F]] 185 // CHECK-NEXT: [[IX2:%.*]] = getelementptr inbounds i32, ptr [[IX1]], i32 5 186 // CHECK-NEXT: store i32 0, ptr [[IX2]], align 4 187 } 188 189 // Follow gcc's behavior for VLAs in parameter lists. PR9559. 190 void test7(int a[b(0)]) { 191 // CHECK-LABEL: define{{.*}} void @test7( 192 // CHECK: call i32 @b(ptr noundef null) 193 } 194 195 // Make sure we emit dereferenceable or nonnull when the static keyword is 196 // provided. 197 void test8(int a[static 3]) { } 198 // CHECK: define{{.*}} void @test8(ptr noundef align 4 dereferenceable(12) %a) 199 200 void test9(int n, int a[static n]) { } 201 // NULL-INVALID: define{{.*}} void @test9(i32 noundef %n, ptr noundef nonnull align 4 %a) 202 // NULL-VALID: define{{.*}} void @test9(i32 noundef %n, ptr noundef align 4 %a) 203 204 // Make sure a zero-sized static array extent is still required to be nonnull. 205 void test10(int a[static 0]) {} 206 // NULL-INVALID: define{{.*}} void @test10(ptr noundef nonnull align 4 %a) 207 // NULL-VALID: define{{.*}} void @test10(ptr noundef align 4 %a) 208 209 const int constant = 32; 210 // CHECK: define {{.*}}pr44406( 211 int pr44406(void) { 212 int n = 0; 213 // Do not fold this VLA to an array of constant bound; that would miscompile 214 // this testcase. 215 char c[1][(constant - constant) + 3]; 216 // CHECK: store i32 1, 217 sizeof(c[n = 1]); 218 return n; 219 } 220