@@ -239,57 +239,11 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
239
239
240
240
case CK_IntegralComplexToBoolean:
241
241
case CK_FloatingComplexToBoolean: {
242
- PrimType ElemT = classifyComplexElementType (SubExpr->getType ());
243
- // We emit the expression (__real(E) != 0 || __imag(E) != 0)
244
- // for us, that means (bool)E[0] || (bool)E[1]
242
+ if (DiscardResult)
243
+ return this ->discard (SubExpr);
245
244
if (!this ->visit (SubExpr))
246
245
return false ;
247
- if (!this ->emitConstUint8 (0 , CE))
248
- return false ;
249
- if (!this ->emitArrayElemPtrUint8 (CE))
250
- return false ;
251
- if (!this ->emitLoadPop (ElemT, CE))
252
- return false ;
253
- if (ElemT == PT_Float) {
254
- if (!this ->emitCastFloatingIntegral (PT_Bool, CE))
255
- return false ;
256
- } else {
257
- if (!this ->emitCast (ElemT, PT_Bool, CE))
258
- return false ;
259
- }
260
-
261
- // We now have the bool value of E[0] on the stack.
262
- LabelTy LabelTrue = this ->getLabel ();
263
- if (!this ->jumpTrue (LabelTrue))
264
- return false ;
265
-
266
- if (!this ->emitConstUint8 (1 , CE))
267
- return false ;
268
- if (!this ->emitArrayElemPtrPopUint8 (CE))
269
- return false ;
270
- if (!this ->emitLoadPop (ElemT, CE))
271
- return false ;
272
- if (ElemT == PT_Float) {
273
- if (!this ->emitCastFloatingIntegral (PT_Bool, CE))
274
- return false ;
275
- } else {
276
- if (!this ->emitCast (ElemT, PT_Bool, CE))
277
- return false ;
278
- }
279
- // Leave the boolean value of E[1] on the stack.
280
- LabelTy EndLabel = this ->getLabel ();
281
- this ->jump (EndLabel);
282
-
283
- this ->emitLabel (LabelTrue);
284
- if (!this ->emitPopPtr (CE))
285
- return false ;
286
- if (!this ->emitConstBool (true , CE))
287
- return false ;
288
-
289
- this ->fallthrough (EndLabel);
290
- this ->emitLabel (EndLabel);
291
-
292
- return true ;
246
+ return this ->emitComplexBoolCast (SubExpr);
293
247
}
294
248
295
249
case CK_IntegralComplexToReal:
@@ -2055,8 +2009,15 @@ bool ByteCodeExprGen<Emitter>::visitInitializer(const Expr *E) {
2055
2009
template <class Emitter >
2056
2010
bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) {
2057
2011
std::optional<PrimType> T = classify (E->getType ());
2058
- if (!T)
2012
+ if (!T) {
2013
+ // Convert complex values to bool.
2014
+ if (E->getType ()->isAnyComplexType ()) {
2015
+ if (!this ->visit (E))
2016
+ return false ;
2017
+ return this ->emitComplexBoolCast (E);
2018
+ }
2059
2019
return false ;
2020
+ }
2060
2021
2061
2022
if (!this ->visit (E))
2062
2023
return false ;
@@ -3150,6 +3111,60 @@ bool ByteCodeExprGen<Emitter>::emitComplexReal(const Expr *SubExpr) {
3150
3111
return true ;
3151
3112
}
3152
3113
3114
+ template <class Emitter >
3115
+ bool ByteCodeExprGen<Emitter>::emitComplexBoolCast(const Expr *E) {
3116
+ assert (!DiscardResult);
3117
+ PrimType ElemT = classifyComplexElementType (E->getType ());
3118
+ // We emit the expression (__real(E) != 0 || __imag(E) != 0)
3119
+ // for us, that means (bool)E[0] || (bool)E[1]
3120
+ if (!this ->emitConstUint8 (0 , E))
3121
+ return false ;
3122
+ if (!this ->emitArrayElemPtrUint8 (E))
3123
+ return false ;
3124
+ if (!this ->emitLoadPop (ElemT, E))
3125
+ return false ;
3126
+ if (ElemT == PT_Float) {
3127
+ if (!this ->emitCastFloatingIntegral (PT_Bool, E))
3128
+ return false ;
3129
+ } else {
3130
+ if (!this ->emitCast (ElemT, PT_Bool, E))
3131
+ return false ;
3132
+ }
3133
+
3134
+ // We now have the bool value of E[0] on the stack.
3135
+ LabelTy LabelTrue = this ->getLabel ();
3136
+ if (!this ->jumpTrue (LabelTrue))
3137
+ return false ;
3138
+
3139
+ if (!this ->emitConstUint8 (1 , E))
3140
+ return false ;
3141
+ if (!this ->emitArrayElemPtrPopUint8 (E))
3142
+ return false ;
3143
+ if (!this ->emitLoadPop (ElemT, E))
3144
+ return false ;
3145
+ if (ElemT == PT_Float) {
3146
+ if (!this ->emitCastFloatingIntegral (PT_Bool, E))
3147
+ return false ;
3148
+ } else {
3149
+ if (!this ->emitCast (ElemT, PT_Bool, E))
3150
+ return false ;
3151
+ }
3152
+ // Leave the boolean value of E[1] on the stack.
3153
+ LabelTy EndLabel = this ->getLabel ();
3154
+ this ->jump (EndLabel);
3155
+
3156
+ this ->emitLabel (LabelTrue);
3157
+ if (!this ->emitPopPtr (E))
3158
+ return false ;
3159
+ if (!this ->emitConstBool (true , E))
3160
+ return false ;
3161
+
3162
+ this ->fallthrough (EndLabel);
3163
+ this ->emitLabel (EndLabel);
3164
+
3165
+ return true ;
3166
+ }
3167
+
3153
3168
// / When calling this, we have a pointer of the local-to-destroy
3154
3169
// / on the stack.
3155
3170
// / Emit destruction of record types (or arrays of record types).
0 commit comments