Skip to content

Commit 1aa6e26

Browse files
committed
Create complex_real_exprt and complex_imag_exprt during typechecking
1 parent d93a021 commit 1aa6e26

File tree

1 file changed

+62
-18
lines changed

1 file changed

+62
-18
lines changed

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -320,36 +320,80 @@ void c_typecheck_baset::typecheck_expr_main(exprt &expr)
320320
// these should only exist as constants,
321321
// and should already be typed
322322
}
323-
else if(expr.id()==ID_complex_real ||
324-
expr.id()==ID_complex_imag)
323+
else if(expr.id() == ID_complex_real)
325324
{
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)
330333
{
331-
if(!is_number(op_type))
334+
if(!is_number(op.type()))
332335
{
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;
336339
throw 0;
337340
}
338341

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);
342346
}
343347
else
344348
{
345-
expr.type()=op_type.subtype();
349+
complex_real_exprt complex_real_expr(op);
346350

347351
// 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);
350395

351-
if(expr.op0().get_bool(ID_C_constant))
352-
expr.set(ID_C_constant, true);
396+
expr.swap(complex_imag_expr);
353397
}
354398
}
355399
else if(expr.id()==ID_generic_selection)

0 commit comments

Comments
 (0)