Skip to content

Commit bd848b0

Browse files
committed
ctest: Disable the GCC ignored-qualifiers warning for roundtrip tests
GCC flags function return values that include `volatile` even through typedefs, such as with this example from NetBSD: typedef unsigned char __cpu_simple_lock_nv_t; typedef volatile __cpu_simple_lock_nv_t __cpu_simple_lock_t; typedef __cpu_simple_lock_t pthread_spin_t; pthread_spin_t foo() { return 0; } Ignore the warning for the scope where we emit these tests.
1 parent 19df995 commit bd848b0

File tree

9 files changed

+486
-45
lines changed

9 files changed

+486
-45
lines changed

ctest/templates/test.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
#if defined(__cplusplus)
2323
#define CTEST_ALIGNOF(T) alignof(T)
24-
#define CTEST_EXTERN extern "C"
24+
#define CTEST_EXTERN extern "C"
2525
#else
2626
#define CTEST_ALIGNOF(T) _Alignof(T)
2727
#define CTEST_EXTERN
@@ -96,9 +96,15 @@ ctest_field_ptr__{{ item.id }}__{{ item.field.ident() }}({{ item.c_ty }} *b) {
9696
{%- endfor +%}
9797

9898
#ifdef _MSC_VER
99-
// Disable signed/unsigned conversion warnings on MSVC.
100-
// These trigger even if the conversion is explicit.
101-
# pragma warning(disable:4365)
99+
// Disable signed/unsigned conversion warnings on MSVC.
100+
// These trigger even if the conversion is explicit.
101+
#pragma warning(disable:4365)
102+
#endif
103+
104+
#ifdef __GNUC__
105+
// GCC emits a warning with `-Wextra` if we return a typedef to a type marked `volatile`.
106+
#pragma GCC diagnostic push
107+
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
102108
#endif
103109

104110
{%- for item in ctx.roundtrip_tests +%}
@@ -132,14 +138,20 @@ CTEST_EXTERN {{ item.c_ty }} ctest_roundtrip__{{ item.id }}(
132138

133139
{%- endfor +%}
134140

141+
#ifdef __GNUC__
142+
// Pop allow for `-Wignored-qualifiers`
143+
#pragma GCC diagnostic pop
144+
#endif
145+
135146
#ifdef _MSC_VER
136-
# pragma warning(default:4365)
147+
// Pop allow for 4365
148+
#pragma warning(default:4365)
137149
#endif
138150

139151
#ifdef _MSC_VER
140-
// Disable function pointer type conversion warnings on MSVC.
141-
// The conversion may fail only if we call that function, however we only check its address.
142-
# pragma warning(disable:4191)
152+
// Disable function pointer type conversion warnings on MSVC.
153+
// The conversion may fail only if we call that function, however we only check its address.
154+
#pragma warning(disable:4191)
143155
#endif
144156

145157
{%- for item in ctx.foreign_fn_tests +%}
@@ -151,7 +163,8 @@ CTEST_EXTERN ctest_void_func ctest_foreign_fn__{{ item.id }}(void) {
151163
{%- endfor +%}
152164

153165
#ifdef _MSC_VER
154-
# pragma warning(default:4191)
166+
// Pop allow for 4191
167+
#pragma warning(default:4191)
155168
#endif
156169

157170
{%- for static_ in ctx.foreign_static_tests +%}

ctest/tests/input/hierarchy.out.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#if defined(__cplusplus)
1010
#define CTEST_ALIGNOF(T) alignof(T)
11-
#define CTEST_EXTERN extern "C"
11+
#define CTEST_EXTERN extern "C"
1212
#else
1313
#define CTEST_ALIGNOF(T) _Alignof(T)
1414
#define CTEST_EXTERN
@@ -38,9 +38,15 @@ CTEST_EXTERN uint32_t ctest_signededness_of__in6_addr(void) {
3838
}
3939

4040
#ifdef _MSC_VER
41-
// Disable signed/unsigned conversion warnings on MSVC.
42-
// These trigger even if the conversion is explicit.
43-
# pragma warning(disable:4365)
41+
// Disable signed/unsigned conversion warnings on MSVC.
42+
// These trigger even if the conversion is explicit.
43+
#pragma warning(disable:4365)
44+
#endif
45+
46+
#ifdef __GNUC__
47+
// GCC emits a warning with `-Wextra` if we return a typedef to a type marked `volatile`.
48+
#pragma GCC diagnostic push
49+
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
4450
#endif
4551

4652
// Tests whether the struct/union/alias `x` when passed by value to C and back to Rust
@@ -70,14 +76,20 @@ CTEST_EXTERN in6_addr ctest_roundtrip__in6_addr(
7076
return value;
7177
}
7278

79+
#ifdef __GNUC__
80+
// Pop allow for `-Wignored-qualifiers`
81+
#pragma GCC diagnostic pop
82+
#endif
83+
7384
#ifdef _MSC_VER
74-
# pragma warning(default:4365)
85+
// Pop allow for 4365
86+
#pragma warning(default:4365)
7587
#endif
7688

7789
#ifdef _MSC_VER
78-
// Disable function pointer type conversion warnings on MSVC.
79-
// The conversion may fail only if we call that function, however we only check its address.
80-
# pragma warning(disable:4191)
90+
// Disable function pointer type conversion warnings on MSVC.
91+
// The conversion may fail only if we call that function, however we only check its address.
92+
#pragma warning(disable:4191)
8193
#endif
8294

8395
// Return a function pointer.
@@ -86,7 +98,8 @@ CTEST_EXTERN ctest_void_func ctest_foreign_fn__malloc(void) {
8698
}
8799

88100
#ifdef _MSC_VER
89-
# pragma warning(default:4191)
101+
// Pop allow for 4191
102+
#pragma warning(default:4191)
90103
#endif
91104

92105
// Return a pointer to the static variable content.

ctest/tests/input/macro.out.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
#if defined(__cplusplus)
1313
#define CTEST_ALIGNOF(T) alignof(T)
14-
#define CTEST_EXTERN extern "C"
14+
#define CTEST_EXTERN extern "C"
1515
#else
1616
#define CTEST_ALIGNOF(T) _Alignof(T)
1717
#define CTEST_EXTERN
@@ -108,9 +108,15 @@ ctest_field_ptr__VecU16__y(struct VecU16 *b) {
108108
}
109109

110110
#ifdef _MSC_VER
111-
// Disable signed/unsigned conversion warnings on MSVC.
112-
// These trigger even if the conversion is explicit.
113-
# pragma warning(disable:4365)
111+
// Disable signed/unsigned conversion warnings on MSVC.
112+
// These trigger even if the conversion is explicit.
113+
#pragma warning(disable:4365)
114+
#endif
115+
116+
#ifdef __GNUC__
117+
// GCC emits a warning with `-Wextra` if we return a typedef to a type marked `volatile`.
118+
#pragma GCC diagnostic push
119+
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
114120
#endif
115121

116122
// Tests whether the struct/union/alias `x` when passed by value to C and back to Rust
@@ -167,16 +173,23 @@ CTEST_EXTERN struct VecU16 ctest_roundtrip__VecU16(
167173
return value;
168174
}
169175

176+
#ifdef __GNUC__
177+
// Pop allow for `-Wignored-qualifiers`
178+
#pragma GCC diagnostic pop
179+
#endif
180+
170181
#ifdef _MSC_VER
171-
# pragma warning(default:4365)
182+
// Pop allow for 4365
183+
#pragma warning(default:4365)
172184
#endif
173185

174186
#ifdef _MSC_VER
175-
// Disable function pointer type conversion warnings on MSVC.
176-
// The conversion may fail only if we call that function, however we only check its address.
177-
# pragma warning(disable:4191)
187+
// Disable function pointer type conversion warnings on MSVC.
188+
// The conversion may fail only if we call that function, however we only check its address.
189+
#pragma warning(disable:4191)
178190
#endif
179191

180192
#ifdef _MSC_VER
181-
# pragma warning(default:4191)
193+
// Pop allow for 4191
194+
#pragma warning(default:4191)
182195
#endif

ctest/tests/input/simple.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ typedef unsigned long gregset_t[32];
66

77
Byte byte = 0x42;
88

9+
typedef volatile char volatile_char;
10+
911
enum Color
1012
{
1113
RED,

ctest/tests/input/simple.out.with-renames.c

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#if defined(__cplusplus)
1010
#define CTEST_ALIGNOF(T) alignof(T)
11-
#define CTEST_EXTERN extern "C"
11+
#define CTEST_EXTERN extern "C"
1212
#else
1313
#define CTEST_ALIGNOF(T) _Alignof(T)
1414
#define CTEST_EXTERN
@@ -62,6 +62,12 @@ CTEST_EXTERN uint64_t ctest_size_of__Byte(void) { return sizeof(Byte); }
6262
// Return the alignment of a type.
6363
CTEST_EXTERN uint64_t ctest_align_of__Byte(void) { return CTEST_ALIGNOF(Byte); }
6464

65+
// Return the size of a type.
66+
CTEST_EXTERN uint64_t ctest_size_of__volatile_char(void) { return sizeof(volatile_char); }
67+
68+
// Return the alignment of a type.
69+
CTEST_EXTERN uint64_t ctest_align_of__volatile_char(void) { return CTEST_ALIGNOF(volatile_char); }
70+
6571
// Return the size of a type.
6672
CTEST_EXTERN uint64_t ctest_size_of__gregset_t(void) { return sizeof(gregset_t); }
6773

@@ -93,6 +99,13 @@ CTEST_EXTERN uint32_t ctest_signededness_of__Byte(void) {
9399
return all_ones < 0;
94100
}
95101

102+
// Return `1` if the type is signed, otherwise return `0`.
103+
// Casting -1 to the aliased type if signed evaluates to `-1 < 0`, if unsigned to `MAX_VALUE < 0`
104+
CTEST_EXTERN uint32_t ctest_signededness_of__volatile_char(void) {
105+
volatile_char all_ones = (volatile_char) -1;
106+
return all_ones < 0;
107+
}
108+
96109
// Return the offset of a struct/union field.
97110
CTEST_EXTERN uint64_t ctest_offset_of__Person__name(void) {
98111
return offsetof(struct Person, name);
@@ -208,9 +221,15 @@ ctest_field_ptr__Word__byte(union Word *b) {
208221
}
209222

210223
#ifdef _MSC_VER
211-
// Disable signed/unsigned conversion warnings on MSVC.
212-
// These trigger even if the conversion is explicit.
213-
# pragma warning(disable:4365)
224+
// Disable signed/unsigned conversion warnings on MSVC.
225+
// These trigger even if the conversion is explicit.
226+
#pragma warning(disable:4365)
227+
#endif
228+
229+
#ifdef __GNUC__
230+
// GCC emits a warning with `-Wextra` if we return a typedef to a type marked `volatile`.
231+
#pragma GCC diagnostic push
232+
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
214233
#endif
215234

216235
// Tests whether the struct/union/alias `x` when passed by value to C and back to Rust
@@ -240,6 +259,33 @@ CTEST_EXTERN Byte ctest_roundtrip__Byte(
240259
return value;
241260
}
242261

262+
// Tests whether the struct/union/alias `x` when passed by value to C and back to Rust
263+
// remains unchanged.
264+
// It checks if the size is the same as well as if the padding bytes are all in the correct place.
265+
CTEST_EXTERN volatile_char ctest_roundtrip__volatile_char(
266+
volatile_char value,
267+
const uint8_t is_padding_byte[sizeof(volatile_char)],
268+
uint8_t value_bytes[sizeof(volatile_char)]
269+
) {
270+
int size = (int)sizeof(volatile_char);
271+
// Mark `p` as volatile so that the C compiler does not optimize away the pattern we create.
272+
// Otherwise the Rust side would not be able to see it.
273+
volatile uint8_t* p = (volatile uint8_t*)&value;
274+
int i = 0;
275+
for (i = 0; i < size; ++i) {
276+
// We skip padding bytes in both Rust and C because writing to it is undefined.
277+
// Instead we just make sure the the placement of the padding bytes remains the same.
278+
if (is_padding_byte[i]) { continue; }
279+
value_bytes[i] = p[i];
280+
// After we check that the pattern remained unchanged from Rust to C, we invert the pattern
281+
// and send it back to Rust to make sure that it remains unchanged from C to Rust.
282+
uint8_t d = (uint8_t)(255) - (uint8_t)(i % 256);
283+
d = d == 0 ? 42: d;
284+
p[i] = d;
285+
}
286+
return value;
287+
}
288+
243289
// Tests whether the struct/union/alias `x` when passed by value to C and back to Rust
244290
// remains unchanged.
245291
// It checks if the size is the same as well as if the padding bytes are all in the correct place.
@@ -321,14 +367,20 @@ CTEST_EXTERN union Word ctest_roundtrip__Word(
321367
return value;
322368
}
323369

370+
#ifdef __GNUC__
371+
// Pop allow for `-Wignored-qualifiers`
372+
#pragma GCC diagnostic pop
373+
#endif
374+
324375
#ifdef _MSC_VER
325-
# pragma warning(default:4365)
376+
// Pop allow for 4365
377+
#pragma warning(default:4365)
326378
#endif
327379

328380
#ifdef _MSC_VER
329-
// Disable function pointer type conversion warnings on MSVC.
330-
// The conversion may fail only if we call that function, however we only check its address.
331-
# pragma warning(disable:4191)
381+
// Disable function pointer type conversion warnings on MSVC.
382+
// The conversion may fail only if we call that function, however we only check its address.
383+
#pragma warning(disable:4191)
332384
#endif
333385

334386
// Return a function pointer.
@@ -337,7 +389,8 @@ CTEST_EXTERN ctest_void_func ctest_foreign_fn__calloc(void) {
337389
}
338390

339391
#ifdef _MSC_VER
340-
# pragma warning(default:4191)
392+
// Pop allow for 4191
393+
#pragma warning(default:4191)
341394
#endif
342395

343396
// Return a pointer to the static variable content.

0 commit comments

Comments
 (0)