Skip to content

Commit 55d36b5

Browse files
Fix code for String.equals
This should check that the object is an instance of String before doing any string operation.
1 parent 5cbb758 commit 55d36b5

File tree

1 file changed

+37
-34
lines changed

1 file changed

+37
-34
lines changed

src/java_bytecode/java_string_library_preprocess.cpp

+37-34
Original file line numberDiff line numberDiff line change
@@ -930,53 +930,56 @@ java_string_library_preprocesst::string_literal_to_string_expr(
930930
/// \param symbol_table: symbol table
931931
/// \return Code corresponding to:
932932
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
933-
/// string_expr1 = {this->length; *this->data}
934-
/// string_expr2 = {arg->length; *arg->data}
935-
/// return cprover_string_equal(string_expr1, string_expr2)
933+
/// IF arg->@class_identifier == "java.lang.String"
934+
/// THEN
935+
/// string_expr1 = {this->length; *this->data}
936+
/// string_expr2 = {arg->length; *arg->data}
937+
/// bool string_equals_tmp = cprover_string_equal(string_expr1, string_expr2)
938+
/// return string_equals_tmp
939+
/// ELSE
940+
/// return false
936941
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
937942
codet java_string_library_preprocesst::make_equals_function_code(
938943
const code_typet &type,
939944
const source_locationt &loc,
940945
symbol_table_baset &symbol_table)
941946
{
942-
code_blockt code;
947+
const typet &return_type = type.return_type();
943948
exprt::operandst ops;
944949
for(const auto &p : type.parameters())
945950
{
946951
symbol_exprt sym(p.get_identifier(), p.type());
947952
ops.push_back(sym);
948953
}
949-
exprt::operandst args=process_equals_function_operands(
950-
ops, loc, symbol_table, code);
951-
952-
member_exprt class_identifier(
953-
checked_dereference(ops[1], ops[1].type().subtype()),
954-
"@class_identifier",
955-
string_typet());
956-
957-
// Check the object argument is a String.
958-
equal_exprt arg_is_string(
959-
class_identifier, constant_exprt("java::java.lang.String", string_typet()));
960954

961-
// Check content equality
962-
const symbolt string_equals_sym = get_fresh_aux_symbol(
963-
java_boolean_type(), "string_equals", "str_eq", loc, ID_java, symbol_table);
964-
const symbol_exprt string_equals = string_equals_sym.symbol_expr();
965-
code.add(code_declt(string_equals), loc);
966-
code.add(
967-
code_assignt(
968-
string_equals,
969-
make_function_application(
970-
ID_cprover_string_equal_func, args, type.return_type(), symbol_table)),
971-
loc);
972-
973-
code.add(
974-
code_returnt(
975-
if_exprt(
976-
arg_is_string,
977-
string_equals,
978-
from_integer(false, java_boolean_type()))),
979-
loc);
955+
code_ifthenelset code;
956+
code.cond() = [&] {
957+
const member_exprt class_identifier(
958+
checked_dereference(ops[1], ops[1].type().subtype()),
959+
"@class_identifier",
960+
string_typet());
961+
return equal_exprt(
962+
class_identifier,
963+
constant_exprt("java::java.lang.String", string_typet()));
964+
}();
965+
966+
code.then_case() = [&] {
967+
code_blockt instance_case;
968+
// Check content equality
969+
const symbolt string_equals_sym = get_fresh_aux_symbol(
970+
return_type, "string_equals", "str_eq", loc, ID_java, symbol_table);
971+
const symbol_exprt string_equals = string_equals_sym.symbol_expr();
972+
instance_case.add(code_declt(string_equals), loc);
973+
const exprt::operandst args =
974+
process_equals_function_operands(ops, loc, symbol_table, instance_case);
975+
const auto fun_app = make_function_application(
976+
ID_cprover_string_equal_func, args, return_type, symbol_table);
977+
instance_case.add(code_assignt(string_equals, fun_app), loc);
978+
instance_case.add(code_returnt(string_equals), loc);
979+
return instance_case;
980+
}();
981+
982+
code.else_case() = code_returnt(from_integer(false, return_type));
980983
return code;
981984
}
982985

0 commit comments

Comments
 (0)