Skip to content

Commit 0bbfe7f

Browse files
Avoid duplicate code in multivardecls.c and itypes_for_extern.c.
1 parent ab2d1a5 commit 0bbfe7f

File tree

3 files changed

+114
-105
lines changed

3 files changed

+114
-105
lines changed

clang/test/3C/itypes_for_extern.c

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ void has_itype1(int *a : itype(_Ptr<int>)) { a = 0; }
9494
// part of the type (the array size) occurs after the name of the variable
9595
// being declared. This complicates rewriting. These examples caused errors in
9696
// libjpeg.
97+
//
98+
// multivardecls_complex_types.c has tests of some similar cases as part of
99+
// multi-decls, with and without -itypes-for-extern.
97100

98101
int const_arr0[10];
99102
//CHECK_ALL: int const_arr0[10] : itype(int _Checked[10]);
@@ -107,38 +110,6 @@ int (*const_arr2)[10];
107110
//CHECK_ALL: int (*const_arr2)[10] : itype(_Ptr<int _Checked[10]>) = ((void *)0);
108111
//CHECK_NOALL: int (*const_arr2)[10] : itype(_Ptr<int[10]>) = ((void *)0);
109112

110-
// Two tests similar to the above but involving multi-decls. These have
111-
// corresponding tests without -itypes-for-extern in multivardecls.c; see the
112-
// comments there.
113-
114-
int m_const_arr0[10], *m_const_arr1[10], (*m_const_arr2)[10],
115-
*m_implicit_itype : count(2), **m_change_with_bounds : count(2);
116-
//CHECK_ALL: int m_const_arr0[10] : itype(int _Checked[10]);
117-
//CHECK_NOALL: int m_const_arr0[10];
118-
//CHECK_ALL: int *m_const_arr1[10] : itype(_Ptr<int> _Checked[10]) = {((void *)0)};
119-
//CHECK_NOALL: int *m_const_arr1[10];
120-
//CHECK_ALL: int (*m_const_arr2)[10] : itype(_Ptr<int _Checked[10]>) = ((void *)0);
121-
//CHECK_NOALL: int (*m_const_arr2)[10] : itype(_Ptr<int[10]>) = ((void *)0);
122-
//CHECK: int *m_implicit_itype : count(2);
123-
//CHECK: int **m_change_with_bounds : itype(_Array_ptr<_Ptr<int>>) count(2) = ((void *)0);
124-
125-
struct { int *x; } s, *s_force_rewrite, s_const_arr0[10], *s_const_arr1[10],
126-
*s_implicit_itype : count(2), **s_change_with_bounds : count(2);
127-
//CHECK: struct s_struct_1 { int *x : itype(_Ptr<int>); };
128-
//CHECK: struct s_struct_1 s;
129-
//CHECK: struct s_struct_1 *s_force_rewrite : itype(_Ptr<struct s_struct_1>) = ((void *)0);
130-
//CHECK_ALL: struct s_struct_1 s_const_arr0[10] : itype(struct s_struct_1 _Checked[10]);
131-
//CHECK_NOALL: struct s_struct_1 s_const_arr0[10];
132-
//CHECK_ALL: struct s_struct_1 *s_const_arr1[10] : itype(_Ptr<struct s_struct_1> _Checked[10]) = {((void *)0)};
133-
//CHECK_NOALL: struct s_struct_1 *s_const_arr1[10];
134-
// As in the corresponding test in multivardecls.c, the type of s_implicit_type
135-
// is loaded as _Array_ptr<struct s_struct_1>, but it is downgraded back to an
136-
// itype by -itypes-for-extern. As long as 3C lacks real support for itypes on
137-
// variables, this is probably the behavior we want with -itypes-for-extern in
138-
// this very unusual case.
139-
//CHECK: struct s_struct_1 *s_implicit_itype : itype(_Array_ptr<struct s_struct_1>) count(2);
140-
//CHECK: struct s_struct_1 **s_change_with_bounds : itype(_Array_ptr<_Ptr<struct s_struct_1>>) count(2) = ((void *)0);
141-
142113
// Itypes for constants sized arrays when there is a declaration with and
143114
// without a parameter list take slightly different paths that need to be
144115
// tested. If there is no parameter list, then the unchecked component of the
@@ -152,8 +123,8 @@ void const_arr_fn(int a[10]) {}
152123

153124
// Rewriting an existing itype or bounds expression on a global variable. Doing
154125
// this correctly requires replacing text until the end of the Checked C
155-
// annotation expression. The m_* and s_* tests above test some similar cases in
156-
// combination with multi-decls.
126+
// annotation expression. The m_* and s_* tests in multivardecls_complex_types.c
127+
// test some similar cases in combination with multi-decls.
157128
int *a : itype(_Ptr<int>);
158129
int **b : itype(_Ptr<int *>);
159130
int *c : count(2);

