1 // RUN: %clang -fstrict-flex-arrays=3 -target x86_64-apple-darwin -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-3 %s
2 // RUN: %clang -fstrict-flex-arrays=2 -target x86_64-apple-darwin -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-2 %s
3 // RUN: %clang -fstrict-flex-arrays=1 -target x86_64-apple-darwin -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-1 %s
4 // RUN: %clang -fstrict-flex-arrays=0 -target x86_64-apple-darwin -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-0 %s
5 
6 #define OBJECT_SIZE_BUILTIN __builtin_object_size
7 
8 typedef struct {
9   float f;
10   double c[];
11 } foo_t;
12 
13 typedef struct {
14   float f;
15   double c[0];
16 } foo0_t;
17 
18 typedef struct {
19   float f;
20   double c[1];
21 } foo1_t;
22 
23 typedef struct {
24   float f;
25   double c[2];
26 } foo2_t;
27 
28 // CHECK-LABEL: @bar
29 unsigned bar(foo_t *f) {
30   // CHECK-STRICT-0: ret i32 %
31   // CHECK-STRICT-1: ret i32 %
32   // CHECK-STRICT-2: ret i32 %
33   // CHECK-STRICT-3: ret i32 %
34   return OBJECT_SIZE_BUILTIN(f->c, 1);
35 }
36 
37 // CHECK-LABEL: @bar0
38 unsigned bar0(foo0_t *f) {
39   // CHECK-STRICT-0: ret i32 %
40   // CHECK-STRICT-1: ret i32 %
41   // CHECK-STRICT-2: ret i32 %
42   // CHECK-STRICT-3: ret i32 0
43   return OBJECT_SIZE_BUILTIN(f->c, 1);
44 }
45 
46 // CHECK-LABEL: @bar1
47 unsigned bar1(foo1_t *f) {
48   // CHECK-STRICT-0: ret i32 %
49   // CHECK-STRICT-1: ret i32 %
50   // CHECK-STRICT-2: ret i32 8
51   // CHECK-STRICT-3: ret i32 8
52   return OBJECT_SIZE_BUILTIN(f->c, 1);
53 }
54 
55 // CHECK-LABEL: @bar2
56 unsigned bar2(foo2_t *f) {
57   // CHECK-STRICT-0: ret i32 %
58   // CHECK-STRICT-1: ret i32 16
59   // CHECK-STRICT-2: ret i32 16
60   // CHECK-STRICT-3: ret i32 16
61   return OBJECT_SIZE_BUILTIN(f->c, 1);
62 }
63 
64 // Also checks for non-trailing flex-array like members
65 
66 typedef struct {
67   double c[0];
68   float f;
69 } foofoo0_t;
70 
71 typedef struct {
72   double c[1];
73   float f;
74 } foofoo1_t;
75 
76 typedef struct {
77   double c[2];
78   float f;
79 } foofoo2_t;
80 
81 // CHECK-LABEL: @babar0
82 unsigned babar0(foofoo0_t *f) {
83   // CHECK-STRICT-0: ret i32 0
84   // CHECK-STRICT-1: ret i32 0
85   // CHECK-STRICT-2: ret i32 0
86   // CHECK-STRICT-3: ret i32 0
87   return OBJECT_SIZE_BUILTIN(f->c, 1);
88 }
89 
90 // CHECK-LABEL: @babar1
91 unsigned babar1(foofoo1_t *f) {
92   // CHECK-STRICT-0: ret i32 8
93   // CHECK-STRICT-1: ret i32 8
94   // CHECK-STRICT-2: ret i32 8
95   // CHECK-STRICT-3: ret i32 8
96   return OBJECT_SIZE_BUILTIN(f->c, 1);
97 }
98 
99 // CHECK-LABEL: @babar2
100 unsigned babar2(foofoo2_t *f) {
101   // CHECK-STRICT-0: ret i32 16
102   // CHECK-STRICT-1: ret i32 16
103   // CHECK-STRICT-2: ret i32 16
104   // CHECK-STRICT-3: ret i32 16
105   return OBJECT_SIZE_BUILTIN(f->c, 1);
106 }
107