public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
* [PATCH/RFC] More strict __DECONST, __DEVOLATILE and __DEQUALIFY implementation.
@ 2014-09-14 14:45 Pavel Pisa
  0 siblings, 0 replies; only message in thread
From: Pavel Pisa @ 2014-09-14 14:45 UTC (permalink / raw)
  To: newlib

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-09-14 14:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-14 14:45 [PATCH/RFC] More strict __DECONST, __DEVOLATILE and __DEQUALIFY implementation Pavel Pisa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).