@@ -241,57 +241,11 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
241
241
242
242
case CK_IntegralComplexToBoolean:
243
243
case CK_FloatingComplexToBoolean: {
244
- PrimType ElemT = classifyComplexElementType (SubExpr->getType ());
245
- // We emit the expression (__real(E) != 0 || __imag(E) != 0)
246
- // for us, that means (bool)E[0] || (bool)E[1]
244
+ if (DiscardResult)
245
+ return this ->discard (SubExpr);
247
246
if (!this ->visit (SubExpr))
248
247
return false ;
249
- if (!this ->emitConstUint8 (0 , CE))
250
- return false ;
251
- if (!this ->emitArrayElemPtrUint8 (CE))
252
- return false ;
253
- if (!this ->emitLoadPop (ElemT, CE))
254
- return false ;
255
- if (ElemT == PT_Float) {
256
- if (!this ->emitCastFloatingIntegral (PT_Bool, CE))
257
- return false ;
258
- } else {
259
- if (!this ->emitCast (ElemT, PT_Bool, CE))
260
- return false ;
261
- }
262
-
263
- // We now have the bool value of E[0] on the stack.
264
- LabelTy LabelTrue = this ->getLabel ();
265
- if (!this ->jumpTrue (LabelTrue))
266
- return false ;
267
-
268
- if (!this ->emitConstUint8 (1 , CE))
269
- return false ;
270
- if (!this ->emitArrayElemPtrPopUint8 (CE))
271
- return false ;
272
- if (!this ->emitLoadPop (ElemT, CE))
273
- return false ;
274
- if (ElemT == PT_Float) {
275
- if (!this ->emitCastFloatingIntegral (PT_Bool, CE))
276
- return false ;
277
- } else {
278
- if (!this ->emitCast (ElemT, PT_Bool, CE))
279
- return false ;
280
- }
281
- // Leave the boolean value of E[1] on the stack.
282
- LabelTy EndLabel = this ->getLabel ();
283
- this ->jump (EndLabel);
284
-
285
- this ->emitLabel (LabelTrue);
286
- if (!this ->emitPopPtr (CE))
287
- return false ;
288
- if (!this ->emitConstBool (true , CE))
289
- return false ;
290
-
291
- this ->fallthrough (EndLabel);
292
- this ->emitLabel (EndLabel);
293
-
294
- return true ;
248
+ return this ->emitComplexBoolCast (SubExpr);
295
249
}
296
250
297
251
case CK_IntegralComplexToReal:
@@ -2120,8 +2074,15 @@ bool ByteCodeExprGen<Emitter>::visitInitializer(const Expr *E) {
2120
2074
template <class Emitter >
2121
2075
bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) {
2122
2076
std::optional<PrimType> T = classify (E->getType ());
2123
- if (!T)
2077
+ if (!T) {
2078
+ // Convert complex values to bool.
2079
+ if (E->getType ()->isAnyComplexType ()) {
2080
+ if (!this ->visit (E))
2081
+ return false ;
2082
+ return this ->emitComplexBoolCast (E);
2083
+ }
2124
2084
return false ;
2085
+ }
2125
2086
2126
2087
if (!this ->visit (E))
2127
2088
return false ;
@@ -3249,6 +3210,60 @@ bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
3249
3210
return true ;
3250
3211
}
3251
3212
3213
+ template <class Emitter >
3214
+ bool ByteCodeExprGen<Emitter>::emitComplexBoolCast(const Expr *E) {
3215
+ assert (!DiscardResult);
3216
+ PrimType ElemT = classifyComplexElementType (E->getType ());
3217
+ // We emit the expression (__real(E) != 0 || __imag(E) != 0)
3218
+ // for us, that means (bool)E[0] || (bool)E[1]
3219
+ if (!this ->emitConstUint8 (0 , E))
3220
+ return false ;
3221
+ if (!this ->emitArrayElemPtrUint8 (E))
3222
+ return false ;
3223
+ if (!this ->emitLoadPop (ElemT, E))
3224
+ return false ;
3225
+ if (ElemT == PT_Float) {
3226
+ if (!this ->emitCastFloatingIntegral (PT_Bool, E))
3227
+ return false ;
3228
+ } else {
3229
+ if (!this ->emitCast (ElemT, PT_Bool, E))
3230
+ return false ;
3231
+ }
3232
+
3233
+ // We now have the bool value of E[0] on the stack.
3234
+ LabelTy LabelTrue = this ->getLabel ();
3235
+ if (!this ->jumpTrue (LabelTrue))
3236
+ return false ;
3237
+
3238
+ if (!this ->emitConstUint8 (1 , E))
3239
+ return false ;
3240
+ if (!this ->emitArrayElemPtrPopUint8 (E))
3241
+ return false ;
3242
+ if (!this ->emitLoadPop (ElemT, E))
3243
+ return false ;
3244
+ if (ElemT == PT_Float) {
3245
+ if (!this ->emitCastFloatingIntegral (PT_Bool, E))
3246
+ return false ;
3247
+ } else {
3248
+ if (!this ->emitCast (ElemT, PT_Bool, E))
3249
+ return false ;
3250
+ }
3251
+ // Leave the boolean value of E[1] on the stack.
3252
+ LabelTy EndLabel = this ->getLabel ();
3253
+ this ->jump (EndLabel);
3254
+
3255
+ this ->emitLabel (LabelTrue);
3256
+ if (!this ->emitPopPtr (E))
3257
+ return false ;
3258
+ if (!this ->emitConstBool (true , E))
3259
+ return false ;
3260
+
3261
+ this ->fallthrough (EndLabel);
3262
+ this ->emitLabel (EndLabel);
3263
+
3264
+ return true ;
3265
+ }
3266
+
3252
3267
// / When calling this, we have a pointer of the local-to-destroy
3253
3268
// / on the stack.
3254
3269
// / Emit destruction of record types (or arrays of record types).
0 commit comments