|
| 1 | +// 3C no longer has incomplete handling of inline structs behind the -alltypes |
| 2 | +// flag, so we can test compilation with -alltypes as well as without it. |
| 3 | + |
1 | 4 | // RUN: rm -rf %t*
|
2 | 5 | // RUN: 3c -base-dir=%S -alltypes -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_ALL","CHECK" %s
|
| 6 | +// RUN: 3c -base-dir=%S -alltypes -addcr %s -- | %clang -c -fcheckedc-extension -x c -o /dev/null - |
3 | 7 | // RUN: 3c -base-dir=%S -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_NOALL","CHECK" %s
|
4 | 8 | // RUN: 3c -base-dir=%S -addcr %s -- | %clang -c -fcheckedc-extension -x c -o /dev/null -
|
5 | 9 | // RUN: 3c -base-dir=%S -output-dir=%t.checked %s --
|
@@ -168,3 +172,118 @@ void foo2(int *x) {
|
168 | 172 | int *il
|
169 | 173 | } * g, *h, *i;
|
170 | 174 | }
|
| 175 | + |
| 176 | +// Tests of new functionality from |
| 177 | +// https://github.com/correctcomputation/checkedc-clang/pull/657. |
| 178 | +// TODO: Do we want to put this in a separate file? |
| 179 | + |
| 180 | +// Test that 3C doesn't mangle the code by attempting to split a forward |
| 181 | +// declaration of a struct out of a multi-decl as if it were a definition |
| 182 | +// (https://github.com/correctcomputation/checkedc-clang/issues/644). |
| 183 | +struct fwd *p; |
| 184 | +//CHECK: _Ptr<struct fwd> p = ((void *)0); |
| 185 | + |
| 186 | +// Test the handling of inline TagDecls when the containing multi-decl is |
| 187 | +// rewritten: |
| 188 | +// - TagDecls are de-nested in postorder whether or not they were originally |
| 189 | +// named, and this does not interfere with rewrites inside those TagDecls |
| 190 | +// (https://github.com/correctcomputation/checkedc-clang/issues/531). |
| 191 | +// - Storage and type qualifiers preceding an inline TagDecl are not copied to |
| 192 | +// the split TypeDecl (where they wouldn't be meaningful) but remain |
| 193 | +// associated with the fields to which they originally applied |
| 194 | +// (https://github.com/correctcomputation/checkedc-clang/issues/647). |
| 195 | +// - Unnamed TagDecls are automatically named |
| 196 | +// (https://github.com/correctcomputation/checkedc-clang/issues/542). |
| 197 | +// This big combined test may be a bit hard to understand, but it may provide |
| 198 | +// better coverage of any interactions among these features than separate tests |
| 199 | +// would. |
| 200 | + |
| 201 | +// Use up the c_struct_1 name. |
| 202 | +struct c_struct_1 {}; |
| 203 | + |
| 204 | +static struct A { |
| 205 | + const struct B { |
| 206 | + struct { |
| 207 | + int *c2i; |
| 208 | + } *c; |
| 209 | + } *ab, ab_arr[2]; |
| 210 | + volatile struct D { |
| 211 | + struct { |
| 212 | + int *c3i; |
| 213 | + } *c; |
| 214 | + struct E { |
| 215 | + int *ei; |
| 216 | + } *de; |
| 217 | + const enum F { F_0, F_1 } *df; |
| 218 | + enum { G_0, G_1 } *dg; |
| 219 | + struct H { |
| 220 | + int *hi; |
| 221 | + } *dh; |
| 222 | + union U { |
| 223 | + int *ui; |
| 224 | + } *du; |
| 225 | + union { |
| 226 | + int *vi; |
| 227 | + } *dv; |
| 228 | + } *ad; |
| 229 | +} *global_a, global_a_arr[2]; |
| 230 | + |
| 231 | +void constrain_dh(void) { |
| 232 | + struct D d; |
| 233 | + d.dh = (struct H *)1; |
| 234 | +} |
| 235 | + |
| 236 | +// Points of note: |
| 237 | +// - We have two unnamed inline structs that get automatically named after a |
| 238 | +// field `c`, but the name `c_struct_1` is taken, so the names `c_struct_2` |
| 239 | +// and `c_struct_3` are assigned. |
| 240 | +// - All kinds of TagDecls (structs, unions, and enums) can be moved out of a |
| 241 | +// containing struct and automatically named if needed. In principle, 3C |
| 242 | +// should be able to move TagDecls out of a union, but I couldn't find any way |
| 243 | +// to force a union field to be rewritten in order to demonstrate this, since |
| 244 | +// 3C constrains union fields to wild. As far as I know, TagDecls can't be |
| 245 | +// nested in an enum in C. |
| 246 | +// - `struct H` does not get moved because there is nothing to trigger rewriting |
| 247 | +// of the containing multi-decl since `dh` is constrained wild by |
| 248 | +// `constrain_dh`. |
| 249 | + |
| 250 | +//CHECK: struct c_struct_2 { |
| 251 | +//CHECK-NEXT: _Ptr<int> c2i; |
| 252 | +//CHECK-NEXT: }; |
| 253 | +//CHECK-NEXT: struct B { |
| 254 | +//CHECK-NEXT: _Ptr<struct c_struct_2> c; |
| 255 | +//CHECK-NEXT: }; |
| 256 | +//CHECK-NEXT: struct c_struct_3 { |
| 257 | +//CHECK-NEXT: _Ptr<int> c3i; |
| 258 | +//CHECK-NEXT: }; |
| 259 | +//CHECK-NEXT: struct E { |
| 260 | +//CHECK-NEXT: _Ptr<int> ei; |
| 261 | +//CHECK-NEXT: }; |
| 262 | +//CHECK-NEXT: enum F { F_0, F_1 }; |
| 263 | +//CHECK-NEXT: enum dg_enum_1 { G_0, G_1 }; |
| 264 | +//CHECK-NEXT: union U { |
| 265 | +//CHECK-NEXT: int *ui; |
| 266 | +//CHECK-NEXT: }; |
| 267 | +//CHECK-NEXT: union dv_union_1 { |
| 268 | +//CHECK-NEXT: int *vi; |
| 269 | +//CHECK-NEXT: }; |
| 270 | +//CHECK-NEXT: struct D { |
| 271 | +//CHECK-NEXT: _Ptr<struct c_struct_3> c; |
| 272 | +//CHECK-NEXT: _Ptr<struct E> de; |
| 273 | +//CHECK-NEXT: _Ptr<const enum F> df; |
| 274 | +//CHECK-NEXT: _Ptr<enum dg_enum_1> dg; |
| 275 | +//CHECK-NEXT: struct H { |
| 276 | +//CHECK-NEXT: _Ptr<int> hi; |
| 277 | +//CHECK-NEXT: } *dh; |
| 278 | +//CHECK-NEXT: _Ptr<union U> du; |
| 279 | +//CHECK-NEXT: _Ptr<union dv_union_1> dv; |
| 280 | +//CHECK-NEXT: }; |
| 281 | +//CHECK-NEXT: struct A { |
| 282 | +//CHECK-NEXT: _Ptr<const struct B> ab; |
| 283 | +//CHECK_NOALL-NEXT: const struct B ab_arr[2]; |
| 284 | +//CHECK_ALL-NEXT: const struct B ab_arr _Checked[2]; |
| 285 | +//CHECK-NEXT: _Ptr<volatile struct D> ad; |
| 286 | +//CHECK-NEXT: }; |
| 287 | +//CHECK-NEXT: static _Ptr<struct A> global_a = ((void *)0); |
| 288 | +//CHECK_NOALL-NEXT: static struct A global_a_arr[2]; |
| 289 | +//CHECK_ALL-NEXT: static struct A global_a_arr _Checked[2]; |
0 commit comments