@@ -320,36 +320,80 @@ void c_typecheck_baset::typecheck_expr_main(exprt &expr)
320
320
// these should only exist as constants,
321
321
// and should already be typed
322
322
}
323
- else if (expr.id ()==ID_complex_real ||
324
- expr.id ()==ID_complex_imag)
323
+ else if (expr.id () == ID_complex_real)
325
324
{
326
- // get the subtype
327
- assert (expr.operands ().size ()==1 );
328
- const typet &op_type=follow (expr.op0 ().type ());
329
- if (op_type.id ()!=ID_complex)
325
+ INVARIANT (
326
+ expr.operands ().size () == 1 ,
327
+ " real part retrieval operation should have one operand" );
328
+
329
+ exprt op = expr.op0 ();
330
+ op.type () = follow (op.type ());
331
+
332
+ if (op.type ().id () != ID_complex)
330
333
{
331
- if (!is_number (op_type ))
334
+ if (!is_number (op. type () ))
332
335
{
333
- err_location (expr. op0 () );
334
- error () << " real/imag expect numerical operand, "
335
- << " but got `" << to_string (op_type ) << " '" << eom;
336
+ err_location (op );
337
+ error () << " real part retrieval expects numerical operand, "
338
+ << " but got `" << to_string (op. type () ) << " '" << eom;
336
339
throw 0 ;
337
340
}
338
341
339
- // we could compile away, I suppose
340
- expr.type ()=op_type;
341
- expr.op0 ().make_typecast (complex_typet (op_type));
342
+ typecast_exprt typecast_expr (op, complex_typet (op.type ()));
343
+ complex_real_exprt complex_real_expr (typecast_expr);
344
+
345
+ expr.swap (complex_real_expr);
342
346
}
343
347
else
344
348
{
345
- expr. type ()=op_type. subtype ( );
349
+ complex_real_exprt complex_real_expr (op );
346
350
347
351
// these are lvalues if the operand is one
348
- if (expr.op0 ().get_bool (ID_C_lvalue))
349
- expr.set (ID_C_lvalue, true );
352
+ if (op.get_bool (ID_C_lvalue))
353
+ complex_real_expr.set (ID_C_lvalue, true );
354
+
355
+ if (op.get_bool (ID_C_constant))
356
+ complex_real_expr.set (ID_C_constant, true );
357
+
358
+ expr.swap (complex_real_expr);
359
+ }
360
+ }
361
+ else if (expr.id () == ID_complex_imag)
362
+ {
363
+ INVARIANT (
364
+ expr.operands ().size () == 1 ,
365
+ " imaginary part retrieval operation should have one operand" );
366
+
367
+ exprt op = expr.op0 ();
368
+ op.type () = follow (op.type ());
369
+
370
+ if (op.type ().id () != ID_complex)
371
+ {
372
+ if (!is_number (op.type ()))
373
+ {
374
+ err_location (op);
375
+ error () << " real part retrieval expects numerical operand, "
376
+ << " but got `" << to_string (op.type ()) << " '" << eom;
377
+ throw 0 ;
378
+ }
379
+
380
+ typecast_exprt typecast_expr (op, complex_typet (op.type ()));
381
+ complex_imag_exprt complex_imag_expr (typecast_expr);
382
+
383
+ expr.swap (complex_imag_expr);
384
+ }
385
+ else
386
+ {
387
+ complex_imag_exprt complex_imag_expr (op);
388
+
389
+ // these are lvalues if the operand is one
390
+ if (op.get_bool (ID_C_lvalue))
391
+ complex_imag_expr.set (ID_C_lvalue, true );
392
+
393
+ if (op.get_bool (ID_C_constant))
394
+ complex_imag_expr.set (ID_C_constant, true );
350
395
351
- if (expr.op0 ().get_bool (ID_C_constant))
352
- expr.set (ID_C_constant, true );
396
+ expr.swap (complex_imag_expr);
353
397
}
354
398
}
355
399
else if (expr.id ()==ID_generic_selection)
0 commit comments