@@ -33,6 +33,7 @@ Author: Daniel Kroening, kroening@kroening.com
3333#include < util/std_expr.h>
3434#include < util/string2int.h>
3535#include < util/string_constant.h>
36+ #include < util/threeval.h>
3637
3738#include < goto-programs/cfg.h>
3839#include < goto-programs/class_hierarchy.h>
@@ -3173,44 +3174,87 @@ irep_idt java_bytecode_convert_methodt::get_static_field(
31733174 return inherited_method.get_full_component_identifier ();
31743175}
31753176
3176- // / create temporary variables if a write instruction can have undesired side-
3177- // / effects
3177+ // / Create temporary variables if a write instruction can have undesired side-
3178+ // / effects.
3179+ // / \param tmp_var_prefix: The prefix string to use for new temporary variables
3180+ // / \param tmp_var_type: The type of the temporary variable.
3181+ // / \param[out] block: The code block the assignment is added to if required.
3182+ // / \param write_type: The enumeration type of the write instruction.
3183+ // / \param identifier: The identifier of the symbol in the write instruction.
31783184void java_bytecode_convert_methodt::save_stack_entries (
31793185 const std::string &tmp_var_prefix,
31803186 const typet &tmp_var_type,
31813187 code_blockt &block,
31823188 const bytecode_write_typet write_type,
31833189 const irep_idt &identifier)
31843190{
3191+ const std::function<bool (
3192+ const std::function<tvt (const exprt &expr)>, const exprt &expr)>
3193+ entry_matches = [&entry_matches, &identifier](
3194+ const std::function<tvt (const exprt &expr)> predicate,
3195+ const exprt &expr) {
3196+ const tvt &tvres = predicate (expr);
3197+ if (tvres.is_unknown ())
3198+ {
3199+ return std::any_of (
3200+ expr.operands ().begin (),
3201+ expr.operands ().end (),
3202+ [&predicate, &entry_matches](const exprt &expr) {
3203+ return entry_matches (predicate, expr);
3204+ });
3205+ }
3206+ else
3207+ {
3208+ return tvres.is_true ();
3209+ }
3210+ };
3211+
3212+ const std::function<tvt (const exprt &expr)> has_member_entry = [&identifier](
3213+ const exprt &expr) {
3214+ const auto member_expr = expr_try_dynamic_cast<member_exprt>(expr);
3215+ return !member_expr ? tvt::unknown ()
3216+ : tvt (member_expr->get_component_name () == identifier);
3217+ };
3218+
3219+ const std::function<tvt (const exprt &expr)> is_symbol_entry =
3220+ [&identifier](const exprt &expr) {
3221+ const auto symbol_expr = expr_try_dynamic_cast<symbol_exprt>(expr);
3222+ return !symbol_expr ? tvt::unknown ()
3223+ : tvt (symbol_expr->get_identifier () == identifier);
3224+ };
3225+
3226+ const std::function<tvt (const exprt &expr)> is_dereference_entry =
3227+ [&identifier](const exprt &expr) {
3228+ const auto dereference_expr =
3229+ expr_try_dynamic_cast<dereference_exprt>(expr);
3230+ return !dereference_expr ? tvt::unknown () : tvt (true );
3231+ };
3232+
31853233 for (auto &stack_entry : stack)
31863234 {
3187- // remove typecasts if existing
3188- while (stack_entry.id ()==ID_typecast)
3189- stack_entry=to_typecast_expr (stack_entry).op ();
3190-
31913235 // variables or static fields and symbol -> save symbols with same id
3192- if ((write_type==bytecode_write_typet::VARIABLE ||
3193- write_type==bytecode_write_typet::STATIC_FIELD) &&
3194- stack_entry.id ()==ID_symbol)
3236+ if (
3237+ (write_type == bytecode_write_typet::VARIABLE ||
3238+ write_type == bytecode_write_typet::STATIC_FIELD) &&
3239+ entry_matches (is_symbol_entry, stack_entry))
31953240 {
3196- const symbol_exprt &var=to_symbol_expr (stack_entry);
3197- if (var.get_identifier ()==identifier)
3198- create_stack_tmp_var (tmp_var_prefix, tmp_var_type, block, stack_entry);
3241+ create_stack_tmp_var (tmp_var_prefix, tmp_var_type, block, stack_entry);
31993242 }
32003243
32013244 // array reference and dereference -> save all references on the stack
3202- else if (write_type==bytecode_write_typet::ARRAY_REF &&
3203- stack_entry.id ()==ID_dereference)
3245+ else if (
3246+ write_type == bytecode_write_typet::ARRAY_REF &&
3247+ entry_matches (is_dereference_entry, stack_entry))
3248+ {
32043249 create_stack_tmp_var (tmp_var_prefix, tmp_var_type, block, stack_entry);
3250+ }
32053251
32063252 // field and member access -> compare component name
3207- else if (write_type==bytecode_write_typet::FIELD &&
3208- stack_entry.id ()==ID_member)
3253+ else if (
3254+ write_type == bytecode_write_typet::FIELD &&
3255+ entry_matches (has_member_entry, stack_entry))
32093256 {
3210- const irep_idt &entry_id=
3211- to_member_expr (stack_entry).get_component_name ();
3212- if (entry_id==identifier)
3213- create_stack_tmp_var (tmp_var_prefix, tmp_var_type, block, stack_entry);
3257+ create_stack_tmp_var (tmp_var_prefix, tmp_var_type, block, stack_entry);
32143258 }
32153259 }
32163260}
0 commit comments