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/* MSVC is not defining the same guards as everyone else, so lets hope they always support it and
44 * not only sometimes. */
45#if !defined(__ARM_FEATURE_UNALIGNED) && !defined(_MSC_VER)
46#warning \
47 "-munaligned-access is required on arm. Use -DDISABLE_SUPPORTED_ARCH_CHECKS=ON to ignore, but there will be dragons ahead!"
48#else
49#define WINPR_ARCH_SUPPORTED 1
50#endif
51#elif defined(_M_IX86) || defined(_M_AMD64) || defined(_M_PPC) || defined(_M_S390X)
52#define WINPR_ARCH_SUPPORTED 1
53#elif defined(_M_RISCV32) || defined(_M_RISCV64)
54#if !defined(__riscv_misaligned_fast)
55#warning \
56 "RISCV must support __riscv_misaligned_fast. Use -DDISABLE_SUPPORTED_ARCH_CHECKS=ON to ignore, but there will be dragons ahead!"
57#else
58#define WINPR_ARCH_SUPPORTED 1
59#endif
60#endif
61
62#if !defined(WINPR_ARCH_SUPPORTED)
63#if defined(__GNUC__) || defined(__clang__) || \
64 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)) || \
65 (defined(__cplusplus) && (__cplusplus >= 202302L))
66#warning "unaligned pointer access not verified on platform, SIGBUS may happen!"
67#endif
68#endif
69
77#if defined(WINPR_ARCH_SUPPORTED) && !defined(_WIN32)
78#define WINPR_PACKED_ALIGN_CAST(t, val) \
79 __extension__({ \
80 WINPR_PRAGMA_DIAG_PUSH; \
81 WINPR_PRAGMA_DIAG_IGNORED_CAST_ALIGN; \
82 typeof(t) aligntmp = WINPR_CXX_COMPAT_CAST(t, val); \
83 WINPR_PRAGMA_DIAG_POP; \
84 aligntmp; \
85 })
86#else
87// Promote any -Wcast-align warnings to errors on platforms not supporting unaligned access
88#if defined(DISABLE_SUPPORTED_ARCH_CHECKS)
89#if defined(__clang__)
90WINPR_DO_PRAGMA(clang diagnostic warning "-Wcast-align")
91#elif defined(__GNUC__)
92WINPR_DO_PRAGMA(GCC diagnostic warning "-Wcast-align")
93#endif
94#else
95#if defined(__clang__)
96WINPR_DO_PRAGMA(clang diagnostic error "-Wcast-align")
97#elif defined(__GNUC__)
98WINPR_DO_PRAGMA(GCC diagnostic error "-Wcast-align")
99#endif
100#endif
101#define WINPR_PACKED_ALIGN_CAST(t, val) WINPR_CXX_COMPAT_CAST(t, val)
102#endif
103
104#if defined(__GNUC__) || defined(__clang__)
112#define WINPR_REINTERPRET_CAST(ptr, srcType, dstType) \
113 __extension__({ \
114 union \
115 { \
116 srcType src; \
117 dstType dst; \
118 } cnv; \
119 WINPR_STATIC_ASSERT(sizeof(srcType) == sizeof(dstType)); \
120 cnv.src = ptr; \
121 cnv.dst; \
122 })
123
131#define WINPR_CAST_CONST_PTR_AWAY(ptr, dstType) \
132 __extension__({ \
133 union \
134 { \
135 __typeof(ptr) src; \
136 dstType dst; \
137 } cnv; \
138 cnv.src = ptr; \
139 cnv.dst; \
140 })
141
149#define WINPR_FUNC_PTR_CAST(ptr, dstType) \
150 __extension__({ \
151 union \
152 { \
153 __typeof(ptr) src; \
154 dstType dst; \
155 } cnv; \
156 WINPR_STATIC_ASSERT(sizeof(dstType) == sizeof(__typeof(ptr))); \
157 cnv.src = ptr; \
158 cnv.dst; \
159 })
160
161#else
162#define WINPR_REINTERPRET_CAST(ptr, srcType, dstType) (dstType) ptr
163#define WINPR_CAST_CONST_PTR_AWAY(ptr, dstType) (dstType) ptr
164#define WINPR_FUNC_PTR_CAST(ptr, dstType) (dstType)(uintptr_t) ptr
165#endif
166
167#if defined(__GNUC__) || defined(__clang__)
168
179#define WINPR_ASSERTING_INT_CAST(type, ivar) \
180 __extension__({ \
181 __typeof(ivar) var = ivar; \
182 WINPR_ASSERT((var) == \
183 WINPR_CXX_COMPAT_CAST(__typeof(var), WINPR_CXX_COMPAT_CAST(type, (var)))); \
184 WINPR_ASSERT((((var) > 0) && (WINPR_CXX_COMPAT_CAST(type, (var)) > 0)) || \
185 (((var) <= 0) && WINPR_CXX_COMPAT_CAST(type, (var)) <= 0)); \
186 WINPR_CXX_COMPAT_CAST(type, (var)); \
187 })
188
189#else
190#define WINPR_ASSERTING_INT_CAST(type, var) WINPR_CXX_COMPAT_CAST(type, var)
191#endif