xref: /llvm-project/clang/test/CodeGen/object-size-flex-array.c (revision 7f93ae808634e33e4dc9bce753c909aa5f9a6eb4)
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