|
| 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