1 // RUN: %clang -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-NO-STRICT %s
2 // RUN: %clang -fstrict-flex-arrays=0 -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-0 %s
3 // RUN: %clang -fstrict-flex-arrays=1 -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-1 %s
4 // RUN: %clang -fstrict-flex-arrays=2 -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-2 %s
5 // RUN: %clang -fstrict-flex-arrays=3 -target x86_64 -O2 -S -emit-llvm %s -o - 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-STRICT-3 %s
6
7 #define OBJECT_SIZE_BUILTIN __builtin_object_size
8
9 typedef struct {
10 float f;
11 double c[];
12 } foo_t;
13
14 typedef struct {
15 float f;
16 double c[0];
17 } foo0_t;
18
19 typedef struct {
20 float f;
21 double c[1];
22 } foo1_t;
23
24 typedef struct {
25 float f;
26 double c[2];
27 } foo2_t;
28
29 // CHECK-LABEL: @bar(
bar(foo_t * f)30 unsigned bar(foo_t *f) {
31 // CHECK-NO-STRICT: ret i32 -1
32 // CHECK-STRICT-0: ret i32 -1
33 // CHECK-STRICT-1: ret i32 -1
34 // CHECK-STRICT-2: ret i32 -1
35 // CHECK-STRICT-3: ret i32 -1
36 return OBJECT_SIZE_BUILTIN(f->c, 1);
37 }
38
39 // CHECK-LABEL: @bar0(
bar0(foo0_t * f)40 unsigned bar0(foo0_t *f) {
41 // CHECK-NO-STRICT: ret i32 -1
42 // CHECK-STRICT-0: ret i32 -1
43 // CHECK-STRICT-1: ret i32 -1
44 // CHECK-STRICT-2: ret i32 -1
45 // CHECK-STRICT-3: ret i32 0
46 return OBJECT_SIZE_BUILTIN(f->c, 1);
47 }
48
49 // CHECK-LABEL: @bar1(
bar1(foo1_t * f)50 unsigned bar1(foo1_t *f) {
51 // CHECK-NO-STRICT: ret i32 -1
52 // CHECK-STRICT-0: ret i32 -1
53 // CHECK-STRICT-1: ret i32 -1
54 // CHECK-STRICT-2: ret i32 8
55 // CHECK-STRICT-3: ret i32 8
56 return OBJECT_SIZE_BUILTIN(f->c, 1);
57 }
58
59 // CHECK-LABEL: @bar2(
bar2(foo2_t * f)60 unsigned bar2(foo2_t *f) {
61 // CHECK-NO-STRICT: ret i32 -1
62 // CHECK-STRICT-0: ret i32 -1
63 // CHECK-STRICT-1: ret i32 16
64 // CHECK-STRICT-2: ret i32 16
65 // CHECK-STRICT-3: ret i32 16
66 return OBJECT_SIZE_BUILTIN(f->c, 1);
67 }
68
69 #define DYNAMIC_OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
70
71 // CHECK-LABEL: @dyn_bar(
dyn_bar(foo_t * f)72 unsigned dyn_bar(foo_t *f) {
73 // CHECK-NO-STRICT: ret i32 -1
74 // CHECK-STRICT-0: ret i32 -1
75 // CHECK-STRICT-1: ret i32 -1
76 // CHECK-STRICT-2: ret i32 -1
77 // CHECK-STRICT-3: ret i32 -1
78 return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1);
79 }
80
81 // CHECK-LABEL: @dyn_bar0(
dyn_bar0(foo0_t * f)82 unsigned dyn_bar0(foo0_t *f) {
83 // CHECK-NO-STRICT: ret i32 -1
84 // CHECK-STRICT-0: ret i32 -1
85 // CHECK-STRICT-1: ret i32 -1
86 // CHECK-STRICT-2: ret i32 -1
87 // CHECK-STRICT-3: ret i32 0
88 return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1);
89 }
90
91 // CHECK-LABEL: @dyn_bar1(
dyn_bar1(foo1_t * f)92 unsigned dyn_bar1(foo1_t *f) {
93 // CHECK-NO-STRICT: ret i32 -1
94 // CHECK-STRICT-0: ret i32 -1
95 // CHECK-STRICT-1: ret i32 -1
96 // CHECK-STRICT-2: ret i32 8
97 // CHECK-STRICT-3: ret i32 8
98 return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1);
99 }
100
101 // CHECK-LABEL: @dyn_bar2(
dyn_bar2(foo2_t * f)102 unsigned dyn_bar2(foo2_t *f) {
103 // CHECK-NO-STRICT: ret i32 -1
104 // CHECK-STRICT-0: ret i32 -1
105 // CHECK-STRICT-1: ret i32 16
106 // CHECK-STRICT-2: ret i32 16
107 // CHECK-STRICT-3: ret i32 16
108 return DYNAMIC_OBJECT_SIZE_BUILTIN(f->c, 1);
109 }
110
111 // Also checks for non-trailing flex-array like members
112
113 typedef struct {
114 double c[0];
115 float f;
116 } foofoo0_t;
117
118 typedef struct {
119 double c[1];
120 float f;
121 } foofoo1_t;
122
123 typedef struct {
124 double c[2];
125 float f;
126 } foofoo2_t;
127
128 // CHECK-LABEL: @babar0(
babar0(foofoo0_t * f)129 unsigned babar0(foofoo0_t *f) {
130 // CHECK-NO-STRICT: ret i32 0
131 // CHECK-STRICT-0: ret i32 0
132 // CHECK-STRICT-1: ret i32 0
133 // CHECK-STRICT-2: ret i32 0
134 // CHECK-STRICT-3: ret i32 0
135 return OBJECT_SIZE_BUILTIN(f->c, 1);
136 }
137
138 // CHECK-LABEL: @babar1(
babar1(foofoo1_t * f)139 unsigned babar1(foofoo1_t *f) {
140 // CHECK-NO-STRICT: ret i32 8
141 // CHECK-STRICT-0: ret i32 8
142 // CHECK-STRICT-1: ret i32 8
143 // CHECK-STRICT-2: ret i32 8
144 // CHECK-STRICT-3: ret i32 8
145 return OBJECT_SIZE_BUILTIN(f->c, 1);
146 }
147
148 // CHECK-LABEL: @babar2(
babar2(foofoo2_t * f)149 unsigned babar2(foofoo2_t *f) {
150 // CHECK-NO-STRICT: ret i32 16
151 // CHECK-STRICT-0: ret i32 16
152 // CHECK-STRICT-1: ret i32 16
153 // CHECK-STRICT-2: ret i32 16
154 // CHECK-STRICT-3: ret i32 16
155 return OBJECT_SIZE_BUILTIN(f->c, 1);
156 }
157