Skip to content

Commit c63863b

Browse files
committed
Fix error caused by GCC strict aliasing
... can't have anything fun around these parts :/
1 parent 17d2221 commit c63863b

File tree

1 file changed

+37
-28
lines changed

1 file changed

+37
-28
lines changed

include/deemon/arg.h

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,15 @@ DFUNDEF WUNUSED ATTR_INS(2, 1) NONNULL((3)) int
112112
goto err; \
113113
} __WHILE0
114114
#else /* __OPTIMIZE_SIZE__ */
115+
#ifdef __COMPILER_HAVE_TYPEOF
116+
#define __DeeArg_ASSIGN(p_arg, value) (*(p_arg) = (__typeof__(*(p_arg)))(value))
117+
#else /* __COMPILER_HAVE_TYPEOF */
118+
/* !!! This version here technically breaks "strict-aliasing rules", but without
119+
* !!! compiler support for "typeof", there's nothing we can do about that. Luckily,
120+
* !!! MSVC (being the only compiler not to support typeof) doesn't care about
121+
* !!! strict aliasing rules. */
122+
#define __DeeArg_ASSIGN(p_arg, value) (*(DeeObject **)(p_arg) = (value))
123+
#endif /* !__COMPILER_HAVE_TYPEOF */
115124
#define _DeeArg_Unpack0(err, argc, argv, function_name) \
116125
if unlikely((argc) != 0) { \
117126
DeeArg_BadArgc0(function_name, argc); \
@@ -123,34 +132,34 @@ DFUNDEF WUNUSED ATTR_INS(2, 1) NONNULL((3)) int
123132
DeeArg_BadArgc1(function_name, argc); \
124133
goto err; \
125134
} else \
126-
(void)(*(DeeObject **)(p_arg0) = (argv)[0], \
127-
__builtin_assume(*(p_arg0) != NULL))
135+
(void)(__DeeArg_ASSIGN(p_arg0, (argv)[0]), \
136+
__builtin_assume(*(p_arg0)))
128137
#define _DeeArg_Unpack2(err, argc, argv, function_name, p_arg0, p_arg1) \
129138
if unlikely((argc) != 2) { \
130139
DeeArg_BadArgc(function_name, argc, 2); \
131140
goto err; \
132141
} else \
133-
(void)(*(DeeObject **)(p_arg0) = (argv)[0], \
134-
*(DeeObject **)(p_arg1) = (argv)[1], \
135-
__builtin_assume(*(p_arg0) != NULL), \
136-
__builtin_assume(*(p_arg1) != NULL))
142+
(void)(__DeeArg_ASSIGN(p_arg0, (argv)[0]), \
143+
__DeeArg_ASSIGN(p_arg1, (argv)[1]), \
144+
__builtin_assume(*(p_arg0)), \
145+
__builtin_assume(*(p_arg1)))
137146
#define _DeeArg_Unpack3(err, argc, argv, function_name, p_arg0, p_arg1, p_arg2) \
138147
if unlikely((argc) != 3) { \
139148
DeeArg_BadArgc(function_name, argc, 3); \
140149
goto err; \
141150
} else \
142-
(void)(*(DeeObject **)(p_arg0) = (argv)[0], \
143-
*(DeeObject **)(p_arg1) = (argv)[1], \
144-
*(DeeObject **)(p_arg2) = (argv)[2], \
145-
__builtin_assume(*(p_arg0) != NULL), \
146-
__builtin_assume(*(p_arg1) != NULL), \
147-
__builtin_assume(*(p_arg2) != NULL))
151+
(void)(__DeeArg_ASSIGN(p_arg0, (argv)[0]), \
152+
__DeeArg_ASSIGN(p_arg1, (argv)[1]), \
153+
__DeeArg_ASSIGN(p_arg2, (argv)[2]), \
154+
__builtin_assume(*(p_arg0)), \
155+
__builtin_assume(*(p_arg1)), \
156+
__builtin_assume(*(p_arg2)))
148157
#define _DeeArg_Unpack0Or1(err, argc, argv, function_name, p_arg0) \
149158
do { \
150159
switch (argc) { \
151160
case 1: \
152-
*(DeeObject **)(p_arg0) = (argv)[0]; \
153-
__builtin_assume(*(p_arg0) != NULL); \
161+
__DeeArg_ASSIGN(p_arg0, (argv)[0]); \
162+
__builtin_assume(*(p_arg0)); \
154163
break; \
155164
case 0: \
156165
break; \
@@ -163,12 +172,12 @@ DFUNDEF WUNUSED ATTR_INS(2, 1) NONNULL((3)) int
163172
do { \
164173
switch (argc) { \
165174
case 2: \
166-
*(DeeObject **)(p_arg1) = (argv)[1]; \
167-
__builtin_assume(*(p_arg1) != NULL); \
175+
__DeeArg_ASSIGN(p_arg1, (argv)[1]); \
176+
__builtin_assume(*(p_arg1)); \
168177
ATTR_FALLTHROUGH \
169178
case 1: \
170-
*(DeeObject **)(p_arg0) = (argv)[0]; \
171-
__builtin_assume(*(p_arg0) != NULL); \
179+
__DeeArg_ASSIGN(p_arg0, (argv)[0]); \
180+
__builtin_assume(*(p_arg0)); \
172181
break; \
173182
default: \
174183
DeeArg_BadArgcEx(function_name, argc, 1, 2); \
@@ -179,12 +188,12 @@ DFUNDEF WUNUSED ATTR_INS(2, 1) NONNULL((3)) int
179188
do { \
180189
switch (argc) { \
181190
case 2: \
182-
*(DeeObject **)(p_arg1) = (argv)[1]; \
183-
__builtin_assume(*(p_arg1) != NULL); \
191+
__DeeArg_ASSIGN(p_arg1, (argv)[1]); \
192+
__builtin_assume(*(p_arg1)); \
184193
ATTR_FALLTHROUGH \
185194
case 1: \
186-
*(DeeObject **)(p_arg0) = (argv)[0]; \
187-
__builtin_assume(*(p_arg0) != NULL); \
195+
__DeeArg_ASSIGN(p_arg0, (argv)[0]); \
196+
__builtin_assume(*(p_arg0)); \
188197
break; \
189198
case 0: \
190199
break; \
@@ -197,16 +206,16 @@ DFUNDEF WUNUSED ATTR_INS(2, 1) NONNULL((3)) int
197206
do { \
198207
switch (argc) { \
199208
case 3: \
200-
*(DeeObject **)(p_arg2) = (argv)[2]; \
201-
__builtin_assume(*(p_arg2) != NULL); \
209+
__DeeArg_ASSIGN(p_arg2, (argv)[2]); \
210+
__builtin_assume(*(p_arg2)); \
202211
ATTR_FALLTHROUGH \
203212
case 2: \
204-
*(DeeObject **)(p_arg1) = (argv)[1]; \
205-
__builtin_assume(*(p_arg1) != NULL); \
213+
__DeeArg_ASSIGN(p_arg1, (argv)[1]); \
214+
__builtin_assume(*(p_arg1)); \
206215
ATTR_FALLTHROUGH \
207216
case 1: \
208-
*(DeeObject **)(p_arg0) = (argv)[0]; \
209-
__builtin_assume(*(p_arg0) != NULL); \
217+
__DeeArg_ASSIGN(p_arg0, (argv)[0]); \
218+
__builtin_assume(*(p_arg0)); \
210219
break; \
211220
default: \
212221
DeeArg_BadArgcEx(function_name, argc, 1, 3); \

0 commit comments

Comments
 (0)