Skip to content

Commit eea9b94

Browse files
Add test of automatic struct naming with multiple translation units.
1 parent 5ed5ad3 commit eea9b94

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

clang/test/3C/inline_anon_structs.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ struct {
122122
//CHECK_ALL: };
123123
//CHECK_ALL-NEXT: _Ptr<struct be_struct_1> be _Checked[4] = {((void *)0)};
124124

125+
// The following is explained in second_tu_fn in inline_anon_structs_cross_tu.c.
126+
struct { int x; } *cross_tu_numbering_test;
127+
//CHECK_AB: struct cross_tu_numbering_test_struct_1 { int x; };
128+
//CHECK_AB-NEXT: _Ptr<struct cross_tu_numbering_test_struct_1> cross_tu_numbering_test = ((void *)0);
129+
//CHECK_BA: struct cross_tu_numbering_test_struct_2 { int x; };
130+
//CHECK_BA-NEXT: _Ptr<struct cross_tu_numbering_test_struct_2> cross_tu_numbering_test = ((void *)0);
131+
125132
/*this code checks inline structs withiin functions*/
126133
void foo2(int *x) {
127134
//CHECK: void foo2(_Ptr<int> x) _Checked {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Regression tests for two bugs seen during the development of
2+
// https://github.com/correctcomputation/checkedc-clang/pull/657 with multiple
3+
// translation units: some information about automatically named TagDecls was
4+
// not propagated across translation units.
5+
//
6+
// Our translation units are inline_anon_structs.c and
7+
// inline_anon_structs_cross_tu.c; the latter `#include`s the former and has
8+
// some code of its own. So inline_anon_structs.c effectively plays the role of
9+
// a shared header file, but we just use the .c file instead of moving the code
10+
// to a .h file and making another .c file that does nothing but `#include` the
11+
// .h file.
12+
//
13+
// We test 3C on both orders of the translation units. Remember that when the
14+
// same file is rewritten as part of multiple translation units, the last
15+
// translation unit wins
16+
// (https://github.com/correctcomputation/checkedc-clang/issues/374#issuecomment-804283984).
17+
// So the "inline_anon_structs.c, inline_anon_structs_cross_tu.c" order should
18+
// catch most problems that occur when 3C makes the decisions in one translation
19+
// unit but does the rewriting in another. We still test the other order for
20+
// completeness.
21+
22+
// RUN: rm -rf %t*
23+
24+
// Tests of the "inline_anon_structs.c, inline_anon_structs_cross_tu.c" order
25+
// (called "AB" for short).
26+
//
27+
// Note about check prefixes: We currently don't bother with a Cartesian product
28+
// of {ALL,NOALL} x {AB,BA} because we don't have any tests whose results depend
29+
// on both variables. We do pass CHECK_NOALL and CHECK_ALL to
30+
// inline_anon_structs_cross_tu.c for uniformity, even though that file
31+
// currently doesn't use either.
32+
//
33+
// RUN: 3c -base-dir=%S -addcr -alltypes -output-dir=%t.checkedALL_AB %S/inline_anon_structs.c %s --
34+
// RUN: FileCheck -match-full-lines -check-prefixes="CHECK_ALL","CHECK","CHECK_AB" --input-file %t.checkedALL_AB/inline_anon_structs.c %S/inline_anon_structs.c
35+
// RUN: FileCheck -match-full-lines -check-prefixes="CHECK_ALL","CHECK","CHECK_AB" --input-file %t.checkedALL_AB/inline_anon_structs_cross_tu.c %s
36+
// RUN: 3c -base-dir=%S -addcr -output-dir=%t.checkedNOALL_AB %S/inline_anon_structs.c %s --
37+
// RUN: FileCheck -match-full-lines -check-prefixes="CHECK_NOALL","CHECK","CHECK_AB" --input-file %t.checkedNOALL_AB/inline_anon_structs.c %S/inline_anon_structs.c
38+
// RUN: FileCheck -match-full-lines -check-prefixes="CHECK_NOALL","CHECK","CHECK_AB" --input-file %t.checkedNOALL_AB/inline_anon_structs_cross_tu.c %s
39+
40+
// Tests of the "inline_anon_structs_cross_tu.c, inline_anon_structs.c" order
41+
// (called "BA").
42+
//
43+
// RUN: 3c -base-dir=%S -addcr -alltypes -output-dir=%t.checkedALL_BA %s %S/inline_anon_structs.c --
44+
// RUN: FileCheck -match-full-lines -check-prefixes="CHECK_ALL","CHECK","CHECK_BA" --input-file %t.checkedALL_BA/inline_anon_structs.c %S/inline_anon_structs.c
45+
// RUN: FileCheck -match-full-lines -check-prefixes="CHECK_ALL","CHECK","CHECK_BA" --input-file %t.checkedALL_BA/inline_anon_structs_cross_tu.c %s
46+
// RUN: 3c -base-dir=%S -addcr -output-dir=%t.checkedNOALL_BA %s %S/inline_anon_structs.c --
47+
// RUN: FileCheck -match-full-lines -check-prefixes="CHECK_NOALL","CHECK","CHECK_BA" --input-file %t.checkedNOALL_BA/inline_anon_structs.c %S/inline_anon_structs.c
48+
// RUN: FileCheck -match-full-lines -check-prefixes="CHECK_NOALL","CHECK","CHECK_BA" --input-file %t.checkedNOALL_BA/inline_anon_structs_cross_tu.c %s
49+
50+
void second_tu_fn(void) {
51+
// In the AB order, the global `cross_tu_numbering_test` variable in
52+
// inline_anon_structs.c will be seen first and its struct will be named
53+
// cross_tu_numbering_test_struct_1, and this struct will be named
54+
// cross_tu_numbering_test_struct_2. In the BA order, this code is seen before
55+
// the `#include "inline_anon_structs.c"`, so this struct will take the
56+
// cross_tu_numbering_test_struct_1 name and the inline_anon_structs.c one
57+
// will be cross_tu_numbering_test_struct_2.
58+
//
59+
// Note that in order to have two different variables with the same name (in
60+
// order to produce a collision in struct names), we have to put the variables
61+
// in different scopes: in this case, global and function-local.
62+
struct { int y; } *cross_tu_numbering_test;
63+
//CHECK_AB: struct cross_tu_numbering_test_struct_2 { int y; };
64+
//CHECK_AB-NEXT: _Ptr<struct cross_tu_numbering_test_struct_2> cross_tu_numbering_test = ((void *)0);
65+
//CHECK_BA: struct cross_tu_numbering_test_struct_1 { int y; };
66+
//CHECK_BA-NEXT: _Ptr<struct cross_tu_numbering_test_struct_1> cross_tu_numbering_test = ((void *)0);
67+
}
68+
69+
#include "inline_anon_structs.c"

0 commit comments

Comments
 (0)