FreeRDP
Loading...
Searching...
No Matches
cast.h
1
20#pragma once
21
22#include <stdint.h>
23
24#include <winpr/platform.h>
25#include <winpr/assert-api.h>
26
31#ifdef __cplusplus
32#define WINPR_CXX_COMPAT_CAST(t, val) static_cast<t>(val)
33#else
34#define WINPR_CXX_COMPAT_CAST(t, val) ((t)(val))
35#endif
36
41#if defined(DISABLE_SUPPORTED_ARCH_CHECKS)
42#elif defined(_M_ARM) || defined(_M_ARM64)
43#if !defined(__ARM_FEATURE_UNALIGNED)
44#warning \
45 "-munaligned-access is required on arm. Use -DDISABLE_SUPPORTED_ARCH_CHECKS=ON to ignore, but there will be dragons ahead!"
46#else
47#define WINPR_ARCH_SUPPORTED 1
48#endif
49#elif defined(_M_IX86) || defined(_M_AMD64)
50#define WINPR_ARCH_SUPPORTED 1
51#elif defined(_M_RISCV32) || defined(_M_RISCV64)
52#if !defined(__riscv_misaligned_fast)
53#warning \
54 "RISCV must support __riscv_misaligned_fast. Use -DDISABLE_SUPPORTED_ARCH_CHECKS=ON to ignore, but there will be dragons ahead!"
55#else
56#define WINPR_ARCH_SUPPORTED 1
57#endif
58#endif
59
60#if !defined(WINPR_ARCH_SUPPORTED)
61#warning "unaligned pointer access not verified on platform, SIGBUS may happen!"
62#endif
63
71#if defined(WINPR_ARCH_SUPPORTED) && !defined(_WIN32)
72#define WINPR_PACKED_ALIGN_CAST(t, val) \
73 __extension__({ \
74 WINPR_PRAGMA_DIAG_PUSH; \
75 WINPR_PRAGMA_DIAG_IGNORED_CAST_ALIGN; \
76 typeof(t) aligntmp = WINPR_CXX_COMPAT_CAST(t, val); \
77 WINPR_PRAGMA_DIAG_POP; \
78 aligntmp; \
79 })
80#else
81// Promote any -Wcast-align warnings to errors on platforms not supporting unaligned access
82#if defined(DISABLE_SUPPORTED_ARCH_CHECKS)
83#if defined(__clang__)
84WINPR_DO_PRAGMA(clang diagnostic warning "-Wcast-align")
85#elif defined(__GNUC__)
86WINPR_DO_PRAGMA(GCC diagnostic warning "-Wcast-align")
87#endif
88#else
89#if defined(__clang__)
90WINPR_DO_PRAGMA(clang diagnostic error "-Wcast-align")
91#elif defined(__GNUC__)
92WINPR_DO_PRAGMA(GCC diagnostic error "-Wcast-align")
93#endif
94#endif
95#define WINPR_PACKED_ALIGN_CAST(t, val) WINPR_CXX_COMPAT_CAST(t, val)
96#endif
97
98#if defined(__GNUC__) || defined(__clang__)
106#define WINPR_REINTERPRET_CAST(ptr, srcType, dstType) \
107 __extension__({ \
108 union \
109 { \
110 srcType src; \
111 dstType dst; \
112 } cnv; \
113 WINPR_STATIC_ASSERT(sizeof(srcType) == sizeof(dstType)); \
114 cnv.src = ptr; \
115 cnv.dst; \
116 })
117
125#define WINPR_CAST_CONST_PTR_AWAY(ptr, dstType) \
126 __extension__({ \
127 union \
128 { \
129 __typeof(ptr) src; \
130 dstType dst; \
131 } cnv; \
132 cnv.src = ptr; \
133 cnv.dst; \
134 })
135
143#define WINPR_FUNC_PTR_CAST(ptr, dstType) \
144 __extension__({ \
145 union \
146 { \
147 __typeof(ptr) src; \
148 dstType dst; \
149 } cnv; \
150 WINPR_STATIC_ASSERT(sizeof(dstType) == sizeof(__typeof(ptr))); \
151 cnv.src = ptr; \
152 cnv.dst; \
153 })
154
155#else
156#define WINPR_REINTERPRET_CAST(ptr, srcType, dstType) (dstType) ptr
157#define WINPR_CAST_CONST_PTR_AWAY(ptr, dstType) (dstType) ptr
158#define WINPR_FUNC_PTR_CAST(ptr, dstType) (dstType)(uintptr_t) ptr
159#endif
160
161#if defined(__GNUC__) || defined(__clang__)
162
173#define WINPR_ASSERTING_INT_CAST(type, ivar) \
174 __extension__({ \
175 __typeof(ivar) var = ivar; \
176 WINPR_ASSERT((var) == \
177 WINPR_CXX_COMPAT_CAST(__typeof(var), WINPR_CXX_COMPAT_CAST(type, (var)))); \
178 WINPR_ASSERT((((var) > 0) && (WINPR_CXX_COMPAT_CAST(type, (var)) > 0)) || \
179 (((var) <= 0) && WINPR_CXX_COMPAT_CAST(type, (var)) <= 0)); \
180 WINPR_CXX_COMPAT_CAST(type, (var)); \
181 })
182
183#else
184#define WINPR_ASSERTING_INT_CAST(type, var) WINPR_CXX_COMPAT_CAST(type, var)
185#endif