[PATCH/RFC] More strict __DECONST, __DEVOLATILE and __DEQUALIFY implementation.
Pavel Pisa
ppisa4lists@pikron.com
Sun Sep 14 14:45:00 GMT 2014
From: Pavel Pisa <ppisa@pikron.com>
This implementation is able to catch cast to type
which differs not only in qualifiers. It suppresses
warning about incompatible pointer assignment only for
case where pointer types differs in volatile and const
in the first indirection level. If pointers differs
other way, the standard waning is reported.
The actual implementation does not distinguish between
volatile and const removal which is equivalent
to the C++ const_cast which is used for C++ code
too. This can be implemented but there would be
much more lines.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
---
newlib/libc/include/sys/cdefs.h | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
This patch tries to restore some safety in pointers manipulation.
The __DECONST, __DEVOLATILE and __DEQUALIFY macros supress
false warning but original implementation hides more serious
errors when pointers for different types are mixed.
The proposed solution has been tested in some of our projects
and proposed even for RTEMS but discussion with people more
aware of GCC internals is welcomed. I am not sure why cast
to __uintptr_t is used in original code - for warnings
suppression it is not necessary for C/GCC mode. Use of const_cast
for C++ is more straightforward too. Do I miss some alliasing
optimization problems or some other miscompile risk there?
The proposal for newlib is little more optimized and simplified
than previous attempt and was tested only by inclusion in simple test.
It has not been tested in full Newlib based toolchain test yet.
diff --git a/newlib/libc/include/sys/cdefs.h b/newlib/libc/include/sys/cdefs.h
index a5e613c..d1b98fd 100644
--- a/newlib/libc/include/sys/cdefs.h
+++ b/newlib/libc/include/sys/cdefs.h
@@ -571,16 +571,52 @@
#define __COPYRIGHT(s) struct __hack
#endif
+#ifndef __TYPEOF_REFX
+/* The cast idea based on libHX by Jan Engelhardt */
+#define __TYPEOF_REFX(ptr_level, ptr_type) \
+ typeof(ptr_level(union { int z; typeof(ptr_type) x; }){0}.x)
+#endif
+
+#ifndef __DEQUALIFY_DEPTHX
+#ifdef __cplusplus
+#define __DEQUALIFY_DEPTHX(ptr_level, type, var) \
+ (const_cast<type>(var))
+#else /* Standard C code */
+#ifdef __GNUC__
+#define __DEQUALIFY_DEPTHX(ptr_level, type, var) ( \
+ __builtin_choose_expr(__builtin_types_compatible_p \
+ (__TYPEOF_REFX(ptr_level, var), \
+ __TYPEOF_REFX(ptr_level, type)), \
+ (type)(var), \
+ var \
+ ) \
+)
+#endif /*__GNUC__*/
+#endif /*__cplusplus*/
+#endif /*__DEQUALIFY_DEPTHX*/
+
#ifndef __DECONST
+#ifndef __DEQUALIFY_DEPTHX
#define __DECONST(type, var) ((type)(__uintptr_t)(const void *)(var))
+#else
+#define __DECONST(type, var) __DEQUALIFY_DEPTHX(*, type, var)
+#endif
#endif
#ifndef __DEVOLATILE
+#ifndef __DEQUALIFY_DEPTHX
#define __DEVOLATILE(type, var) ((type)(__uintptr_t)(volatile void *)(var))
+#else
+#define __DEVOLATILE(type, var) __DEQUALIFY_DEPTHX(*, type, var)
+#endif
#endif
#ifndef __DEQUALIFY
+#ifndef __DEQUALIFY_DEPTHX
#define __DEQUALIFY(type, var) ((type)(__uintptr_t)(const volatile void *)(var))
+#else
+#define __DEQUALIFY(type, var) __DEQUALIFY_DEPTHX(*, type, var)
+#endif
#endif
/*-
--
1.9.1
More information about the Newlib
mailing list