Go to the documentation of this file.
48 if(expr.
id()==ID_already_typechecked)
66 if(expr.
id()==ID_div ||
71 if(expr.
type().
id()==ID_floatbv &&
80 expr.
id(ID_floatbv_div);
81 else if(expr.
id()==ID_mult)
82 expr.
id(ID_floatbv_mult);
83 else if(expr.
id()==ID_plus)
84 expr.
id(ID_floatbv_plus);
85 else if(expr.
id()==ID_minus)
86 expr.
id(ID_floatbv_minus);
107 if(type1.
id()==ID_c_enum_tag)
109 else if(type2.
id()==ID_c_enum_tag)
112 if(type1.
id()==ID_c_enum)
114 if(type2.
id()==ID_c_enum)
119 else if(type2.
id()==ID_c_enum)
124 else if(type1.
id()==ID_pointer &&
125 type2.
id()==ID_pointer)
130 else if(type1.
id()==ID_array &&
131 type2.
id()==ID_array)
137 else if(type1.
id()==ID_code &&
151 for(std::size_t i=0; i<c_type1.
parameters().size(); i++)
167 if(type1.
get(ID_C_c_type)==type2.
get(ID_C_c_type))
177 if(expr.
id()==ID_side_effect)
179 else if(expr.
id()==ID_constant)
181 else if(expr.
id()==ID_infinity)
185 else if(expr.
id()==ID_symbol)
187 else if(expr.
id()==ID_unary_plus ||
188 expr.
id()==ID_unary_minus ||
189 expr.
id()==ID_bitnot)
191 else if(expr.
id()==ID_not)
194 expr.
id() == ID_and || expr.
id() == ID_or || expr.
id() == ID_implies ||
197 else if(expr.
id()==ID_address_of)
199 else if(expr.
id()==ID_dereference)
201 else if(expr.
id()==ID_member)
203 else if(expr.
id()==ID_ptrmember)
205 else if(expr.
id()==ID_equal ||
206 expr.
id()==ID_notequal ||
212 else if(expr.
id()==ID_index)
214 else if(expr.
id()==ID_typecast)
216 else if(expr.
id()==ID_sizeof)
218 else if(expr.
id()==ID_alignof)
221 expr.
id() == ID_plus || expr.
id() == ID_minus || expr.
id() == ID_mult ||
222 expr.
id() == ID_div || expr.
id() == ID_mod || expr.
id() == ID_bitand ||
223 expr.
id() == ID_bitxor || expr.
id() == ID_bitor || expr.
id() == ID_bitnand)
227 else if(expr.
id()==ID_shl || expr.
id()==ID_shr)
229 else if(expr.
id()==ID_comma)
231 else if(expr.
id()==ID_if)
233 else if(expr.
id()==ID_code)
236 error() <<
"typecheck_expr_main got code: " << expr.
pretty() <<
eom;
239 else if(expr.
id()==ID_gcc_builtin_va_arg)
241 else if(expr.
id()==ID_cw_va_arg_typeof)
243 else if(expr.
id()==ID_gcc_builtin_types_compatible_p)
248 assert(subtypes.size()==2);
254 subtypes[0].
remove(ID_C_constant);
255 subtypes[0].remove(ID_C_volatile);
256 subtypes[0].remove(ID_C_restricted);
257 subtypes[1].remove(ID_C_constant);
258 subtypes[1].remove(ID_C_volatile);
259 subtypes[1].remove(ID_C_restricted);
264 else if(expr.
id()==ID_clang_builtin_convertvector)
273 else if(expr.
id()==ID_builtin_offsetof)
275 else if(expr.
id()==ID_string_constant)
278 expr.
set(ID_C_lvalue,
true);
280 else if(expr.
id()==ID_arguments)
284 else if(expr.
id()==ID_designated_initializer)
286 exprt &designator=
static_cast<exprt &
>(expr.
add(ID_designator));
290 if(it->id()==ID_index)
294 else if(expr.
id()==ID_initializer_list)
300 expr.
id() == ID_forall || expr.
id() == ID_exists || expr.
id() == ID_lambda)
306 auto &bindings = binary_expr.op0().operands();
307 auto &where = binary_expr.op1();
309 for(
const auto &binding : bindings)
311 if(binding.get(ID_statement) != ID_decl)
314 error() <<
"expected declaration as operand of quantifier" <<
eom;
322 error() <<
"quantifier must not contain side effects" <<
eom;
327 for(
auto &binding : bindings)
330 if(expr.
id() == ID_lambda)
334 for(
auto &binding : bindings)
335 domain.push_back(binding.type());
345 else if(expr.
id()==ID_label)
349 else if(expr.
id()==ID_array)
353 else if(expr.
id()==ID_complex)
358 else if(expr.
id() == ID_complex_real)
362 if(op.
type().
id() != ID_complex)
367 error() <<
"real part retrieval expects numerical operand, "
375 expr.
swap(complex_real_expr);
383 complex_real_expr.
set(ID_C_lvalue,
true);
386 complex_real_expr.
type().
set(ID_C_constant,
true);
388 expr.
swap(complex_real_expr);
391 else if(expr.
id() == ID_complex_imag)
395 if(op.
type().
id() != ID_complex)
400 error() <<
"real part retrieval expects numerical operand, "
408 expr.
swap(complex_imag_expr);
416 complex_imag_expr.
set(ID_C_lvalue,
true);
419 complex_imag_expr.
type().
set(ID_C_constant,
true);
421 expr.
swap(complex_imag_expr);
424 else if(expr.
id()==ID_generic_selection)
434 if(op.type().id() == ID_bool)
441 for(
auto &irep : generic_associations)
443 if(irep.get(ID_type_arg) != ID_default)
445 typet &type =
static_cast<typet &
>(irep.add(ID_type_arg));
456 for(
const auto &irep : generic_associations)
458 if(irep.get(ID_type_arg) == ID_default)
459 default_match =
static_cast<const exprt &
>(irep.find(ID_value));
461 op_type ==
follow(
static_cast<const typet &
>(irep.find(ID_type_arg))))
463 assoc_match =
static_cast<const exprt &
>(irep.find(ID_value));
470 expr.
swap(default_match);
474 error() <<
"unmatched generic selection: " <<
to_string(op.type())
480 expr.
swap(assoc_match);
485 else if(expr.
id()==ID_gcc_asm_input ||
486 expr.
id()==ID_gcc_asm_output ||
487 expr.
id()==ID_gcc_asm_clobbered_register)
490 else if(expr.
id()==ID_lshr || expr.
id()==ID_ashr ||
491 expr.
id()==ID_assign_lshr || expr.
id()==ID_assign_ashr)
495 else if(expr.
id() == ID_C_spec_assigns || expr.
id() == ID_target_list)
513 expr.
set(ID_C_lvalue,
true);
550 symbol.
name=ID_gcc_builtin_va_arg;
551 symbol.
type=symbol_type;
581 error() <<
"builtin_offsetof expects no operands" <<
eom;
596 if(m_it->id()==ID_member)
598 if(type.
id()!=ID_union && type.
id()!=ID_struct)
601 error() <<
"offsetof of member expects struct/union type, "
607 irep_idt component_name=m_it->get(ID_component_name);
611 assert(type.
id()==ID_union || type.
id()==ID_struct);
621 if(type.
id()==ID_struct)
626 if(!o_opt.has_value())
629 error() <<
"offsetof failed to determine offset of '"
630 << component_name <<
"'" <<
eom;
646 for(
const auto &c : struct_union_type.
components())
650 (c.type().id() == ID_struct_tag || c.type().id() == ID_union_tag))
654 if(type.
id()==ID_struct)
659 if(!o_opt.has_value())
662 error() <<
"offsetof failed to determine offset of '"
663 << component_name <<
"'" <<
eom;
675 assert(type.
id()==ID_union || type.
id()==ID_struct);
685 error() <<
"offset-of of member failed to find component '"
686 << component_name <<
"' in '" <<
to_string(type) <<
"'"
693 else if(m_it->id()==ID_index)
695 if(type.
id()!=ID_array)
698 error() <<
"offsetof of index expects array type" <<
eom;
707 auto element_size_opt =
710 if(!element_size_opt.has_value())
713 error() <<
"offsetof failed to determine array element size" <<
eom;
736 if(expr.
id()==ID_side_effect &&
737 expr.
get(ID_statement)==ID_function_call)
742 else if(expr.
id()==ID_side_effect &&
743 expr.
get(ID_statement)==ID_statement_expression)
748 expr.
id() == ID_forall || expr.
id() == ID_exists || expr.
id() == ID_lambda)
754 auto &bindings = binary_expr.op0().operands();
756 for(
auto &binding : bindings)
765 error() <<
"forall/exists expects one declarator exactly" <<
eom;
772 symbol_tablet::symbolst::const_iterator s_it =
778 error() <<
"failed to find bound symbol `" << identifier
779 <<
"' in symbol table" <<
eom;
783 const symbolt &symbol = s_it->second;
790 error() <<
"unexpected quantified symbol" <<
eom;
814 id_type_mapt::const_iterator p_it=
parameter_map.find(identifier);
818 expr.
type()=p_it->second;
819 expr.
set(ID_C_lvalue,
true);
824 asm_label_mapt::const_iterator entry=
828 identifier=entry->second;
834 if(
lookup(identifier, symbol_ptr))
837 error() <<
"failed to find symbol '" << identifier <<
"'" <<
eom;
841 const symbolt &symbol=*symbol_ptr;
846 error() <<
"did not expect a type symbol here, but got '"
864 if(expr.
id()==ID_constant &&
866 expr.
set(ID_C_cformat, base_name);
881 else if(identifier==
"__func__" ||
882 identifier==
"__FUNCTION__" ||
883 identifier==
"__PRETTY_FUNCTION__")
889 s.
set(ID_C_lvalue,
true);
900 expr.
set(ID_C_lvalue,
true);
902 if(expr.
type().
id()==ID_code)
905 tmp.
set(ID_C_implicit,
true);
924 if(last_statement==ID_expression)
930 if(op.
type().
id()==ID_array)
964 if(op.
type().
id() == ID_bool)
972 if(type.
id()==ID_c_bit_field)
975 error() <<
"sizeof cannot be applied to bit fields" <<
eom;
978 else if(type.
id() == ID_bool)
981 error() <<
"sizeof cannot be applied to single bits" <<
eom;
984 else if(type.
id() == ID_empty)
993 (type.
id() == ID_struct_tag &&
995 (type.
id() == ID_union_tag &&
997 (type.
id() == ID_c_enum_tag &&
1002 error() <<
"invalid application of \'sizeof\' to an incomplete type\n\t\'"
1009 if(!size_of_opt.has_value())
1016 new_expr = size_of_opt.value();
1019 new_expr.
swap(expr);
1021 expr.
add(ID_C_c_sizeof_type)=type;
1029 decl_block.set_statement(ID_decl_block);
1040 std::move(side_effect_expr), ID_comma, expr, expr.
type()};
1041 expr.
swap(comma_expr);
1047 typet argument_type;
1055 argument_type=op_type;
1079 decl_block.set_statement(ID_decl_block);
1090 std::move(side_effect_expr), ID_comma, op, op.
type()};
1091 op.
swap(comma_expr);
1097 expr_type.
id() == ID_union_tag && expr_type != op.
type() &&
1098 op.
id() != ID_initializer_list)
1106 if(op.
type().
id() == ID_bool)
1111 for(
const auto &c : union_type.components())
1113 if(c.type() == op.
type())
1119 expr.
set(ID_C_lvalue,
true);
1127 <<
"' not found in union" <<
eom;
1134 if(op.
id()==ID_initializer_list)
1143 exprt tmp(ID_compound_literal, expr.
type());
1147 if(op.
id()==ID_array &&
1148 expr.
type().
id()==ID_array &&
1153 expr.
set(ID_C_lvalue,
true);
1158 if(expr_type.
id()==ID_empty)
1164 if(expr_type == op_type)
1169 if(expr_type.
id()==ID_vector)
1172 if(op_type.
id()==ID_vector)
1174 else if(op_type.
id()==ID_signedbv ||
1175 op_type.
id()==ID_unsignedbv)
1182 error() <<
"type cast to '" <<
to_string(expr_type) <<
"' is not permitted"
1190 else if(op_type.
id()==ID_array)
1195 else if(op_type.
id()==ID_empty)
1197 if(expr_type.
id()!=ID_empty)
1200 error() <<
"type cast from void only permitted to void, but got '"
1205 else if(op_type.
id()==ID_vector)
1212 if((expr_type.
id()==ID_signedbv ||
1213 expr_type.
id()==ID_unsignedbv) &&
1222 <<
"' not permitted" <<
eom;
1229 error() <<
"type cast from '" <<
to_string(op_type) <<
"' not permitted"
1245 if(expr_type.
id()==ID_pointer)
1246 expr.
set(ID_C_lvalue,
true);
1263 const typet &array_type = array_expr.
type();
1267 array_type.
id() != ID_array && array_type.
id() != ID_pointer &&
1268 array_type.
id() != ID_vector &&
1271 std::swap(array_expr, index_expr);
1279 const typet final_array_type = array_expr.
type();
1281 if(final_array_type.
id()==ID_array ||
1282 final_array_type.
id()==ID_vector)
1286 if(array_expr.
get_bool(ID_C_lvalue))
1287 expr.
set(ID_C_lvalue,
true);
1289 if(final_array_type.
get_bool(ID_C_constant))
1290 expr.
type().
set(ID_C_constant,
true);
1292 else if(final_array_type.
id()==ID_pointer)
1298 std::swap(summands, expr.
operands());
1300 expr.
id(ID_dereference);
1301 expr.
set(ID_C_lvalue,
true);
1307 error() <<
"operator [] must take array/vector or pointer but got '"
1316 if(expr.
op0().
type().
id() == ID_floatbv)
1318 if(expr.
id()==ID_equal)
1319 expr.
id(ID_ieee_float_equal);
1320 else if(expr.
id()==ID_notequal)
1321 expr.
id(ID_ieee_float_notequal);
1334 if(o_type0.
id() == ID_vector || o_type1.
id() == ID_vector)
1342 if(expr.
id()==ID_equal || expr.
id()==ID_notequal)
1346 if(o_type0.
id() != ID_array)
1367 if(type0.
id()==ID_pointer)
1369 if(expr.
id()==ID_equal || expr.
id()==ID_notequal)
1372 if(expr.
id()==ID_le || expr.
id()==ID_lt ||
1373 expr.
id()==ID_ge || expr.
id()==ID_gt)
1377 if(type0.
id()==ID_string_constant)
1379 if(expr.
id()==ID_equal || expr.
id()==ID_notequal)
1386 if(type0.
id()==ID_pointer &&
1393 if(type1.
id()==ID_pointer &&
1413 if(type0.
id()==ID_pointer && type1.
id()==ID_pointer)
1421 error() <<
"operator '" << expr.
id() <<
"' not defined for types '"
1432 if(o_type0.
id() != ID_vector || o_type0 != o_type1)
1435 error() <<
"vector operator '" << expr.
id() <<
"' not defined for types '"
1443 auto subtype_width =
1452 if(expr.
id() == ID_notequal)
1453 expr.
id(ID_vector_notequal);
1461 const typet &op0_type = op.type();
1463 if(op0_type.
id() == ID_array)
1468 index_expr.
set(ID_C_lvalue,
true);
1469 op.swap(index_expr);
1471 else if(op0_type.
id() == ID_pointer)
1477 op.swap(deref_expr);
1482 error() <<
"ptrmember operator requires pointer or array type "
1483 "on left hand side, but got '"
1499 if(type.
id()!=ID_struct &&
1500 type.
id()!=ID_union)
1503 error() <<
"member operator requires structure type "
1504 "on left hand side but got '"
1515 error() <<
"member operator got incomplete " << type.
id()
1516 <<
" type on left hand side" <<
eom;
1521 expr.
get(ID_component_name);
1537 error() <<
"member '" << component_name <<
"' not found in '"
1550 expr.
set(ID_C_lvalue,
true);
1553 expr.
type().
set(ID_C_constant,
true);
1558 if(!identifier.
empty())
1559 expr.
set(ID_C_identifier, identifier);
1563 if(access==ID_private)
1566 error() <<
"member '" << component_name <<
"' is " << access <<
eom;
1575 assert(operands.size()==3);
1578 const typet o_type0=operands[0].type();
1579 const typet o_type1=operands[1].type();
1580 const typet o_type2=operands[2].type();
1584 if(o_type1.
id() == ID_empty || o_type2.
id() == ID_empty)
1592 if(operands[1].type().
id()==ID_pointer &&
1593 operands[2].type().
id()!=ID_pointer)
1595 else if(operands[2].type().
id()==ID_pointer &&
1596 operands[1].type().
id()!=ID_pointer)
1599 if(operands[1].type().
id()==ID_pointer &&
1600 operands[2].type().
id()==ID_pointer &&
1601 operands[1].type()!=operands[2].type())
1648 if(operands[1].type().
id()==ID_empty ||
1649 operands[2].type().
id()==ID_empty)
1656 operands[1].type() != operands[2].type() ||
1657 operands[1].type().
id() == ID_array)
1662 if(operands[1].type() == operands[2].type())
1664 expr.
type()=operands[1].type();
1670 if(operands[1].get_bool(ID_C_lvalue) &&
1671 operands[2].get_bool(ID_C_lvalue))
1672 expr.
set(ID_C_lvalue,
true);
1678 error() <<
"operator ?: not defined for types '" <<
to_string(o_type1)
1691 if(operands.size()!=2)
1694 error() <<
"gcc conditional_expr expects two operands" <<
eom;
1700 if_exprt if_expr(operands[0], operands[0], operands[1]);
1715 if(op.
type().
id()==ID_c_bit_field)
1718 error() <<
"cannot take address of a bit field" <<
eom;
1722 if(op.
type().
id() == ID_bool)
1725 error() <<
"cannot take address of a single bit" <<
eom;
1730 if(op.
id()==ID_label)
1743 op.
id() == ID_address_of && op.
get_bool(ID_C_implicit) &&
1749 tmp.
set(ID_C_implicit,
false);
1754 if(op.
id()==ID_struct ||
1755 op.
id()==ID_union ||
1756 op.
id()==ID_array ||
1757 op.
id()==ID_string_constant)
1765 else if(op.
type().
id()==ID_code)
1772 error() <<
"address_of error: '" <<
to_string(op) <<
"' not an lvalue"
1786 if(op_type.
id()==ID_array)
1794 else if(op_type.
id()==ID_pointer)
1799 expr.
type().
id() == ID_empty &&
1803 error() <<
"dereferencing void pointer" <<
eom;
1811 <<
"' is not a pointer, but got '" <<
to_string(op_type) <<
"'"
1816 expr.
set(ID_C_lvalue,
true);
1827 if(expr.
type().
id()==ID_code)
1830 tmp.
set(ID_C_implicit,
true);
1840 if(statement==ID_preincrement ||
1841 statement==ID_predecrement ||
1842 statement==ID_postincrement ||
1843 statement==ID_postdecrement)
1852 <<
"' not an lvalue" <<
eom;
1863 if(type0.
id() == ID_c_enum_tag)
1869 error() <<
"operator '" << statement <<
"' given incomplete type '"
1879 else if(type0.
id() == ID_c_bit_field)
1884 expr.
type()=underlying_type;
1886 else if(type0.
id() == ID_bool || type0.
id() == ID_c_bool)
1895 else if(type0.
id() == ID_pointer)
1903 error() <<
"operator '" << statement <<
"' not defined for type '"
1910 else if(statement==ID_function_call)
1913 else if(statement==ID_statement_expression)
1915 else if(statement==ID_gcc_conditional_expression)
1920 error() <<
"unknown side effect: " << statement <<
eom;
1932 "expression must be a " CPROVER_PREFIX "typed_target function call");
1939 "expected 1 argument for " CPROVER_PREFIX "typed_target, found " +
1950 arg0.source_location()};
1954 if(!size.has_value())
1958 "typed_target of type " +
1960 arg0.source_location()};
1969 arguments.push_back(size.value());
1971 if(arg0.type().id() == ID_pointer)
1986 error() <<
"function_call side effect expects two operands" <<
eom;
1995 if(f_op.
id()==ID_symbol)
1999 asm_label_mapt::const_iterator entry=
2002 identifier=entry->second;
2019 identifier ==
"__noop" &&
2033 identifier ==
"__builtin_shuffle" &&
2042 identifier ==
"__builtin_shufflevector" &&
2063 irep_idt identifier_with_type = gcc_polymorphic->get_identifier();
2066 !parameters.empty(),
2067 "GCC polymorphic built-ins should have at least one parameter");
2072 if(parameters.front().type().id() == ID_pointer)
2074 identifier_with_type =
2081 identifier_with_type =
2085 gcc_polymorphic->set_identifier(identifier_with_type);
2089 for(std::size_t i = 0; i < parameters.size(); ++i)
2096 id2string(identifier_with_type) +
"::" + base_name;
2099 new_symbol.
type = parameters[i].type();
2102 new_symbol.
mode = ID_C;
2104 parameters[i].set_identifier(new_symbol.
name);
2105 parameters[i].set_base_name(new_symbol.
base_name);
2112 new_symbol.
name = identifier_with_type;
2113 new_symbol.
base_name = identifier_with_type;
2115 new_symbol.
type = gcc_polymorphic->type();
2116 new_symbol.
mode = ID_C;
2123 new_symbol.
value = implementation;
2128 f_op = std::move(*gcc_polymorphic);
2140 if(identifier==
"malloc" ||
2141 identifier==
"realloc" ||
2142 identifier==
"reallocf" ||
2143 identifier==
"valloc")
2150 new_symbol.
name=identifier;
2154 new_symbol.
type.
set(ID_C_incomplete,
true);
2162 warning() <<
"function '" << identifier <<
"' is not declared" <<
eom;
2172 if(f_op_type.
id() == ID_mathematical_function)
2174 const auto &mathematical_function_type =
2178 if(expr.
arguments().size() != mathematical_function_type.domain().size())
2181 error() <<
"expected " << mathematical_function_type.domain().size()
2182 <<
" arguments but got " << expr.
arguments().size() <<
eom;
2190 if(p.first.type() != p.second)
2203 expr.
swap(function_application);
2207 if(f_op_type.
id()!=ID_pointer)
2210 error() <<
"expected function/function pointer as argument but got '"
2216 if(f_op.
id() == ID_address_of && f_op.
get_bool(ID_C_implicit))
2223 tmp.
set(ID_C_implicit,
true);
2228 if(f_op.
type().
id()!=ID_code)
2231 error() <<
"expected code as argument" <<
eom;
2254 if(f_op.
id()!=ID_symbol)
2276 error() <<
"same_object expects two operands" <<
eom;
2282 exprt same_object_expr=
2286 return same_object_expr;
2293 error() <<
"get_must expects two operands" <<
eom;
2303 return std::move(get_must_expr);
2310 error() <<
"get_may expects two operands" <<
eom;
2320 return std::move(get_may_expr);
2327 error() <<
"is_invalid_pointer expects one operand" <<
eom;
2336 return same_object_expr;
2343 error() <<
"buffer_size expects one operand" <<
eom;
2353 return buffer_size_expr;
2361 error() <<
"is_list expects one operand" <<
eom;
2368 expr.
arguments()[0].type().id() != ID_pointer ||
2373 error() <<
"is_list expects a struct-pointer operand" <<
eom;
2381 return std::move(is_list_expr);
2389 error() <<
"is_dll expects one operand" <<
eom;
2396 expr.
arguments()[0].type().id() != ID_pointer ||
2401 error() <<
"is_dll expects a struct-pointer operand" <<
eom;
2409 return std::move(is_dll_expr);
2417 error() <<
"is_cyclic_dll expects one operand" <<
eom;
2424 expr.
arguments()[0].type().id() != ID_pointer ||
2429 error() <<
"is_cyclic_dll expects a struct-pointer operand" <<
eom;
2437 return std::move(is_cyclic_dll_expr);
2445 error() <<
"is_sentinel_dll expects two or three operands" <<
eom;
2451 for(
const auto &argument : expr.
arguments())
2454 argument.type().id() != ID_pointer ||
2458 error() <<
"is_sentinel_dll_node expects struct-pointer operands"
2468 return std::move(is_sentinel_dll_expr);
2476 error() <<
"is_cstring expects one operand" <<
eom;
2482 if(expr.
arguments()[0].type().id() != ID_pointer)
2485 error() <<
"is_cstring expects a pointer operand" <<
eom;
2492 return std::move(is_cstring_expr);
2500 error() <<
"cstrlen expects one operand" <<
eom;
2506 if(expr.
arguments()[0].type().id() != ID_pointer)
2509 error() <<
"cstrlen expects a pointer operand" <<
eom;
2516 return std::move(cstrlen_expr);
2523 error() <<
"is_zero_string expects one operand" <<
eom;
2531 is_zero_string_expr.
set(ID_C_lvalue,
true);
2534 return std::move(is_zero_string_expr);
2541 error() <<
"zero_string_length expects one operand" <<
eom;
2547 exprt zero_string_length_expr(
"zero_string_length",
size_type());
2549 zero_string_length_expr.
set(ID_C_lvalue,
true);
2552 return zero_string_length_expr;
2559 error() <<
"dynamic_object expects one argument" <<
eom;
2568 return is_dynamic_object_expr;
2575 error() <<
"live_object expects one argument" <<
eom;
2584 return live_object_expr;
2591 error() <<
"writeable_object expects one argument" <<
eom;
2600 return writeable_object_expr;
2607 error() <<
"pointer_offset expects one argument" <<
eom;
2623 error() <<
"object_size expects one operand" <<
eom;
2632 return std::move(object_size_expr);
2639 error() <<
"pointer_object expects one argument" <<
eom;
2650 else if(identifier==
"__builtin_bswap16" ||
2651 identifier==
"__builtin_bswap32" ||
2652 identifier==
"__builtin_bswap64")
2657 error() << identifier <<
" expects one operand" <<
eom;
2667 return std::move(bswap_expr);
2670 identifier ==
"__builtin_rotateleft8" ||
2671 identifier ==
"__builtin_rotateleft16" ||
2672 identifier ==
"__builtin_rotateleft32" ||
2673 identifier ==
"__builtin_rotateleft64" ||
2674 identifier ==
"__builtin_rotateright8" ||
2675 identifier ==
"__builtin_rotateright16" ||
2676 identifier ==
"__builtin_rotateright32" ||
2677 identifier ==
"__builtin_rotateright64")
2683 error() << identifier <<
" expects two operands" <<
eom;
2689 irep_idt id = (identifier ==
"__builtin_rotateleft8" ||
2690 identifier ==
"__builtin_rotateleft16" ||
2691 identifier ==
"__builtin_rotateleft32" ||
2692 identifier ==
"__builtin_rotateleft64")
2699 return std::move(rotate_expr);
2701 else if(identifier==
"__builtin_nontemporal_load")
2706 error() << identifier <<
" expects one operand" <<
eom;
2715 if(ptr_arg.
type().
id()!=ID_pointer)
2718 error() <<
"__builtin_nontemporal_load takes pointer as argument" <<
eom;
2727 identifier ==
"__builtin_fpclassify" ||
2733 error() << identifier <<
" expects six arguments" <<
eom;
2746 if(fp_value.
type().
id() != ID_floatbv)
2749 error() <<
"non-floating-point argument for " << identifier <<
eom;
2757 const auto &arguments = expr.
arguments();
2776 identifier==
"__builtin_isnan")
2781 error() <<
"isnan expects one operand" <<
eom;
2799 error() <<
"isfinite expects one operand" <<
eom;
2811 identifier==
"__builtin_inf")
2818 return std::move(inf_expr);
2827 return std::move(inff_expr);
2836 return std::move(infl_expr);
2848 error() <<
"abs-functions expect one operand" <<
eom;
2857 return std::move(abs_expr);
2867 error() <<
"fmod-functions expect two operands" <<
eom;
2881 return std::move(fmod_expr);
2891 error() <<
"remainder-functions expect two operands" <<
eom;
2905 return std::move(floatbv_rem_expr);
2912 error() <<
"allocate expects two operands" <<
eom;
2921 return std::move(malloc_expr);
2930 error() << identifier <<
" expects one or two operands" <<
eom;
2937 const auto &pointer_expr = expr.
arguments()[0];
2938 if(pointer_expr.type().id() != ID_pointer)
2941 error() << identifier <<
" expects a pointer as first argument" <<
eom;
2958 if(subtype.id() == ID_empty)
2961 error() << identifier <<
" expects a size when given a void pointer"
2967 if(!size_expr_opt.has_value())
2970 error() << identifier <<
" was given object pointer without size"
2975 size_expr = std::move(size_expr_opt.value());
2985 return std::move(ok_expr);
2994 error() << identifier <<
" expects one operand" <<
eom;
2998 const auto ¶m_id = expr.
arguments().front().id();
2999 if(!(param_id == ID_dereference || param_id == ID_member ||
3000 param_id == ID_symbol || param_id == ID_ptrmember ||
3001 param_id == ID_constant || param_id == ID_typecast ||
3002 param_id == ID_index))
3005 error() <<
"Tracking history of " << param_id
3006 <<
" expressions is not supported yet." <<
eom;
3015 return std::move(old_expr);
3020 identifier==
"__builtin_isinf")
3025 error() << identifier <<
" expects one operand" <<
eom;
3033 if(fp_value.
type().
id() != ID_floatbv)
3036 error() <<
"non-floating-point argument for " << identifier <<
eom;
3045 else if(identifier ==
"__builtin_isinf_sign")
3050 error() << identifier <<
" expects one operand" <<
eom;
3060 if(fp_value.
type().
id() != ID_floatbv)
3063 error() <<
"non-floating-point argument for " << identifier <<
eom;
3081 identifier ==
"__builtin_isnormal")
3086 error() << identifier <<
" expects one operand" <<
eom;
3094 if(fp_value.
type().
id() != ID_floatbv)
3097 error() <<
"non-floating-point argument for " << identifier <<
eom;
3109 identifier==
"__builtin_signbit" ||
3110 identifier==
"__builtin_signbitf" ||
3111 identifier==
"__builtin_signbitl")
3116 error() << identifier <<
" expects one operand" <<
eom;
3127 else if(identifier==
"__builtin_popcount" ||
3128 identifier==
"__builtin_popcountl" ||
3129 identifier==
"__builtin_popcountll" ||
3130 identifier==
"__popcnt16" ||
3131 identifier==
"__popcnt" ||
3132 identifier==
"__popcnt64")
3137 error() << identifier <<
" expects one operand" <<
eom;
3146 return std::move(popcount_expr);
3149 identifier ==
"__builtin_clz" || identifier ==
"__builtin_clzl" ||
3150 identifier ==
"__builtin_clzll" || identifier ==
"__lzcnt16" ||
3151 identifier ==
"__lzcnt" || identifier ==
"__lzcnt64")
3156 error() << identifier <<
" expects one operand" <<
eom;
3167 return std::move(clz);
3170 identifier ==
"__builtin_ctz" || identifier ==
"__builtin_ctzl" ||
3171 identifier ==
"__builtin_ctzll")
3176 error() << identifier <<
" expects one operand" <<
eom;
3186 return std::move(ctz);
3189 identifier ==
"__builtin_ffs" || identifier ==
"__builtin_ffsl" ||
3190 identifier ==
"__builtin_ffsll")
3195 error() << identifier <<
" expects one operand" <<
eom;
3204 return std::move(ffs);
3211 error() <<
"equal expects two operands" <<
eom;
3224 error() <<
"equal expects two operands of same type" <<
eom;
3228 return std::move(equality_expr);
3230 else if(identifier==
"__builtin_expect")
3241 error() <<
"__builtin_expect expects two arguments" <<
eom;
3249 else if(identifier==
"__builtin_object_size")
3258 error() <<
"__builtin_object_size expects two arguments" <<
eom;
3275 error() <<
"__builtin_object_size expects constant as second argument, "
3283 if(arg1==0 || arg1==1)
3296 else if(identifier==
"__builtin_choose_expr")
3302 error() <<
"__builtin_choose_expr expects three arguments" <<
eom;
3317 else if(identifier==
"__builtin_constant_p")
3324 error() <<
"__builtin_constant_p expects one argument" <<
eom;
3340 tmp1.
id() == ID_typecast &&
3346 .
id() == ID_string_constant)
3358 else if(identifier==
"__builtin_classify_type")
3365 error() <<
"__builtin_classify_type expects one argument" <<
eom;
3378 if(type.
id() == ID_c_bit_field)
3381 unsigned type_number;
3383 if(type.
id() == ID_bool || type.
id() == ID_c_bool)
3392 type.
id() == ID_empty
3394 : (type.
id() == ID_bool || type.
id() == ID_c_bool)
3396 : (type.
id() == ID_pointer || type.
id() == ID_array)
3398 : type.
id() == ID_floatbv
3400 : (type.
id() == ID_complex &&
3403 : type.
id() == ID_struct
3405 : type.
id() == ID_union
3426 overflow.
id(ID_minus);
3431 overflow.id(ID_mult);
3436 overflow.id(ID_plus);
3441 overflow.id(ID_shl);
3446 overflow.
operands()[0], overflow.id(), overflow.operands()[1]};
3447 of.add_source_location() = overflow.source_location();
3448 return std::move(of);
3458 overflow.add_source_location() = tmp.source_location();
3459 return std::move(overflow);
3466 std::ostringstream error_message;
3467 error_message << identifier <<
" takes exactly 1 argument, but "
3468 << expr.
arguments().size() <<
" were provided";
3477 std::ostringstream error_message;
3478 error_message << identifier <<
" expects enum, but ("
3479 <<
expr2c(arg1, *
this) <<
") has type `"
3480 <<
type2c(arg1.type(), *
this) <<
'`';
3490 identifier ==
"__builtin_add_overflow" ||
3491 identifier ==
"__builtin_sadd_overflow" ||
3492 identifier ==
"__builtin_saddl_overflow" ||
3493 identifier ==
"__builtin_saddll_overflow" ||
3494 identifier ==
"__builtin_uadd_overflow" ||
3495 identifier ==
"__builtin_uaddl_overflow" ||
3496 identifier ==
"__builtin_uaddll_overflow" ||
3497 identifier ==
"__builtin_add_overflow_p")
3502 identifier ==
"__builtin_sub_overflow" ||
3503 identifier ==
"__builtin_ssub_overflow" ||
3504 identifier ==
"__builtin_ssubl_overflow" ||
3505 identifier ==
"__builtin_ssubll_overflow" ||
3506 identifier ==
"__builtin_usub_overflow" ||
3507 identifier ==
"__builtin_usubl_overflow" ||
3508 identifier ==
"__builtin_usubll_overflow" ||
3509 identifier ==
"__builtin_sub_overflow_p")
3514 identifier ==
"__builtin_mul_overflow" ||
3515 identifier ==
"__builtin_smul_overflow" ||
3516 identifier ==
"__builtin_smull_overflow" ||
3517 identifier ==
"__builtin_smulll_overflow" ||
3518 identifier ==
"__builtin_umul_overflow" ||
3519 identifier ==
"__builtin_umull_overflow" ||
3520 identifier ==
"__builtin_umulll_overflow" ||
3521 identifier ==
"__builtin_mul_overflow_p")
3526 identifier ==
"__builtin_bitreverse8" ||
3527 identifier ==
"__builtin_bitreverse16" ||
3528 identifier ==
"__builtin_bitreverse32" ||
3529 identifier ==
"__builtin_bitreverse64")
3534 std::ostringstream error_message;
3535 error_message <<
"error: " << identifier <<
" expects one operand";
3543 bitreverse.add_source_location() = source_location;
3545 return std::move(bitreverse);
3561 std::ostringstream error_message;
3562 error_message << identifier <<
" takes exactly 3 arguments, but "
3563 << expr.
arguments().size() <<
" were provided";
3577 auto const raise_wrong_argument_error =
3579 const exprt &wrong_argument, std::size_t argument_number,
bool _p) {
3580 std::ostringstream error_message;
3581 error_message <<
"error: " << identifier <<
" has signature "
3582 << identifier <<
"(integral, integral, integral"
3583 << (_p ?
"" :
"*") <<
"), "
3584 <<
"but argument " << argument_number <<
" ("
3585 <<
expr2c(wrong_argument, *
this) <<
") has type `"
3586 <<
type2c(wrong_argument.
type(), *
this) <<
'`';
3590 for(
int arg_index = 0; arg_index <= (!is__p_variant ? 1 : 2); ++arg_index)
3592 auto const &argument = expr.
arguments()[arg_index];
3596 raise_wrong_argument_error(argument, arg_index + 1, is__p_variant);
3600 !is__p_variant && (
result.type().id() != ID_pointer ||
3604 raise_wrong_argument_error(
result, 3, is__p_variant);
3623 std::ostringstream error_message;
3624 error_message <<
"error: " << identifier
3625 <<
" takes exactly two arguments, but "
3626 << expr.
arguments().size() <<
" were provided";
3658 if(code_type.
get_bool(ID_C_incomplete))
3662 else if(code_type.
is_KnR())
3667 while(parameter_types.size()>arguments.size())
3672 if(parameter_types.size()>arguments.size())
3675 error() <<
"not enough function arguments" <<
eom;
3679 else if(parameter_types.size()!=arguments.size())
3682 error() <<
"wrong number of function arguments: "
3683 <<
"expected " << parameter_types.size()
3684 <<
", but got " << arguments.size() <<
eom;
3688 for(std::size_t i=0; i<arguments.size(); i++)
3690 exprt &op=arguments[i];
3696 else if(i<parameter_types.size())
3701 const typet &op_type=parameter_type.
type();
3703 if(op_type.
id()==ID_bool &&
3704 op.
id()==ID_side_effect &&
3705 op.
get(ID_statement)==ID_assign &&
3709 warning() <<
"assignment where Boolean argument is expected" <<
eom;
3718 if(op.
type().
id() == ID_array)
3721 dest_type.base_type().set(ID_C_constant,
true);
3739 if(o_type.
id()==ID_vector)
3758 error() <<
"operator '" << expr.
id() <<
"' not defined for type '"
3782 const auto s0 = numeric_cast<mp_integer>(type0.
size());
3783 const auto s1 = numeric_cast<mp_integer>(type1.
size());
3813 if(o_type0.
id()==ID_vector &&
3814 o_type1.
id()==ID_vector)
3828 o_type0.
id() == ID_vector && o_type1.
id() != ID_vector &&
3833 expr.
type() = o_type0;
3837 o_type0.
id() != ID_vector && o_type1.
id() == ID_vector &&
3842 expr.
type() = o_type1;
3846 if(expr.
id() == ID_saturating_minus || expr.
id() == ID_saturating_plus)
3859 if(expr.
id()==ID_plus || expr.
id()==ID_minus ||
3860 expr.
id()==ID_mult || expr.
id()==ID_div)
3862 if(type0.
id()==ID_pointer || type1.
id()==ID_pointer)
3867 else if(type0==type1)
3876 else if(expr.
id()==ID_mod)
3880 if(type0.
id()==ID_signedbv || type0.
id()==ID_unsignedbv)
3888 expr.
id() == ID_bitand || expr.
id() == ID_bitnand ||
3889 expr.
id() == ID_bitxor || expr.
id() == ID_bitor)
3898 else if(type0.
id()==ID_bool)
3900 if(expr.
id()==ID_bitand)
3902 else if(expr.
id() == ID_bitnand)
3904 else if(expr.
id()==ID_bitor)
3906 else if(expr.
id()==ID_bitxor)
3915 else if(expr.
id() == ID_saturating_minus || expr.
id() == ID_saturating_plus)
3919 (type0.
id() == ID_signedbv || type0.
id() == ID_unsignedbv))
3921 expr.
type() = type0;
3927 error() <<
"operator '" << expr.
id() <<
"' not defined for types '"
3935 assert(expr.
id()==ID_shl || expr.
id()==ID_shr);
3943 if(o_type0.
id()==ID_vector &&
3944 o_type1.
id()==ID_vector)
3960 o_type0.
id() == ID_vector &&
3978 if(expr.
id()==ID_shr)
3982 if(op0_type.
id()==ID_unsignedbv)
3987 else if(op0_type.
id()==ID_signedbv)
3998 error() <<
"operator '" << expr.
id() <<
"' not defined for types '"
4012 base_type.
id() == ID_struct_tag &&
4016 error() <<
"pointer arithmetic with unknown object size" <<
eom;
4020 base_type.
id() == ID_union_tag &&
4024 error() <<
"pointer arithmetic with unknown object size" <<
eom;
4028 base_type.
id() == ID_empty &&
4032 error() <<
"pointer arithmetic with unknown object size" <<
eom;
4046 if(expr.
id()==ID_minus ||
4047 (expr.
id()==ID_side_effect && expr.
get(ID_statement)==ID_assign_minus))
4049 if(type0.
id()==ID_pointer &&
4050 type1.
id()==ID_pointer)
4060 if(type0.
id()==ID_pointer &&
4061 (type1.
id()==ID_bool ||
4062 type1.
id()==ID_c_bool ||
4063 type1.
id()==ID_unsignedbv ||
4064 type1.
id()==ID_signedbv ||
4065 type1.
id()==ID_c_bit_field ||
4066 type1.
id()==ID_c_enum_tag))
4074 else if(expr.
id()==ID_plus ||
4075 (expr.
id()==ID_side_effect && expr.
get(ID_statement)==ID_assign_plus))
4077 exprt *p_op, *int_op;
4079 if(type0.
id()==ID_pointer)
4084 else if(type1.
id()==ID_pointer)
4091 p_op=int_op=
nullptr;
4095 const typet &int_op_type = int_op->
type();
4097 if(int_op_type.
id()==ID_bool ||
4098 int_op_type.
id()==ID_c_bool ||
4099 int_op_type.
id()==ID_unsignedbv ||
4100 int_op_type.
id()==ID_signedbv ||
4101 int_op_type.
id()==ID_c_bit_field ||
4102 int_op_type.
id()==ID_c_enum_tag)
4113 if(expr.
id()==ID_side_effect)
4119 error() <<
"operator '" << op_name <<
"' not defined for types '"
4150 if(type0.
id()==ID_empty)
4153 error() <<
"cannot assign void" <<
eom;
4160 error() <<
"assignment error: '" <<
to_string(op0) <<
"' not an lvalue"
4173 if(type0.
id() == ID_array)
4176 error() <<
"direct assignments to arrays not permitted" <<
eom;
4183 if(op0.
type().
id()==ID_c_bit_field)
4190 expr.
type()=o_type0;
4192 if(statement==ID_assign)
4197 else if(statement==ID_assign_shl ||
4198 statement==ID_assign_shr)
4200 if(o_type0.
id() == ID_vector)
4205 o_type1.
id() == ID_vector &&
4206 vector_o_type0.element_type() ==
4208 is_number(vector_o_type0.element_type()))
4224 if(statement==ID_assign_shl)
4234 if(underlying_type.
id()==ID_unsignedbv ||
4235 underlying_type.
id()==ID_c_bool)
4237 expr.
set(ID_statement, ID_assign_lshr);
4240 else if(underlying_type.
id()==ID_signedbv)
4242 expr.
set(ID_statement, ID_assign_ashr);
4248 else if(statement==ID_assign_bitxor ||
4249 statement==ID_assign_bitand ||
4250 statement==ID_assign_bitor)
4253 if(o_type0.
id()==ID_bool ||
4254 o_type0.
id()==ID_c_bool)
4258 op1.
type().
id() == ID_bool || op1.
type().
id() == ID_c_bool ||
4259 op1.
type().
id() == ID_c_enum_tag || op1.
type().
id() == ID_unsignedbv ||
4260 op1.
type().
id() == ID_signedbv || op1.
type().
id() == ID_c_bit_field)
4265 else if(o_type0.
id()==ID_c_enum_tag ||
4266 o_type0.
id()==ID_unsignedbv ||
4267 o_type0.
id()==ID_signedbv ||
4268 o_type0.
id()==ID_c_bit_field)
4272 op1.
type().
id() == ID_c_enum_tag || op1.
type().
id() == ID_unsignedbv ||
4273 op1.
type().
id() == ID_signedbv || op1.
type().
id() == ID_c_bit_field)
4278 else if(o_type0.
id()==ID_vector &&
4279 o_type1.
id()==ID_vector)
4290 o_type0.
id() == ID_vector &&
4291 (o_type1.
id() == ID_bool || o_type1.
id() == ID_c_bool ||
4292 o_type1.
id() == ID_c_enum_tag || o_type1.
id() == ID_unsignedbv ||
4293 o_type1.
id() == ID_signedbv))
4302 if(o_type0.
id()==ID_pointer &&
4303 (statement==ID_assign_minus || statement==ID_assign_plus))
4308 else if(o_type0.
id()==ID_vector &&
4309 o_type1.
id()==ID_vector)
4319 else if(o_type0.
id() == ID_vector)
4325 op1.
type().
id() == ID_c_bool || op1.
type().
id() == ID_c_enum_tag)
4331 else if(o_type0.
id()==ID_bool ||
4332 o_type0.
id()==ID_c_bool)
4335 if(op1.
type().
id()==ID_bool ||
4336 op1.
type().
id()==ID_c_bool ||
4337 op1.
type().
id()==ID_c_enum_tag ||
4338 op1.
type().
id()==ID_unsignedbv ||
4339 op1.
type().
id()==ID_signedbv)
4347 op1.
type().
id()==ID_bool ||
4348 op1.
type().
id()==ID_c_bool ||
4349 op1.
type().
id()==ID_c_enum_tag)
4355 error() <<
"assignment '" << statement <<
"' not defined for types '"
4374 if(e.
id() == ID_infinity)
4382 if(e.
id() == ID_symbol)
4384 return e.
type().
id() == ID_code ||
4387 else if(e.
id() == ID_array && e.
get_bool(ID_C_string_constant))
4399 const auto rounding_mode =
4408 error() <<
"expected constant expression, but got '" <<
to_string(expr)
4423 error() <<
"conversion to integer constant failed" <<
eom;
4431 const std::string &message)
const
virtual void do_initializer(exprt &initializer, const typet &type, bool force_constant)
Determine whether an expression is constant.
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
#define UNREACHABLE
This should be used to mark dead code.
const componentst & components() const
virtual void typecheck_expr_side_effect(side_effect_exprt &expr)
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
const irep_idt & get_function() const
bool has_ellipsis() const
A codet representing sequential composition of program statements.
static exprt conditional_cast(const exprt &expr, const typet &type)
virtual void implicit_typecast_arithmetic(exprt &expr)
bool is_assignable(const exprt &expr)
Returns true iff the argument is one of the following:
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
exprt get_component_rec(const exprt &struct_union, const irep_idt &component_name, const namespacet &ns)
Type with multiple subtypes.
bool gcc_vector_types_compatible(const vector_typet &, const vector_typet &)
static code_blockt from_list(const std::list< codet > &_list)
side_effect_expr_function_callt & to_side_effect_expr_function_call(exprt &expr)
bool has_subexpr(const exprt &expr, const std::function< bool(const exprt &)> &pred)
returns true if the expression has a subexpression that satisfies pred
exprt pointer_object(const exprt &p)
const declaratorst & declarators() const
bool is_incomplete() const
enum types may be incomplete
#define Forall_operands(it, expr)
The count trailing zeros (counting the number of zero bits starting from the least-significant bit) e...
bool is_number(const typet &type)
Returns true if the type is a rational, real, integer, natural, complex, unsignedbv,...
virtual void typecheck_expr_builtin_offsetof(exprt &expr)
const componentt & get_component(const irep_idt &component_name) const
Get the reference to a component with given name.
virtual void typecheck_expr_shifts(shift_exprt &expr)
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
virtual exprt do_special_functions(side_effect_expr_function_callt &expr)
const irep_idt & display_name() const
Return language specific display name if present.
The type of an expression, extends irept.
already_typechecked_exprt & to_already_typechecked_expr(exprt &expr)
std::vector< parametert > parameterst
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
void typecheck_declaration(ansi_c_declarationt &)
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
virtual std::string to_string(const exprt &expr)
virtual void adjust_float_rel(binary_relation_exprt &)
Base type for structs and unions.
typet type
Type of symbol.
floatbv_typet long_double_type()
Operator to dereference a pointer.
const constant_exprt & size() const
A side_effect_exprt representation of a function call side effect.
The trinary if-then-else operator.
static void add_rounding_mode(exprt &)
Evaluates to true if the operand is a pointer to a dynamic object.
Fixed-width bit-vector with IEEE floating-point interpretation.
virtual bool is_constant_address_of(const exprt &) const
this function determines which reference-typed expressions are constant
virtual void typecheck_function_call_arguments(side_effect_expr_function_callt &expr)
Typecheck the parameters in a function call expression, and where necessary, make implicit casts arou...
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
Real part of the expression describing a complex number.
bool builtin_factory(const irep_idt &identifier, symbol_tablet &symbol_table, message_handlert &mh)
Check whether given identifier is a compiler built-in.
Union constructor from single element.
void disallow_subexpr_by_id(const exprt &, const irep_idt &, const std::string &) const
const type_with_subtypet & to_type_with_subtype(const typet &type)
virtual void typecheck_side_effect_statement_expression(side_effect_exprt &expr)
The plus expression Associativity is not specified.
virtual void typecheck_expr_symbol(exprt &expr)
A codet representing the declaration of a local variable.
const mathematical_function_typet & to_mathematical_function_type(const typet &type)
Cast a typet to a mathematical_function_typet.
Base class for all expressions.
virtual void typecheck_expr_pointer_arithmetic(exprt &expr)
Generic base class for unary expressions.
A base class for binary expressions.
irep_idt base_name
Base (non-scoped) name.
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Complex numbers made of pair of given subtype.
Sign of an expression Predicate is true if _op is negative, false otherwise.
virtual void typecheck_expr_address_of(exprt &expr)
virtual void typecheck_expr_alignof(exprt &expr)
Thrown when we can't handle something in an input source file.
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
void move_symbol(symbolt &symbol, symbolt *&new_symbol)
virtual void typecheck_type(typet &type)
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
const code_frontend_declt & to_code_frontend_decl(const codet &code)
virtual void typecheck_side_effect_function_call(side_effect_expr_function_callt &expr)
bool is_true() const
Return whether the expression is a constant representing true.
side_effect_exprt & to_side_effect_expr(exprt &expr)
virtual void typecheck_expr_binary_arithmetic(exprt &expr)
struct configt::ansi_ct ansi_c
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
is_compile_time_constantt(const namespacet &ns)
const complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
Expression to hold a symbol (variable)
bool has_suffix(const std::string &s, const std::string &suffix)
Expression for finding the size (in bytes) of the object a pointer points to.
bitvector_typet index_type()
Saturating subtraction expression.
virtual void typecheck_expr_binary_boolean(exprt &expr)
side_effect_expr_statement_expressiont & to_side_effect_expr_statement_expression(exprt &expr)
An expression denoting infinity.
Evaluates to true if the operand is finite.
typet index_type() const
The type of any index expression into an instance of this type.
The saturating plus expression.
std::list< codet > clean_code
const irep_idt & get(const irep_idt &name) const
virtual void make_constant(exprt &expr)
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
virtual void typecheck_expr_operands(exprt &expr)
virtual void typecheck_typed_target_call(side_effect_expr_function_callt &expr)
const exprt & size() const
virtual void typecheck_expr_member(exprt &expr)
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
const codet & to_code(const exprt &expr)
virtual bool is_constant(const exprt &) const
This function determines what expressions are to be propagated as "constants".
void follow_macros(exprt &) const
Follow macros to their values in a given expression.
typet & type()
Return the type of the expression.
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
bool is_constant_address_of(const exprt &e) const override
this function determines which reference-typed expressions are constant
bool has_component_rec(const typet &type, const irep_idt &component_name, const namespacet &ns)
asm_label_mapt asm_label_map
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
virtual void typecheck_expr_rel(binary_relation_exprt &expr)
const typet & element_type() const
The type of the elements of the vector.
irep_idt mode
Language mode.
mstreamt & result() const
const T & as_const(T &value)
Return a reference to the same object but ensures the type is const.
static ieee_float_spect double_precision()
signedbv_typet signed_int_type()
bool has_prefix(const std::string &s, const std::string &prefix)
virtual void typecheck_expr_unary_arithmetic(exprt &expr)
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
virtual void implicit_typecast_bool(exprt &expr)
The null pointer constant.
const std::string & id2string(const irep_idt &d)
bool can_cast_type< c_enum_tag_typet >(const typet &type)
Check whether a reference to a typet is a c_enum_tag_typet.
virtual code_blockt instantiate_gcc_polymorphic_builtin(const irep_idt &identifier, const symbol_exprt &function_symbol)
source_locationt source_location
static optionalt< smt_termt > get_identifier(const exprt &expr, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_handle_identifiers, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers)
A base class for expressions that are predicates, i.e., Boolean-typed.
virtual void typecheck_expr_function_identifier(exprt &expr)
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
#define forall_operands(it, expr)
void set(const irep_idt &name, const irep_idt &value)
virtual void typecheck_expr_dereference(exprt &expr)
std::string expr2c(const exprt &expr, const namespacet &ns, const expr2c_configurationt &configuration)
A Boolean expression returning true, iff operation kind would result in an overflow when applied to o...
A base class for expressions that are predicates, i.e., Boolean-typed, and that take exactly two argu...
#define PRECONDITION(CONDITION)
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
const irep_idt & get_identifier() const
exprt typecheck_saturating_arithmetic(const side_effect_expr_function_callt &expr)
virtual bool is_complete_type(const typet &type) const
optionalt< mp_integer > pointer_offset_bits(const typet &type, const namespacet &ns)
Fixed-width bit-vector with two's complement interpretation.
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
bool simplify(exprt &expr, const namespacet &ns)
Application of (mathematical) function.
Binary multiplication Associativity is not specified.
std::vector< typet > domaint
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
exprt simplify_expr(exprt src, const namespacet &ns)
A predicate that indicates that a zero-terminated string starts at the given address.
bool is_signed_or_unsigned_bitvector(const typet &type)
This method tests, if the given typet is a signed or unsigned bitvector.
virtual void typecheck_expr_unary_boolean(exprt &expr)
virtual std::pair< symbolt &, bool > insert(symbolt symbol) override
Author: Diffblue Ltd.
virtual optionalt< symbol_exprt > typecheck_gcc_polymorphic_builtin(const irep_idt &identifier, const exprt::operandst &arguments, const source_locationt &source_location)
symbol_tablet & symbol_table
virtual bool gcc_types_compatible_p(const typet &, const typet &)
mp_integer alignment(const typet &type, const namespacet &ns)
pointer_typet pointer_type(const typet &subtype)
unsignedbv_typet unsigned_int_type()
virtual void typecheck_code(codet &code)
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
virtual void typecheck_side_effect_gcc_conditional_expression(side_effect_exprt &expr)
virtual void typecheck_arithmetic_pointer(const exprt &expr)
bool has_component(const irep_idt &component_name) const
virtual void make_constant_index(exprt &expr)
virtual exprt typecheck_shuffle_vector(const side_effect_expr_function_callt &expr)
const irep_idt & id() const
virtual void typecheck_expr_trinary(if_exprt &expr)
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
std::vector< exprt > operandst
The Boolean constant false.
ansi_c_declarationt & to_ansi_c_declaration(exprt &expr)
An expression, akin to ISO C's strlen, that denotes the length of a zero-terminated string that start...
const parameterst & parameters() const
source_locationt & add_source_location()
virtual void typecheck_side_effect_assignment(side_effect_exprt &expr)
A predicate that indicates that the object pointed to is writeable.
id_type_mapt parameter_map
exprt pointer_offset(const exprt &pointer)
const shift_exprt & to_shift_expr(const exprt &expr)
Cast an exprt to a shift_exprt.
virtual void typecheck_expr_rel_vector(binary_exprt &expr)
std::map< irep_idt, source_locationt > labels_used
static ieee_floatt plus_infinity(const ieee_float_spect &_spec)
const irep_idt & get_statement() const
virtual void typecheck_expr_ptrmember(exprt &expr)
virtual void typecheck_expr(exprt &expr)
const typet & underlying_type() const
std::size_t get_width() const
const ieee_float_op_exprt & to_ieee_float_op_expr(const exprt &expr)
Cast an exprt to an ieee_float_op_exprt.
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
Deprecated expression utility functions.
A base class for shift and rotate operators.
exprt value
Initial value of symbol.
message_handlert & get_message_handler()
irept & add(const irep_idt &name)
static bool is_numeric_type(const typet &src)
A class for an expression that indicates a history variable.
exprt typecheck_builtin_overflow(side_effect_expr_function_callt &expr, const irep_idt &arith_op)
virtual void typecheck_expr_main(exprt &expr)
A Boolean expression returning true, iff negation would result in an overflow when applied to the (si...
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Evaluates to true if the operand is infinite.
source_locationt location
Source code location of definition of symbol.
exprt::operandst & arguments()
virtual void typecheck_expr_cw_va_arg_typeof(exprt &expr)
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
const symbolst & symbols
Read-only field, used to look up symbols given their names.
bool is_constant() const
Return whether the expression is a constant.
A predicate that indicates that the object pointed to is live.
A base class for relations, i.e., binary predicates whose two operands have the same type.
const typet & base_type() const
The type of the data what we point to.
Imaginary part of the expression describing a complex number.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
exprt same_object(const exprt &p1, const exprt &p2)
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
virtual void typecheck_expr_constant(exprt &expr)
A base class for a predicate that indicates that an address range is ok to read or write or both.
std::string type_to_partial_identifier(const typet &type, const namespacet &ns)
Constructs a string describing the given type, which can be used as part of a C identifier.
const typet & subtype() const
const vector_typet & to_vector_type(const typet &type)
Cast a typet to a vector_typet.
static ieee_floatt zero(const floatbv_typet &type)
const typet & return_type() const
optionalt< exprt > size_of_expr(const typet &type, const namespacet &ns)
const code_blockt & to_code_block(const codet &code)
The byte swap expression.
void adjust_float_expressions(exprt &expr, const exprt &rounding_mode)
Replaces arithmetic operations and typecasts involving floating point numbers with their equivalent f...
constant_exprt to_expr() const
constant_exprt make_boolean_expr(bool value)
returns true_exprt if given true and false_exprt otherwise
A Boolean expression returning true, iff the result of performing operation kind on operands a and b ...
codet & find_last_statement()
Returns one plus the index of the least-significant one bit, or zero if the operand is zero.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
std::string type2c(const typet &type, const namespacet &ns, const expr2c_configurationt &configuration)
Symbol table entry of function parameter.
bool is_null_pointer(const constant_exprt &expr)
Returns true if expr has a pointer type and a value NULL; it also returns true when expr has value ze...
void remove(const irep_idt &name)
Operator to return the address of an object.
const typet & underlying_type() const
source_locationt & add_source_location()
The popcount (counting the number of bits set to 1) expression.
Semantic type conversion.
signedbv_typet pointer_diff_type()
unsignedbv_typet size_type()
bool is_constant(const exprt &e) const override
This function determines what expressions are to be propagated as "constants".
The Boolean constant true.
const irep_idt & get_statement() const
A constant literal expression.
IEEE-floating-point equality.
mstreamt & warning() const
optionalt< exprt > member_offset_expr(const member_exprt &member_expr, const namespacet &ns)
virtual void typecheck_expr_sizeof(exprt &expr)
bitvector_typet c_index_type()
bool is_constant(const typet &type)
This method tests, if the given typet is a constant.
const binary_relation_exprt & to_binary_relation_expr(const exprt &expr)
Cast an exprt to a binary_relation_exprt.
static ieee_float_spect single_precision()
const source_locationt & source_location() const
bool is_incomplete() const
A struct/union may be incomplete.
ranget< iteratort > make_range(iteratort begin, iteratort end)
A type for mathematical functions (do not confuse with functions/methods in code)
Evaluates to true if the operand is a normal number.
void set_identifier(const irep_idt &identifier)
irep_idt name
The unique identifier.
bool get_bool(const irep_idt &name) const
An expression containing a side effect.
virtual void typecheck_expr_index(exprt &expr)
virtual void make_index_type(exprt &expr)
The count leading zeros (counting the number of zero bits starting from the most-significant bit) exp...
virtual void typecheck_expr_builtin_va_arg(exprt &expr)
virtual void implicit_typecast(exprt &expr, const typet &type)
const typet & element_type() const
The type of the elements of the array.
Evaluates to true if the operand is NaN.
Reverse the order of bits in a bit-vector.
Data structure for representing an arbitrary statement in a program.
virtual void typecheck_expr_comma(exprt &expr)
virtual void typecheck_expr_typecast(exprt &expr)
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.