clang/test/3C/multivardecls.c

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -164,77 +164,6 @@ void test6() {
164164
// CHECK: _Ptr<int> d;
165165
// CHECK: };
166166

167-
// The next two tests have corresponding tests with -itypes-for-extern in
168-
// itypes_for_extern.c.
169-
// REVIEW: Should we put all these tests in one file? We would need a ton of
170-
// different CHECK prefixes. I don't know whether that would end up being easier
171-
// or harder to understand.
172-
173-
// A multi-decl with a mix of pointers and arrays, including an "unchecked
174-
// pointer to constant size array" member that would trigger a known bug in
175-
// mkString (item 5 of
176-
// https://github.com/correctcomputation/checkedc-clang/issues/703),
177-
// demonstrating that unchanged multi-decl members whose base type wasn't
178-
// renamed use Decl::print (which doesn't have this bug).
179-
//
180-
// `m_force_rewrite` gets converted and forces the
181-
// multi-decl to be broken up even though nothing else changes when -alltypes is
182-
// off.
183-
//
184-
// `m_implicit_itype` and `m_change_with_bounds` together test that 3C includes
185-
// Checked C annotations in the range to be replaced (for both changed and
186-
// unchanged multi-decl members) rather than leaving them to duplicate the
187-
// annotations in the newly inserted declaration.
188-
int *m_force_rewrite, m_const_arr0[10], *m_const_arr1[10],
189-
(*m_const_arr2)[10] = 1, *m_implicit_itype : count(2),
190-
**m_change_with_bounds : count(2);
191-
//CHECK: _Ptr<int> m_force_rewrite = ((void *)0);
192-
//CHECK_ALL: int m_const_arr0 _Checked[10];
193-
//CHECK_NOALL: int m_const_arr0[10];
194-
//CHECK_ALL: _Ptr<int> m_const_arr1 _Checked[10] = {((void *)0)};
195-
//CHECK_NOALL: int *m_const_arr1[10];
196-
//CHECK: int (*m_const_arr2)[10] = 1;
197-
// 3C doesn't have proper support for itypes on variables: if a variable has an
198-
// existing itype, 3C uses the checked side as the variable's original type. So
199-
// 3C treats m_implicit_itype as having original type _Array_ptr<int>, but since
200-
// the solved type is the same, 3C uses Decl::print for the unchanged multi-decl
201-
// member and preserves the original declaration with the itype. When 3C gains
202-
// proper itype support for variables, it should generate an actual rewrite to
203-
// the fully checked type if nothing else in the program prevents it from doing
204-
// so.
205-
//CHECK: int *m_implicit_itype : count(2);
206-
// In this case, the solved type changes and shows up in the output.
207-
//CHECK: _Array_ptr<_Ptr<int>> m_change_with_bounds : count(2) = ((void *)0);
208-
209-
// A similar multi-decl with an unnamed inline struct, which forces the use of
210-
// mkString. We can't include (*s_const_arr2)[10] because it would trigger the
211-
// previously mentioned mkString bug and produce output that doesn't compile.
212-
// `s` serves just to give the struct a shorter generated name.
213-
struct { int *x; } s, *s_force_rewrite, s_const_arr0[10], *s_const_arr1[10],
214-
// The only way a variable of unnamed struct type can have an itype is if it
215-
// comes implicitly from a bounds annotation, since we have no name to refer
216-
// to the struct in a written itype.
217-
*s_implicit_itype : count(2), **s_change_with_bounds : count(2);
218-
//CHECK: struct s_struct_1 { _Ptr<int> x; };
219-
//CHECK: struct s_struct_1 s;
220-
//CHECK: _Ptr<struct s_struct_1> s_force_rewrite = ((void *)0);
221-
//CHECK_ALL: struct s_struct_1 s_const_arr0 _Checked[10];
222-
//CHECK_NOALL: struct s_struct_1 s_const_arr0[10];
223-
//CHECK_ALL: _Ptr<struct s_struct_1> s_const_arr1 _Checked[10] = {((void *)0)};
224-
// The reason this isn't `_Ptr<struct s_struct_1>` is probably the "outer wild
225-
// -> inner wild" constraint
226-
// (https://github.com/correctcomputation/checkedc-clang/issues/656).
227-
//CHECK_NOALL: struct s_struct_1 *s_const_arr1[10];
228-
// Like with m_implicit_itype above, 3C treats s_implicit_itype as having type
229-
// _Array_ptr<struct s_struct_1>, but now 3C uses mkString and that type
230-
// actually shows up in the output: not a great result, but at least we test
231-
// that it isn't any worse and that the bounds annotation is preserved. Since
232-
// s_implicit_itype is now the only member of its "multi-decl", if the user
233-
// manually edits it back to an itype, there won't be another multi-decl breakup
234-
// to cause 3C to mess it up again.
235-
//CHECK: _Array_ptr<struct s_struct_1> s_implicit_itype : count(2);
236-
//CHECK: _Array_ptr<_Ptr<struct s_struct_1>> s_change_with_bounds : count(2) = ((void *)0);
237-
238167
void test7() {
239168
// Test that variables that require struct initialization honor base type
240169
// renames the same way as global variables.
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// A few tests of multi-decls with complex types, with and without
2+
// -itypes-for-extern. These tests cannot be included in multivardecls.c because
3+
// compiling that entire file with -itypes-for-extern -addcr would produce an
4+
// unrelated error in the typedef multi-decl test: see the first example in
5+
// https://github.com/correctcomputation/checkedc-clang/issues/740.
6+
7+
// RUN: rm -rf %t*
8+
9+
// RUN: 3c -base-dir=%S -addcr -alltypes %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_ALL","CHECK" %s
10+
// RUN: 3c -base-dir=%S -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_NOALL","CHECK" %s
11+
// RUN: 3c -base-dir=%S -addcr %s -- | %clang -c -fcheckedc-extension -x c -o /dev/null -
12+
// RUN: 3c -base-dir=%S -alltypes -output-dir=%t.checked %s --
13+
// RUN: 3c -base-dir=%t.checked -alltypes %t.checked/multivardecls_complex_types.c -- | diff %t.checked/multivardecls_complex_types.c -
14+
15+
// RUN: 3c -base-dir=%S -itypes-for-extern -alltypes -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_ITE_ALL","CHECK_ITE" %s
16+
// RUN: 3c -base-dir=%S -itypes-for-extern -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_ITE_NOALL","CHECK_ITE" %s
17+
// RUN: 3c -base-dir=%S -itypes-for-extern -alltypes -addcr %s -- | %clang -c -fcheckedc-extension -x c -o /dev/null -
18+
// RUN: 3c -base-dir=%S -itypes-for-extern -alltypes -output-dir=%t.checked_ITE %s --
19+
// RUN: 3c -base-dir=%t.checked_ITE -itypes-for-extern -alltypes %t.checked_ITE/multivardecls_complex_types.c -- | diff %t.checked_ITE/multivardecls_complex_types.c -
20+
21+
// A multi-decl with a mix of pointers and arrays, including an "unchecked
22+
// pointer to constant size array" member that would trigger a known bug in
23+
// mkString (item 5 of
24+
// https://github.com/correctcomputation/checkedc-clang/issues/703),
25+
// demonstrating that unchanged multi-decl members whose base type wasn't
26+
// renamed use Decl::print (which doesn't have this bug).
27+
//
28+
// `m_force_rewrite` gets converted and forces the
29+
// multi-decl to be broken up even though nothing else changes when -alltypes is
30+
// off.
31+
//
32+
// `m_implicit_itype` and `m_change_with_bounds` together test that 3C includes
33+
// Checked C annotations in the range to be replaced (for both changed and
34+
// unchanged multi-decl members) rather than leaving them to duplicate the
35+
// annotations in the newly inserted declaration.
36+
int m_const_arr0[10], *m_const_arr1[10], (*m_p_const_arr_wild)[10] = 1,
37+
(*m_p_const_arr_chk)[10], *m_implicit_itype : count(2),
38+
**m_change_with_bounds : count(2);
39+
//CHECK_ALL: int m_const_arr0 _Checked[10];
40+
//CHECK_NOALL: int m_const_arr0[10];
41+
//CHECK_ALL: _Ptr<int> m_const_arr1 _Checked[10] = {((void *)0)};
42+
//CHECK_NOALL: int *m_const_arr1[10];
43+
//CHECK: int (*m_p_const_arr_wild)[10] = 1;
44+
//CHECK_ALL: _Ptr<int _Checked[10]> m_p_const_arr_chk = ((void *)0);
45+
//CHECK_NOALL: _Ptr<int[10]> m_p_const_arr_chk = ((void *)0);
46+
// 3C doesn't have proper support for itypes on variables: if a variable has an
47+
// existing itype, 3C uses the checked side as the variable's original type. So
48+
// 3C treats m_implicit_itype as having original type _Array_ptr<int>, but since
49+
// the solved type is the same, 3C uses Decl::print for the unchanged multi-decl
50+
// member and preserves the original declaration with the itype. When 3C gains
51+
// proper itype support for variables, it should generate an actual rewrite to
52+
// the fully checked type if nothing else in the program prevents it from doing
53+
// so.
54+
//CHECK: int *m_implicit_itype : count(2);
55+
// In this case, the solved type changes and shows up in the output.
56+
//CHECK: _Array_ptr<_Ptr<int>> m_change_with_bounds : count(2) = ((void *)0);
57+
58+
// Test the same multi-decl with -itypes-for-extern.
59+
//CHECK_ITE_ALL: int m_const_arr0[10] : itype(int _Checked[10]);
60+
//CHECK_ITE_NOALL: int m_const_arr0[10];
61+
//CHECK_ITE_ALL: int *m_const_arr1[10] : itype(_Ptr<int> _Checked[10]) = {((void *)0)};
62+
//CHECK_ITE_NOALL: int *m_const_arr1[10];
63+
//CHECK_ITE: int (*m_p_const_arr_wild)[10] = 1;
64+
//CHECK_ITE_ALL: int (*m_p_const_arr_chk)[10] : itype(_Ptr<int _Checked[10]>) = ((void *)0);
65+
//CHECK_ITE_NOALL: int (*m_p_const_arr_chk)[10] : itype(_Ptr<int[10]>) = ((void *)0);
66+
//CHECK_ITE: int *m_implicit_itype : count(2);
67+
//CHECK_ITE: int **m_change_with_bounds : itype(_Array_ptr<_Ptr<int>>) count(2) = ((void *)0);
68+
69+
// A similar multi-decl with an unnamed inline struct, which forces the use of
70+
// mkString. We can't include (*s_p_const_arr_*)[10] because it would trigger
71+
// the previously mentioned mkString bug and produce output that doesn't
72+
// compile. `s` serves just to give the struct a shorter generated name.
73+
struct { int *x; } s, s_const_arr0[10], *s_const_arr1[10],
74+
// The only way a variable of unnamed struct type can have an itype is if it
75+
// comes implicitly from a bounds annotation, since we have no name to refer
76+
// to the struct in a written itype.
77+
*s_implicit_itype : count(2), **s_change_with_bounds : count(2);
78+
//CHECK: struct s_struct_1 { _Ptr<int> x; };
79+
//CHECK: struct s_struct_1 s;
80+
//CHECK_ALL: struct s_struct_1 s_const_arr0 _Checked[10];
81+
//CHECK_NOALL: struct s_struct_1 s_const_arr0[10];
82+
//CHECK_ALL: _Ptr<struct s_struct_1> s_const_arr1 _Checked[10] = {((void *)0)};
83+
// The reason this isn't `_Ptr<struct s_struct_1>` is probably the "outer wild
84+
// -> inner wild" constraint
85+
// (https://github.com/correctcomputation/checkedc-clang/issues/656).
86+
//CHECK_NOALL: struct s_struct_1 *s_const_arr1[10];
87+
// Like with m_implicit_itype above, 3C treats s_implicit_itype as having type
88+
// _Array_ptr<struct s_struct_1>, but now 3C uses mkString and that type
89+
// actually shows up in the output: not a great result, but at least we test
90+
// that it isn't any worse and that the bounds annotation is preserved. Since
91+
// s_implicit_itype is now the only member of its "multi-decl", if the user
92+
// manually edits it back to an itype, there won't be another multi-decl breakup
93+
// to cause 3C to mess it up again.
94+
//CHECK: _Array_ptr<struct s_struct_1> s_implicit_itype : count(2);
95+
//CHECK: _Array_ptr<_Ptr<struct s_struct_1>> s_change_with_bounds : count(2) = ((void *)0);
96+
97+
// Test the same multi-decl with -itypes-for-extern.
98+
//CHECK_ITE: struct s_struct_1 { int *x : itype(_Ptr<int>); };
99+
//CHECK_ITE: struct s_struct_1 s;
100+
//CHECK_ITE_ALL: struct s_struct_1 s_const_arr0[10] : itype(struct s_struct_1 _Checked[10]);
101+
//CHECK_ITE_NOALL: struct s_struct_1 s_const_arr0[10];
102+
//CHECK_ITE_ALL: struct s_struct_1 *s_const_arr1[10] : itype(_Ptr<struct s_struct_1> _Checked[10]) = {((void *)0)};
103+
//CHECK_ITE_NOALL: struct s_struct_1 *s_const_arr1[10];
104+
// The type of s_implicit_type is still loaded as _Array_ptr<struct s_struct_1>,
105+
// but it is downgraded back to an itype by -itypes-for-extern. As long as 3C
106+
// lacks real support for itypes on variables, this is probably the behavior we
107+
// want with -itypes-for-extern in this very unusual case.
108+
//CHECK_ITE: struct s_struct_1 *s_implicit_itype : itype(_Array_ptr<struct s_struct_1>) count(2);
109+
//CHECK_ITE: struct s_struct_1 **s_change_with_bounds : itype(_Array_ptr<_Ptr<struct s_struct_1>>) count(2) = ((void *)0);

0 commit comments

Comments
 (0)