diff --git a/scripts/expected_doxygen_warnings.txt b/scripts/expected_doxygen_warnings.txt index 9514df885df..b5140394ce6 100644 --- a/scripts/expected_doxygen_warnings.txt +++ b/scripts/expected_doxygen_warnings.txt @@ -21,9 +21,9 @@ warning: Include graph for 'goto_instrument_parse_options.cpp' not generated, too many nodes (97), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. warning: Included by graph for 'goto_functions.h' not generated, too many nodes (66), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. warning: Included by graph for 'goto_model.h' not generated, too many nodes (111), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. -warning: Included by graph for 'arith_tools.h' not generated, too many nodes (183), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. -warning: Included by graph for 'c_types.h' not generated, too many nodes (143), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. -warning: Included by graph for 'config.h' not generated, too many nodes (78), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. +warning: Included by graph for 'arith_tools.h' not generated, too many nodes (182), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. +warning: Included by graph for 'c_types.h' not generated, too many nodes (144), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. +warning: Included by graph for 'config.h' not generated, too many nodes (77), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. warning: Included by graph for 'exception_utils.h' not generated, too many nodes (61), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. warning: Included by graph for 'expr.h' not generated, too many nodes (87), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. warning: Included by graph for 'expr_util.h' not generated, too many nodes (61), threshold is 60. Consider increasing DOT_GRAPH_MAX_NODES. diff --git a/src/solvers/flattening/boolbv.cpp b/src/solvers/flattening/boolbv.cpp index 75a0be6abb9..a29414a760a 100644 --- a/src/solvers/flattening/boolbv.cpp +++ b/src/solvers/flattening/boolbv.cpp @@ -15,6 +15,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include #include @@ -32,6 +33,13 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +endianness_mapt boolbvt::endianness_map(const typet &type) const +{ + const bool little_endian = + config.ansi_c.endianness == configt::ansi_ct::endiannesst::IS_LITTLE_ENDIAN; + return endianness_map(type, little_endian); +} + /// Convert expression to vector of literalts, using an internal /// cache to speed up conversion if available. Also assert the resultant /// vector is of a specific size, and freeze any elements if appropriate. diff --git a/src/solvers/flattening/boolbv.h b/src/solvers/flattening/boolbv.h index c74c4798ef7..89adb27e6eb 100644 --- a/src/solvers/flattening/boolbv.h +++ b/src/solvers/flattening/boolbv.h @@ -104,6 +104,8 @@ class boolbvt:public arrayst return endianness_mapt{type, little_endian, ns}; } + virtual endianness_mapt endianness_map(const typet &type) const; + protected: boolbv_widtht bv_width; bv_utilst bv_utils; diff --git a/src/solvers/flattening/boolbv_byte_update.cpp b/src/solvers/flattening/boolbv_byte_update.cpp index 5d97db8dcec..551b9ce754d 100644 --- a/src/solvers/flattening/boolbv_byte_update.cpp +++ b/src/solvers/flattening/boolbv_byte_update.cpp @@ -58,31 +58,23 @@ bvt boolbvt::convert_byte_update(const byte_update_exprt &expr) } else { - if(little_endian) - { - for(std::size_t i=0; i(offset + i)] = value_bv[i]; - } - else - { - endianness_mapt map_op = endianness_map(op.type(), false); - endianness_mapt map_value = endianness_map(value.type(), false); + endianness_mapt map_op = endianness_map(op.type(), little_endian); + endianness_mapt map_value = endianness_map(value.type(), little_endian); - const std::size_t offset_i = numeric_cast_v(offset); + const std::size_t offset_i = numeric_cast_v(offset); - for(std::size_t i=0; i + +static bvt convert_member_struct( + const member_exprt &expr, + const bvt &struct_bv, + const std::function boolbv_width, + const namespacet &ns) { const exprt &struct_op=expr.struct_op(); const typet &struct_op_type=ns.follow(struct_op.type()); - const bvt &struct_bv=convert_bv(struct_op); - const irep_idt &component_name = expr.get_component_name(); - const struct_union_typet::componentst &components = - to_struct_union_type(struct_op_type).components(); + const struct_typet::componentst &components = + to_struct_type(struct_op_type).components(); std::size_t offset = 0; @@ -42,8 +46,7 @@ bvt boolbvt::convert_member(const member_exprt &expr) struct_bv.begin() + offset, struct_bv.begin() + offset + sub_width); } - if(struct_op_type.id() != ID_union) - offset += sub_width; + offset += sub_width; } INVARIANT_WITH_DIAGNOSTICS( @@ -52,3 +55,52 @@ bvt boolbvt::convert_member(const member_exprt &expr) expr.find_source_location(), id2string(component_name)); } + +static bvt convert_member_union( + const member_exprt &expr, + const bvt &union_bv, + const boolbvt &boolbv, + const namespacet &ns) +{ + const exprt &union_op = expr.compound(); + const union_typet &union_op_type = + ns.follow_tag(to_union_tag_type(union_op.type())); + + const irep_idt &component_name = expr.get_component_name(); + const union_typet::componentt &component = + union_op_type.get_component(component_name); + DATA_INVARIANT_WITH_DIAGNOSTICS( + component.is_not_nil(), + "union type shall contain component accessed by member expression", + expr.find_source_location(), + id2string(component_name)); + + const typet &subtype = component.type(); + const std::size_t sub_width = boolbv.boolbv_width(subtype); + + endianness_mapt map_u = boolbv.endianness_map(union_op_type); + endianness_mapt map_component = boolbv.endianness_map(subtype); + + bvt result(sub_width, literalt{}); + for(std::size_t i = 0; i < sub_width; ++i) + result[map_u.map_bit(i)] = union_bv[map_component.map_bit(i)]; + + return result; +} + +bvt boolbvt::convert_member(const member_exprt &expr) +{ + const bvt &compound_bv = convert_bv(expr.compound()); + + if(expr.compound().type().id() == ID_struct_tag) + return convert_member_struct( + expr, + compound_bv, + [this](const typet &t) { return boolbv_width(t); }, + ns); + else + { + PRECONDITION(expr.compound().type().id() == ID_union_tag); + return convert_member_union(expr, compound_bv, *this, ns); + } +} diff --git a/src/solvers/flattening/boolbv_union.cpp b/src/solvers/flattening/boolbv_union.cpp index d8df5bc48b0..b6202dc288c 100644 --- a/src/solvers/flattening/boolbv_union.cpp +++ b/src/solvers/flattening/boolbv_union.cpp @@ -8,9 +8,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "boolbv.h" -#include -#include - bvt boolbvt::convert_union(const union_exprt &expr) { std::size_t width=boolbv_width(expr.type()); @@ -28,31 +25,15 @@ bvt boolbvt::convert_union(const union_exprt &expr) bvt bv; bv.resize(width); - if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::IS_LITTLE_ENDIAN) - { - for(std::size_t i=0; i #include -#include #include #include @@ -237,20 +236,9 @@ void boolbvt::convert_with_union( "convert_with_union: unexpected operand op2 width", irep_pretty_diagnosticst{type}); - if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::IS_LITTLE_ENDIAN) - { - for(std::size_t i=0; i