@@ -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