|
From: Florian K. <fl...@ei...> - 2014-10-22 12:56:00
|
Greetings.
I've just enabled the -Wcast-qual option for compilation of the
valgrind code base. Testcases are not compiled with -Wcast-qual as
that is not very interesting.
I've tested this:
- on s390x with GCC 3.4.6 and 4.8.3
- on ppc64be with GCC 4.7.2
- on amd64 with GCC 4.8.2, clang 3.0 and clang 3.5.0
I would appreciate if somebody with access to Darwin, ARM and MIPS
platforms could give it a spin.
For the curious, there are some spots in the code where a cast that
drops a type qualifier is unavoidable. For instance:
HChar* VG_(strchr) ( const HChar* s, HChar c )
{
while (True) {
if (*s == c) return (HChar *)s;
if (*s == 0) return NULL;
s++;
}
}
To get this compiled with -Wcast-qual and have no warnings there are
basically two options.
One is to enclose such offensive code with
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
HChar* VG_(strchr) .......
#pragma GCC diagnostic pop
The other option is to replace the cast with some type punning trickery:
#define CONST_CAST(T,x) \
({ \
union { \
const T in; \
T out; \
} var = { .in = x }; var.out; \
})
and use it like so:
if (*s == c) return CONST_CAST(HChar *,s);
I opted for the latter as it is less intrusive. The construct is
guaranteed to work even with -fstrict-aliasing (which we're not using).
Also, C99 says (6.5.2.3, footnote 82):
If the member used to access the contents of a union object is not the
same as the member last used to store a value in the object, the
appropriate part of the object representation of the value is
reinterpreted as an object representation in the new type.
Which is exactly what is being done in that macro.
Florian
|