From 1aede785e785904825ff3e62aa432b9e0ce585d4 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Sat, 31 Dec 2016 15:27:04 +0300 Subject: [PATCH 01/10] Preprocessing of goto programs for string refinement --- .../string_refine_preprocess.cpp | 1289 +++++++++++++++++ src/goto-programs/string_refine_preprocess.h | 215 +++ src/util/std_expr.h | 13 + 3 files changed, 1517 insertions(+) create mode 100644 src/goto-programs/string_refine_preprocess.cpp create mode 100644 src/goto-programs/string_refine_preprocess.h diff --git a/src/goto-programs/string_refine_preprocess.cpp b/src/goto-programs/string_refine_preprocess.cpp new file mode 100644 index 00000000000..c4dc1a92960 --- /dev/null +++ b/src/goto-programs/string_refine_preprocess.cpp @@ -0,0 +1,1289 @@ +/*******************************************************************\ + +Module: Preprocess a goto-programs so that calls to the java String + library are recognized by the string solver + +Author: Romain Brenguier + +Date: September 2016 + +\*******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +// TODO: refined_string_type should be moved to util +#include +#include + +#include "string_refine_preprocess.h" + +/******************************************************************* \ + +Function: string_refine_preprocesst::fresh_array + + Inputs: + type - an array type + location - a location in the program + + Outputs: a new symbol + + Purpose: add a symbol with static lifetime and name containing + `cprover_string_array` and given type + +\*******************************************************************/ + +symbol_exprt string_refine_preprocesst::fresh_array( + const typet &type, const source_locationt &location) +{ + symbolt array_symbol=get_fresh_aux_symbol( + type, + "cprover_string_array", + "cprover_string_array", + location, + ID_java, + symbol_table); + array_symbol.is_static_lifetime=true; + return array_symbol.symbol_expr(); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::fresh_string + + Inputs: + type - a type for refined strings + location - a location in the program + + Outputs: a new symbol + + Purpose: add a symbol with static lifetime and name containing + `cprover_string` and given type + +\*******************************************************************/ + +symbol_exprt string_refine_preprocesst::fresh_string( + const typet &type, const source_locationt &location) +{ + symbolt array_symbol=get_fresh_aux_symbol( + type, "cprover_string", "cprover_string", location, ID_java, symbol_table); + array_symbol.is_static_lifetime=true; + return array_symbol.symbol_expr(); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::declare_function + + Inputs: a name and a type + + Purpose: declare a function with the given name and type + +\*******************************************************************/ + +void string_refine_preprocesst::declare_function( + irep_idt function_name, const typet &type) +{ + auxiliary_symbolt func_symbol; + func_symbol.base_name=function_name; + func_symbol.is_static_lifetime=false; + func_symbol.mode=ID_java; + func_symbol.name=function_name; + func_symbol.type=type; + symbol_table.add(func_symbol); + goto_functions.function_map[function_name]; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::get_data_and_length_type_of_string + + Inputs: an expression, a reference to a data type and a reference to a + length type + + Purpose: assuming the expression is a java string, figure out what + the types for length and data are and put them into the references + given as argument + +\*******************************************************************/ + +void string_refine_preprocesst::get_data_and_length_type_of_string( + const exprt &expr, typet &data_type, typet &length_type) +{ + assert(refined_string_typet::is_java_string_type(expr.type()) || + refined_string_typet::is_java_string_builder_type(expr.type())); + typet object_type=ns.follow(expr.type()); + const struct_typet &struct_type=to_struct_type(object_type); + for(const auto &component : struct_type.components()) + if(component.get_name()=="length") + length_type=component.type(); + else if(component.get_name()=="data") + data_type=component.type(); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_cprover_string_assign + + Inputs: a goto_program, a position in this program, an expression and a + location + + Outputs: an expression + + Purpose: Introduce a temporary variable for cprover strings; + returns the cprover_string corresponding to rhs if it is a string + pointer and the original rhs otherwise. + +\*******************************************************************/ + +exprt string_refine_preprocesst::make_cprover_string_assign( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &rhs, + const source_locationt &location) +{ + if(refined_string_typet::is_java_string_pointer_type(rhs.type())) + { + auto pair=java_to_cprover_strings.insert( + std::pair(rhs, nil_exprt())); + + if(pair.second) + { + // We do the following assignments: + // cprover_string_array = *(rhs->data) + // cprover_string = { rhs->length; cprover_string_array } + + dereference_exprt deref(rhs, rhs.type().subtype()); + + typet data_type, length_type; + get_data_and_length_type_of_string(deref, data_type, length_type); + member_exprt length(deref, "length", length_type); + symbol_exprt array_lhs=fresh_array(data_type.subtype(), location); + + // string expression for the rhs of the second assignment + string_exprt new_rhs( + length, array_lhs, refined_string_typet(length_type, data_type)); + + member_exprt data(deref, "data", data_type); + dereference_exprt deref_data(data, data_type.subtype()); + symbol_exprt lhs=fresh_string(new_rhs.type(), location); + + std::list assignments; + assignments.emplace_back(array_lhs, deref_data); + assignments.emplace_back(lhs, new_rhs); + insert_assignments( + goto_program, target, target->function, location, assignments); + target=goto_program.insert_after(target); + pair.first->second=lhs; + } + return pair.first->second; + } + else if(rhs.id()==ID_typecast && + refined_string_typet::is_java_string_pointer_type(rhs.op0().type())) + { + exprt new_rhs=make_cprover_string_assign( + goto_program, target, rhs.op0(), location); + return typecast_exprt(new_rhs, rhs.type()); + } + else + return rhs; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_normal_assign + + Inputs: a goto_program, a position in this program, an expression lhs, + a function type, a function name, a vector of arguments, a location + and a signature + + Purpose: replace the current instruction by: + > lhs=function_name(arguments) : return_type @ location + If given, signature can force String conversion of given arguments. + The convention for signature is one character by argument + and 'S' denotes string. + +\*******************************************************************/ + +void string_refine_preprocesst::make_normal_assign( + goto_programt &goto_program, + goto_programt::targett target, + const exprt &lhs, + const code_typet &function_type, + const irep_idt &function_name, + const exprt::operandst &arguments, + const source_locationt &location, + const std::string &signature) +{ + if(function_name==ID_cprover_string_copy_func) + { + assert(!arguments.empty()); + make_string_copy(goto_program, target, lhs, arguments[0], location); + } + else + { + function_application_exprt rhs( + symbol_exprt(function_name), function_type.return_type()); + rhs.add_source_location()=location; + declare_function(function_name, function_type); + + exprt::operandst processed_arguments=process_arguments( + goto_program, target, arguments, location, signature); + rhs.arguments()=processed_arguments; + + code_assignt assignment(lhs, rhs); + assignment.add_source_location()=location; + target->make_assignment(); + target->code=assignment; + } +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::insert_assignments + + Inputs: a goto_program, a position in this program, a list of assignments + + Purpose: add the assignments to the program in the order they are given + +\*******************************************************************/ + +void string_refine_preprocesst::insert_assignments( + goto_programt &goto_program, + goto_programt::targett &target, + irep_idt function, + source_locationt location, + const std::list &va) +{ + if(va.empty()) + return; + + auto i=va.begin(); + target->make_assignment(); + target->code=*i; + target->function=function; + target->source_location=location; + for(i++; i!=va.end(); i++) + { + target=goto_program.insert_after(target); + target->make_assignment(); + target->code=*i; + target->function=function; + target->source_location=location; + } +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_string_assign + + Inputs: a goto_program, a position in this program, an expression lhs, + a function type, a function name, a vector of arguments, a location + and a signature + + Purpose: replace the current instruction by: + > lhs=malloc(String *) + > lhs->length=function_name_length(arguments) + > tmp_data=function_name_data(arguments) + > lhs->data=&tmp_data + +\*******************************************************************/ + +void string_refine_preprocesst::make_string_assign( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &lhs, + const code_typet &function_type, + const irep_idt &function_name, + const exprt::operandst &arguments, + const source_locationt &location, + const std::string &signature) +{ + assert(refined_string_typet::is_java_string_pointer_type( + function_type.return_type())); + dereference_exprt deref(lhs, lhs.type().subtype()); + typet object_type=ns.follow(deref.type()); + exprt object_size=size_of_expr(object_type, ns); + typet length_type, data_type; + get_data_and_length_type_of_string(deref, data_type, length_type); + + std::string fnamel=id2string(function_name)+"_length"; + std::string fnamed=id2string(function_name)+"_data"; + declare_function(fnamel, length_type); + declare_function(fnamed, data_type); + function_application_exprt rhs_length(symbol_exprt(fnamel), length_type); + function_application_exprt rhs_data( + symbol_exprt(fnamed), data_type.subtype()); + + exprt::operandst processed_arguments=process_arguments( + goto_program, target, arguments, location, signature); + rhs_length.arguments()=processed_arguments; + rhs_data.arguments()=processed_arguments; + + symbolt sym_length=get_fresh_aux_symbol( + length_type, "length", "length", location, ID_java, symbol_table); + symbol_exprt tmp_length=sym_length.symbol_expr(); + symbol_exprt tmp_array=fresh_array(data_type.subtype(), location); + member_exprt lhs_length(deref, "length", length_type); + member_exprt lhs_data(deref, "data", tmp_array.type()); + + // lhs=malloc(String *) + assert(object_size.is_not_nil()); // got nil object_size + side_effect_exprt malloc_expr(ID_malloc); + malloc_expr.copy_to_operands(object_size); + malloc_expr.type()=pointer_typet(object_type); + malloc_expr.add_source_location()=location; + + std::list assigns; + assigns.emplace_back(lhs, malloc_expr); + assigns.emplace_back(tmp_length, rhs_length); + assigns.emplace_back(lhs_length, tmp_length); + assigns.emplace_back(tmp_array, rhs_data); + assigns.emplace_back(lhs_data, address_of_exprt(tmp_array)); + insert_assignments(goto_program, target, target->function, location, assigns); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_assign + + Inputs: a goto_program, a position in this program, an expression lhs, + a function type, a function name, a vector of arguments, a location + and a signature + + Purpose: assign the result of the function application to lhs, + in case the function type is string, it does a special assignment + using `make_string_assign` + +\*******************************************************************/ + +void string_refine_preprocesst::make_assign( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &lhs, + const code_typet &function_type, + const irep_idt &function_name, + const exprt::operandst &arg, + const source_locationt &loc, + const std::string &sig) +{ + if(refined_string_typet::is_java_string_pointer_type( + function_type.return_type())) + make_string_assign( + goto_program, target, lhs, function_type, function_name, arg, loc, sig); + else + make_normal_assign( + goto_program, target, lhs, function_type, function_name, arg, loc, sig); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_string_copy + + Inputs: a goto_program, a position in this program, a lhs expression, + an argument expression and a location + + Outputs: an expression + + Purpose: replace the current instruction by: + > lhs->length=argument->length + > tmp_data=*(argument->data) + > lhs->data=&tmp_data + +\*******************************************************************/ + +void string_refine_preprocesst::make_string_copy( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &lhs, + const exprt &argument, + const source_locationt &location) +{ + // TODO : treat CharSequence and StringBuffer + assert(refined_string_typet::is_java_string_pointer_type(lhs.type()) || + refined_string_typet::is_java_string_builder_pointer_type(lhs.type())); + exprt deref=dereference_exprt(lhs, lhs.type().subtype()); + + typet length_type, data_type; + get_data_and_length_type_of_string(deref, data_type, length_type); + + dereference_exprt deref_arg(argument, argument.type().subtype()); + std::list assignments; + + exprt lhs_length=get_length(deref, length_type); + exprt rhs_length=get_length(deref_arg, length_type); + assignments.emplace_back(lhs_length, rhs_length); + + symbol_exprt tmp_data=fresh_array(data_type.subtype(), location); + exprt rhs_data=get_data(deref_arg, data_type); + exprt lhs_data=get_data(deref, data_type); + assignments.emplace_back( + tmp_data, dereference_exprt(rhs_data, data_type.subtype())); + assignments.emplace_back(lhs_data, address_of_exprt(tmp_data)); + + insert_assignments( + goto_program, target, target->function, location, assignments); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_string_function + + Inputs: a position in a goto program, a function name, an expression lhs, + a function type, name, arguments, a location and a signature string + + Purpose: at the current position replace `lhs=s.some_function(x,...)` + by `lhs=function_name(s,x,...)`; + +\*******************************************************************/ + +void string_refine_preprocesst::make_string_function( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &lhs, + const code_typet &function_type, + const irep_idt &function_name, + const exprt::operandst &arguments, + const source_locationt &location, + const std::string &signature) +{ + if(refined_string_typet::is_java_string_pointer_type( + function_type.return_type())) + make_string_assign( + goto_program, + target, + lhs, + function_type, + function_name, + arguments, + location, + signature); + else + make_normal_assign( + goto_program, + target, + lhs, + function_type, + function_name, + arguments, + location, + signature); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_string_function + + Inputs: a position in a goto program, a function name and two Boolean options + + Purpose: at the current position replace `lhs=s.some_function(x,...)` + by `lhs=function_name(s,x,...)`; + option `assign_first_arg` uses `s` instead of `lhs` in the resulting + expression; + option `skip_first_arg`, removes `s` from the arguments, ie `x` is + the first one + +\*******************************************************************/ + +void string_refine_preprocesst::make_string_function( + goto_programt &goto_program, + goto_programt::targett &target, + const irep_idt &function_name, + const std::string &signature, + bool assign_first_arg, + bool skip_first_arg) +{ + code_function_callt &function_call=to_code_function_call(target->code); + code_typet function_type=to_code_type(function_call.function().type()); + code_typet new_type; + const source_locationt &loc=function_call.source_location(); + declare_function(function_name, function_type); + function_application_exprt rhs; + std::vector args; + if(assign_first_arg) + { + assert(!function_call.arguments().empty()); + rhs.type()=function_call.arguments()[0].type(); + } + else + rhs.type()=function_type.return_type(); + rhs.add_source_location()=function_call.source_location(); + rhs.function()=symbol_exprt(function_name); + + std::size_t start_index=skip_first_arg?1:0; + for(std::size_t i=start_index; icode); + assert(!function_call.arguments().empty()); + string_builders[function_call.lhs()]=function_call.arguments()[0]; + make_string_function( + goto_program, target, function_name, signature, true, false); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::build_function_application + + Inputs: a function name, a type, a location and a vector of arguments + + Outputs: a function application expression + + Purpose: declare a function and construct an function application expression + with the given function name, type, location and arguments + +\*******************************************************************/ + +function_application_exprt + string_refine_preprocesst::build_function_application( + const irep_idt &function_name, + const typet &type, + const source_locationt &location, + const exprt::operandst &arguments) +{ + declare_function(function_name, type); + function_application_exprt function_app(symbol_exprt(function_name), type); + function_app.add_source_location()=location; + for(const auto &arg : arguments) + function_app.arguments().push_back(arg); + + return function_app; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_to_char_array_function + + Inputs: a goto program and a position in that goto program + + Purpose: at the given position replace `return_tmp0=s.toCharArray()` with: + > return_tmp0->data=&((s->data)[0]) + > return_tmp0->length=s->length + +\*******************************************************************/ + +void string_refine_preprocesst::make_to_char_array_function( + goto_programt &goto_program, goto_programt::targett &target) +{ + const code_function_callt &function_call=to_code_function_call(target->code); + + assert(!function_call.arguments().empty()); + const exprt &string_argument=function_call.arguments()[0]; + assert(refined_string_typet::is_java_string_pointer_type( + string_argument.type())); + + dereference_exprt deref(string_argument, string_argument.type().subtype()); + typet length_type, data_type; + get_data_and_length_type_of_string(deref, data_type, length_type); + std::list assignments; + + // &((s->data)[0]) + exprt rhs_data=get_data(deref, data_type); + dereference_exprt rhs_array(rhs_data, data_type.subtype()); + exprt first_index=from_integer(0, java_int_type()); + index_exprt first_element(rhs_array, first_index, java_char_type()); + address_of_exprt rhs_pointer(first_element); + + // return_tmp0->data=&((s->data)[0]) + typet deref_type=function_call.lhs().type().subtype(); + dereference_exprt deref_lhs(function_call.lhs(), deref_type); + exprt lhs_data=get_data(deref_lhs, data_type); + assignments.emplace_back(lhs_data, rhs_pointer); + + // return_tmp0->length=s->length + exprt rhs_length=get_length(deref, length_type); + exprt lhs_length=get_length(deref_lhs, length_type); + assignments.emplace_back(lhs_length, rhs_length); + source_locationt location=target->source_location; + insert_assignments( + goto_program, target, target->function, location, assignments); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_cprover_char_array_assign + + Inputs: a goto_program, a position in this program, an expression and a + location + + Outputs: a char array expression (not a pointer) + + Purpose: Introduce a temporary variable for cprover strings; + returns the cprover_string corresponding to rhs + +\*******************************************************************/ + +exprt string_refine_preprocesst::make_cprover_char_array_assign( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &rhs, + const source_locationt &location) +{ + // TODO : add an assertion on the type of rhs + + // We do the following assignments: + // cprover_string_array = rhs.data + // cprover_string = { rhs.length; cprover_string_array } + + // string expression for the rhs of the second assignment + string_exprt new_rhs(java_char_type()); + + typet data_type=new_rhs.content().type(); + typet length_type=java_int_type(); + + symbol_exprt array_lhs=fresh_array(data_type, location); + exprt array_rhs=get_data(rhs, new_rhs.content().type()); + symbol_exprt lhs=fresh_string(new_rhs.type(), location); + new_rhs.length()=get_length(rhs, length_type); + new_rhs.content()=array_lhs; + + std::list assignments; + assignments.emplace_back(array_lhs, array_rhs); + assignments.emplace_back(lhs, new_rhs); + insert_assignments( + goto_program, target, target->function, location, assignments); + target=goto_program.insert_after(target); + return lhs; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::make_char_array_function + + Inputs: a position in a goto program, a function name, two Boolean options, + and the index of the char array argument in the function + + Purpose: at the given position replace + `lhs=s.some_function(...,char_array,...)` by + > cprover_string = { char_array->length, *char_array } + > tmp_string=function_name(s, cprover_string, ...) + option `assign_first_arg` uses `s` instead of `lhs` in the second + assignment; + option `skip_first_arg`, removes `s` from the arguments, ie `x` is + the first one; + argument index gives the index of the argument containing char_array + +\*******************************************************************/ + +void string_refine_preprocesst::make_char_array_function( + goto_programt &goto_program, + goto_programt::targett &target, + const irep_idt &function_name, + const std::string &signature, + std::size_t index, + bool assign_first_arg, + bool skip_first_arg) +{ + code_function_callt &function_call=to_code_function_call(target->code); + code_typet function_type=to_code_type(function_call.function().type()); + code_typet new_function_type; + const source_locationt &location=function_call.source_location(); + assert(!function_call.arguments().size()>index); + const std::vector &args=function_call.arguments(); + std::vector new_args; + + exprt lhs; + if(assign_first_arg) + { + assert(!function_call.arguments().empty()); + lhs=function_call.arguments()[0]; + else + lhs=function_call.lhs(); + + if(lhs.id()==ID_typecast) + lhs=to_typecast_expr(lhs).op(); + + exprt char_array=dereference_exprt( + function_call.arguments()[index], + function_call.arguments()[index].type().subtype()); + exprt string=make_cprover_char_array_assign( + goto_program, target, char_array, location); + + std::size_t start_index=skip_first_arg?1:0; + for(std::size_t i=start_index; icode); + assert(!function_call.arguments().empty()); + string_builders[function_call.lhs()]=function_call.arguments()[0]; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::process_arguments + + Inputs: a goto program, a position, a list of expressions, a location and a + signature + + Outputs: a list of expressions + + Purpose: for each expression that is a string or that is at a position with + an 'S' character in the signature, we declare a new `cprover_string` + whose contents is deduced from the expression and replace the + expression by this cprover_string in the output list; + in the other case the expression is kept as is for the output list. + +\*******************************************************************/ + +exprt::operandst string_refine_preprocesst::process_arguments( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt::operandst &arguments, + const source_locationt &location, + const std::string &signature) +{ + exprt::operandst new_arguments; + + for(std::size_t i=0; isecond); + else + { + if(isecond; + else + return ""; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::replace_string_calls + + Inputs: a function in a goto_program + + Purpose: goes through the instructions, replace function calls to string + function by equivalent instructions using functions defined + for the string solver, replace string literals by string + expressions of the type used by the string solver + TODO: the current implementation is only for java functions, + we should add support for other languages + +\*******************************************************************/ + +void string_refine_preprocesst::replace_string_calls( + goto_functionst::function_mapt::iterator f_it) +{ + goto_programt &goto_program=f_it->second.body; + + Forall_goto_program_instructions(target, goto_program) + { + if(target->is_function_call()) + { + code_function_callt &function_call=to_code_function_call(target->code); + for(auto &arg : function_call.arguments()) + { + auto sb_it=string_builders.find(arg); + if(sb_it!=string_builders.end()) + arg=sb_it->second; + } + + if(function_call.function().id()==ID_symbol) + { + const irep_idt &function_id= + to_symbol_expr(function_call.function()).get_identifier(); + std::string signature=function_signature(function_id); + + auto it=string_functions.find(function_id); + if(it!=string_functions.end()) + make_string_function( + goto_program, target, it->second, signature, false, false); + + it=side_effect_functions.find(function_id); + if(it!=side_effect_functions.end()) + make_string_function_side_effect( + goto_program, target, it->second, signature); + + it=string_function_calls.find(function_id); + if(it!=string_function_calls.end()) + make_string_function_call( + goto_program, target, it->second, signature); + + it=string_of_char_array_functions.find(function_id); + if(it!=string_of_char_array_functions.end()) + make_char_array_function( + goto_program, target, it->second, signature, 0); + + it=string_of_char_array_function_calls.find(function_id); + if(it!=string_of_char_array_function_calls.end()) + make_char_array_function_call( + goto_program, target, it->second, signature); + + it=side_effect_char_array_functions.find(function_id); + if(it!=side_effect_char_array_functions.end()) + make_char_array_side_effect( + goto_program, target, it->second, signature); + + if(function_id==irep_idt("java::java.lang.String.toCharArray:()[C")) + make_to_char_array_function(goto_program, target); + } + } + else + { + if(target->is_assign()) + { + // In assignments we replace string literals and C string functions + code_assignt assignment=to_code_assign(target->code); + + exprt new_rhs=assignment.rhs(); + code_assignt new_assignment(assignment.lhs(), new_rhs); + + if(new_rhs.id()==ID_function_application) + { + function_application_exprt f=to_function_application_expr(new_rhs); + const exprt &name=f.function(); + assert(name.id()==ID_symbol); + const irep_idt &id=to_symbol_expr(name).get_identifier(); + auto it=c_string_functions.find(id); + if(it!=c_string_functions.end()) + { + declare_function(it->second, f.type()); + f.function()=symbol_exprt(it->second); + new_assignment=code_assignt(assignment.lhs(), f); + } + } + + new_assignment.add_source_location()=assignment.source_location(); + target->make_assignment(); + target->code=new_assignment; + } + } + } + return; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::initialize_string_function_table + + Purpose: fill maps with correspondance from java method names to cprover + functions + +\*******************************************************************/ + +void string_refine_preprocesst::initialize_string_function_table() +{ + string_functions["java::java.lang.String.codePointAt:(I)I"]= + ID_cprover_string_code_point_at_func; + string_functions["java::java.lang.String.codePointBefore:(I)I"]= + ID_cprover_string_code_point_before_func; + string_functions["java::java.lang.String.codePointCount:(II)I"]= + ID_cprover_string_code_point_count_func; + string_functions["java::java.lang.String.offsetByCodePoints:(II)I"]= + ID_cprover_string_offset_by_code_point_func; + string_functions["java::java.lang.String.hashCode:()I"]= + ID_cprover_string_hash_code_func; + string_functions["java::java.lang.String.indexOf:(I)I"]= + ID_cprover_string_index_of_func; + string_functions["java::java.lang.String.indexOf:(II)I"]= + ID_cprover_string_index_of_func; + string_functions["java::java.lang.String.indexOf:(Ljava/lang/String;)I"]= + ID_cprover_string_index_of_func; + string_functions["java::java.lang.String.indexOf:(Ljava/lang/String;I)I"]= + ID_cprover_string_index_of_func; + string_functions["java::java.lang.String.lastIndexOf:(I)I"]= + ID_cprover_string_last_index_of_func; + string_functions["java::java.lang.String.lastIndexOf:(II)I"]= + ID_cprover_string_last_index_of_func; + string_functions + ["java::java.lang.String.lastIndexOf:(Ljava/lang/String;)I"]= + ID_cprover_string_last_index_of_func; + string_functions + ["java::java.lang.String.lastIndexOf:(Ljava/lang/String;I)I"]= + ID_cprover_string_last_index_of_func; + string_functions + ["java::java.lang.String.concat:(Ljava/lang/String;)Ljava/lang/String;"]= + ID_cprover_string_concat_func; + string_functions["java::java.lang.String.length:()I"]= + ID_cprover_string_length_func; + string_functions["java::java.lang.StringBuilder.length:()I"]= + ID_cprover_string_length_func; + string_functions["java::java.lang.String.equals:(Ljava/lang/Object;)Z"]= + ID_cprover_string_equal_func; + string_functions + ["java::java.lang.String.equalsIgnoreCase:(Ljava/lang/String;)Z"]= + ID_cprover_string_equals_ignore_case_func; + string_functions["java::java.lang.String.startsWith:(Ljava/lang/String;)Z"]= + ID_cprover_string_startswith_func; + string_functions + ["java::java.lang.String.startsWith:(Ljava/lang/String;I)Z"]= + ID_cprover_string_startswith_func; + string_functions["java::java.lang.String.endsWith:(Ljava/lang/String;)Z"]= + ID_cprover_string_endswith_func; + string_functions["java::java.lang.String.substring:(II)Ljava/lang/String;"]= + ID_cprover_string_substring_func; + string_functions["java::java.lang.String.substring:(II)Ljava/lang/String;"]= + ID_cprover_string_substring_func; + string_functions["java::java.lang.String.substring:(I)Ljava/lang/String;"]= + ID_cprover_string_substring_func; + string_functions + ["java::java.lang.StringBuilder.substring:(II)Ljava/lang/String;"]= + ID_cprover_string_substring_func; + string_functions + ["java::java.lang.StringBuilder.substring:(I)Ljava/lang/String;"]= + ID_cprover_string_substring_func; + string_functions + ["java::java.lang.String.subSequence:(II)Ljava/lang/CharSequence;"]= + ID_cprover_string_substring_func; + string_functions["java::java.lang.String.trim:()Ljava/lang/String;"]= + ID_cprover_string_trim_func; + string_functions["java::java.lang.String.toLowerCase:()Ljava/lang/String;"]= + ID_cprover_string_to_lower_case_func; + string_functions["java::java.lang.String.toUpperCase:()Ljava/lang/String;"]= + ID_cprover_string_to_upper_case_func; + string_functions["java::java.lang.String.replace:(CC)Ljava/lang/String;"]= + ID_cprover_string_replace_func; + string_functions + ["java::java.lang.String.contains:(Ljava/lang/CharSequence;)Z"]= + ID_cprover_string_contains_func; + string_functions["java::java.lang.String.compareTo:(Ljava/lang/String;)I"]= + ID_cprover_string_compare_to_func; + string_functions["java::java.lang.String.intern:()Ljava/lang/String;"]= + ID_cprover_string_intern_func; + string_functions["java::java.lang.String.isEmpty:()Z"]= + ID_cprover_string_is_empty_func; + string_functions["java::java.lang.String.charAt:(I)C"]= + ID_cprover_string_char_at_func; + string_functions["java::java.lang.StringBuilder.charAt:(I)C"]= + ID_cprover_string_char_at_func; + string_functions["java::java.lang.CharSequence.charAt:(I)C"]= + ID_cprover_string_char_at_func; + string_functions + ["java::java.lang.StringBuilder.toString:()Ljava/lang/String;"]= + ID_cprover_string_copy_func; + + string_functions["java::java.lang.String.valueOf:(F)Ljava/lang/String;"]= + ID_cprover_string_of_float_func; + string_functions["java::java.lang.Float.toString:(F)Ljava/lang/String;"]= + ID_cprover_string_of_float_func; + string_functions["java::java.lang.Integer.toString:(I)Ljava/lang/String;"]= + ID_cprover_string_of_int_func; + string_functions["java::java.lang.String.valueOf:(I)Ljava/lang/String;"]= + ID_cprover_string_of_int_func; + string_functions["java::java.lang.Integer.toHexString:(I)Ljava/lang/String;"]= + ID_cprover_string_of_int_hex_func; + string_functions["java::java.lang.String.valueOf:(L)Ljava/lang/String;"]= + ID_cprover_string_of_long_func; + string_functions["java::java.lang.String.valueOf:(D)Ljava/lang/String;"]= + ID_cprover_string_of_double_func; + string_functions["java::java.lang.String.valueOf:(Z)Ljava/lang/String;"]= + ID_cprover_string_of_bool_func; + string_functions["java::java.lang.String.valueOf:(C)Ljava/lang/String;"]= + ID_cprover_string_of_char_func; + string_functions["java::java.lang.Integer.parseInt:(Ljava/lang/String;)I"]= + ID_cprover_string_parse_int_func; + + side_effect_functions + ["java::java.lang.StringBuilder.append:(Ljava/lang/String;)" + "Ljava/lang/StringBuilder;"]= + ID_cprover_string_concat_func; + side_effect_functions["java::java.lang.StringBuilder.setCharAt:(IC)V"]= + ID_cprover_string_char_set_func; + side_effect_functions + ["java::java.lang.StringBuilder.append:(I)Ljava/lang/StringBuilder;"]= + ID_cprover_string_concat_int_func; + side_effect_functions + ["java::java.lang.StringBuilder.append:(J)Ljava/lang/StringBuilder;"]= + ID_cprover_string_concat_long_func; + side_effect_functions + ["java::java.lang.StringBuilder.append:(Z)Ljava/lang/StringBuilder;"]= + ID_cprover_string_concat_bool_func; + side_effect_functions + ["java::java.lang.StringBuilder.append:(C)Ljava/lang/StringBuilder;"]= + ID_cprover_string_concat_char_func; + side_effect_functions + ["java::java.lang.StringBuilder.append:(D)Ljava/lang/StringBuilder;"]= + ID_cprover_string_concat_double_func; + side_effect_functions + ["java::java.lang.StringBuilder.append:(F)Ljava/lang/StringBuilder;"]= + ID_cprover_string_concat_float_func; + side_effect_functions + ["java::java.lang.StringBuilder.appendCodePoint:(I)" + "Ljava/lang/StringBuilder;"]= + ID_cprover_string_concat_code_point_func; + side_effect_functions + ["java::java.lang.StringBuilder.delete:(II)Ljava/lang/StringBuilder;"]= + ID_cprover_string_delete_func; + side_effect_functions + ["java::java.lang.StringBuilder.deleteCharAt:(I)Ljava/lang/StringBuilder;"]= + ID_cprover_string_delete_char_at_func; + side_effect_functions + ["java::java.lang.StringBuilder.insert:(ILjava/lang/String;)" + "Ljava/lang/StringBuilder;"]= + ID_cprover_string_insert_func; + side_effect_functions + ["java::java.lang.StringBuilder.insert:(II)Ljava/lang/StringBuilder;"]= + ID_cprover_string_insert_int_func; + side_effect_functions + ["java::java.lang.StringBuilder.insert:(IJ)Ljava/lang/StringBuilder;"]= + ID_cprover_string_insert_long_func; + side_effect_functions + ["java::java.lang.StringBuilder.insert:(IC)Ljava/lang/StringBuilder;"]= + ID_cprover_string_insert_char_func; + side_effect_functions + ["java::java.lang.StringBuilder.insert:(IZ)Ljava/lang/StringBuilder;"]= + ID_cprover_string_insert_bool_func; + side_effect_functions + ["java::java.lang.StringBuilder.setLength:(I)V"]= + ID_cprover_string_set_length_func; + + + side_effect_char_array_functions + ["java::java.lang.StringBuilder.insert:(I[CII)Ljava/lang/StringBuilder;"]= + ID_cprover_string_insert_char_array_func; + side_effect_char_array_functions + ["java::java.lang.StringBuilder.insert:(I[C)Ljava/lang/StringBuilder;"]= + ID_cprover_string_insert_char_array_func; + + string_function_calls + ["java::java.lang.String.:(Ljava/lang/String;)V"]= + ID_cprover_string_copy_func; + string_function_calls + ["java::java.lang.String.:(Ljava/lang/StringBuilder;)V"]= + ID_cprover_string_copy_func; + string_function_calls + ["java::java.lang.StringBuilder.:(Ljava/lang/String;)V"]= + ID_cprover_string_copy_func; + string_function_calls["java::java.lang.String.:()V"]= + ID_cprover_string_empty_string_func; + string_function_calls["java::java.lang.StringBuilder.:()V"]= + ID_cprover_string_empty_string_func; + + string_of_char_array_function_calls["java::java.lang.String.:([C)V"]= + ID_cprover_string_of_char_array_func; + string_of_char_array_function_calls["java::java.lang.String.:([CII)V"]= + ID_cprover_string_of_char_array_func; + + string_of_char_array_functions + ["java::java.lang.String.valueOf:([CII)Ljava/lang/String;"]= + ID_cprover_string_of_char_array_func; + string_of_char_array_functions + ["java::java.lang.String.valueOf:([C)Ljava/lang/String;"]= + ID_cprover_string_of_char_array_func; + string_of_char_array_functions + ["java::java.lang.String.copyValueOf:([CII)Ljava/lang/String;"]= + ID_cprover_string_of_char_array_func; + string_of_char_array_functions + ["java::java.lang.String.copyValueOf:([C)Ljava/lang/String;"]= + ID_cprover_string_of_char_array_func; + + c_string_functions["__CPROVER_uninterpreted_string_literal_func"]= + ID_cprover_string_literal_func; + c_string_functions["__CPROVER_uninterpreted_string_char_at_func"]= + ID_cprover_string_char_at_func; + c_string_functions["__CPROVER_uninterpreted_string_equal_func"]= + ID_cprover_string_equal_func; + c_string_functions["__CPROVER_uninterpreted_string_concat_func"]= + ID_cprover_string_concat_func; + c_string_functions["__CPROVER_uninterpreted_string_length_func"]= + ID_cprover_string_length_func; + c_string_functions["__CPROVER_uninterpreted_string_substring_func"]= + ID_cprover_string_substring_func; + c_string_functions["__CPROVER_uninterpreted_string_is_prefix_func"]= + ID_cprover_string_is_prefix_func; + c_string_functions["__CPROVER_uninterpreted_string_is_suffix_func"]= + ID_cprover_string_is_suffix_func; + c_string_functions["__CPROVER_uninterpreted_string_contains_func"]= + ID_cprover_string_contains_func; + c_string_functions["__CPROVER_uninterpreted_string_index_of_func"]= + ID_cprover_string_index_of_func; + c_string_functions["__CPROVER_uninterpreted_string_last_index_of_func"]= + ID_cprover_string_last_index_of_func; + c_string_functions["__CPROVER_uninterpreted_string_char_set_func"]= + ID_cprover_string_char_set_func; + c_string_functions["__CPROVER_uninterpreted_string_copy_func"]= + ID_cprover_string_copy_func; + c_string_functions["__CPROVER_uninterpreted_string_parse_int_func"]= + ID_cprover_string_parse_int_func; + c_string_functions["__CPROVER_uninterpreted_string_of_int_func"]= + ID_cprover_string_of_int_func; + + signatures["java::java.lang.String.equals:(Ljava/lang/Object;)Z"]="SSZ"; + signatures + ["java::java.lang.String.contains:(Ljava/lang/CharSequence;)Z"]= + "SSZ"; +} + +/*******************************************************************\ + +Constructor: string_refine_preprocesst::string_refine_preprocesst + + Inputs: a symbol table, goto functions, a message handler + + Purpose: process the goto function by replacing calls to string functions + +\*******************************************************************/ + +string_refine_preprocesst::string_refine_preprocesst( + symbol_tablet &_symbol_table, + goto_functionst &_goto_functions, + message_handlert &_message_handler): + messaget(_message_handler), + ns(_symbol_table), + symbol_table(_symbol_table), + goto_functions(_goto_functions), + next_symbol_id(0), + jls_ptr(symbol_typet("java::java.lang.String")) +{ + initialize_string_function_table(); + Forall_goto_functions(it, goto_functions) + replace_string_calls(it); +} diff --git a/src/goto-programs/string_refine_preprocess.h b/src/goto-programs/string_refine_preprocess.h new file mode 100644 index 00000000000..37e178f799a --- /dev/null +++ b/src/goto-programs/string_refine_preprocess.h @@ -0,0 +1,215 @@ +/*******************************************************************\ + +Module: Preprocess a goto-programs so that calls to the java String + library are recognized by the PASS algorithm + +Author: Romain Brenguier + +Date: September 2016 + +\*******************************************************************/ + +#ifndef CPROVER_GOTO_PROGRAMS_STRING_REFINE_PREPROCESS_H +#define CPROVER_GOTO_PROGRAMS_STRING_REFINE_PREPROCESS_H + +#include +#include + +class string_refine_preprocesst:public messaget +{ + public: + string_refine_preprocesst( + symbol_tablet &, goto_functionst &, message_handlert &); + + private: + namespacet ns; + symbol_tablet & symbol_table; + goto_functionst & goto_functions; + + typedef std::unordered_map id_mapt; + typedef std::unordered_map expr_mapt; + + // String builders maps the different names of a same StringBuilder object + // to a unique expression. + expr_mapt string_builders; + + // Map name of Java string functions to there equivalent in the solver + id_mapt side_effect_functions; + id_mapt string_functions; + id_mapt c_string_functions; + id_mapt string_function_calls; + id_mapt string_of_char_array_functions; + id_mapt string_of_char_array_function_calls; + id_mapt side_effect_char_array_functions; + + std::unordered_map signatures; + expr_mapt hidden_strings; + expr_mapt java_to_cprover_strings; + + // unique id for each newly created symbols + int next_symbol_id; + + void initialize_string_function_table(); + + symbol_exprt fresh_array( + const typet &type, const source_locationt &location); + symbol_exprt fresh_string( + const typet &type, const source_locationt &location); + + // get the data member of a java string + static exprt get_data(const exprt &string, const typet &data_type) + { + return member_exprt(string, "data", data_type); + } + + // get the length member of a java string + exprt get_length(const exprt &string, const typet &length_type) + { + return member_exprt(string, "length", length_type); + } + + // type of pointers to string + pointer_typet jls_ptr; + exprt replace_string(const exprt &in); + exprt replace_string_in_assign(const exprt &in); + + void insert_assignments( + goto_programt &goto_program, + goto_programt::targett &target, + irep_idt function, + source_locationt location, + const std::list &va); + + exprt replace_string_pointer(const exprt &in); + + // Replace string builders by expression of the mapping and make + // assignments for strings as string_exprt + exprt::operandst process_arguments( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt::operandst &arguments, + const source_locationt &location, + const std::string &signature=""); + + // Signature of the named function if it is defined in the signature map, + // empty string otherwise + std::string function_signature(const irep_idt &function_id); + + void declare_function(irep_idt function_name, const typet &type); + + void get_data_and_length_type_of_string( + const exprt &expr, typet &data_type, typet &length_type); + + function_application_exprt build_function_application( + const irep_idt &function_name, + const typet &type, + const source_locationt &location, + const exprt::operandst &arguments); + + void make_normal_assign( + goto_programt &goto_program, + goto_programt::targett target, + const exprt &lhs, + const code_typet &function_type, + const irep_idt &function_name, + const exprt::operandst &arguments, + const source_locationt &location, + const std::string &signature=""); + + void make_string_assign( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &lhs, + const code_typet &function_type, + const irep_idt &function_name, + const exprt::operandst &arguments, + const source_locationt &location, + const std::string &signature); + + void make_assign( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &lhs, + const code_typet &function_type, + const irep_idt &function_name, + const exprt::operandst &arg, + const source_locationt &loc, + const std::string &sig); + + exprt make_cprover_string_assign( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &rhs, + const source_locationt &location); + + void make_string_copy( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &lhs, + const exprt &argument, + const source_locationt &location); + + void make_string_function( + goto_programt &goto_program, + goto_programt::targett &target, + const irep_idt &function_name, + const std::string &signature, + bool assign_first_arg=false, + bool skip_first_arg=false); + + void make_string_function( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &lhs, + const code_typet &function_type, + const irep_idt &function_name, + const exprt::operandst &arguments, + const source_locationt &location, + const std::string &signature); + + void make_string_function_call( + goto_programt &goto_program, + goto_programt::targett &target, + const irep_idt &function_name, + const std::string &signature); + + void make_string_function_side_effect( + goto_programt &goto_program, + goto_programt::targett &target, + const irep_idt &function_name, + const std::string &signature); + + void make_to_char_array_function( + goto_programt &goto_program, goto_programt::targett &); + + exprt make_cprover_char_array_assign( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &rhs, + const source_locationt &location); + + void make_char_array_function( + goto_programt &goto_program, + goto_programt::targett &target, + const irep_idt &function_name, + const std::string &signature, + std::size_t index, + bool assign_first_arg=false, + bool skip_first_arg=false); + + void make_char_array_function_call( + goto_programt &goto_program, + goto_programt::targett &target, + const irep_idt &function_name, + const std::string &signature); + + void make_char_array_side_effect( + goto_programt &goto_program, + goto_programt::targett &target, + const irep_idt &function_name, + const std::string &signature); + + void replace_string_calls(goto_functionst::function_mapt::iterator f_it); +}; + +#endif diff --git a/src/util/std_expr.h b/src/util/std_expr.h index a2f78ab25e8..5c5856b4a9d 100644 --- a/src/util/std_expr.h +++ b/src/util/std_expr.h @@ -3450,6 +3450,19 @@ class function_application_exprt:public exprt operands().resize(2); } + explicit function_application_exprt(const typet &_type): + exprt(ID_function_application, _type) + { + operands().resize(2); + } + + function_application_exprt( + const symbol_exprt &_function, const typet &_type): + function_application_exprt(_type) // NOLINT(runtime/explicit) + { + function()=_function; + } + exprt &function() { return op0(); From 3a2e210d482e568f6114108ce28bf14aa43569ab Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 17 Feb 2017 13:10:40 +0000 Subject: [PATCH 02/10] Moving is_java_string_type functions to string_preprocess This avoid dependencies between goto-programs and solver. We also removed function is_unrefined_string_type which should not be needed in the string solver. Removed also mention of java string types and unrefined types in the solver. These mentions should not be necessary, since we are not supposed to do anything java specific. The solver should only have to deal with refined string types and possibly char arrays. --- .../string_refine_preprocess.cpp | 146 ++++++++++++++++-- src/goto-programs/string_refine_preprocess.h | 10 ++ .../refinement/refined_string_type.cpp | 95 ------------ src/solvers/refinement/refined_string_type.h | 36 +---- .../string_constraint_generator_constants.cpp | 2 +- .../string_constraint_generator_indexof.cpp | 20 ++- .../string_constraint_generator_main.cpp | 4 +- src/solvers/refinement/string_refinement.cpp | 6 +- 8 files changed, 166 insertions(+), 153 deletions(-) diff --git a/src/goto-programs/string_refine_preprocess.cpp b/src/goto-programs/string_refine_preprocess.cpp index c4dc1a92960..b14153c26c1 100644 --- a/src/goto-programs/string_refine_preprocess.cpp +++ b/src/goto-programs/string_refine_preprocess.cpp @@ -22,7 +22,125 @@ Date: September 2016 #include "string_refine_preprocess.h" -/******************************************************************* \ +/*******************************************************************\ + +Function: string_refine_preprocesst::is_java_string_pointer_type + + Inputs: a type + + Outputs: Boolean telling whether the type is that of java string pointers + +\*******************************************************************/ + +bool string_refine_preprocesst::is_java_string_pointer_type(const typet &type) +{ + if(type.id()==ID_pointer) + { + const pointer_typet &pt=to_pointer_type(type); + const typet &subtype=pt.subtype(); + return is_java_string_type(subtype); + } + return false; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::is_java_string_type + + Inputs: a type + + Outputs: Boolean telling whether the type is that of java string + +\*******************************************************************/ + +bool string_refine_preprocesst::is_java_string_type(const typet &type) +{ + if(type.id()==ID_symbol) + { + const irep_idt &tag=to_symbol_type(type).get_identifier(); + return tag=="java::java.lang.String"; + } + else if(type.id()==ID_struct) + { + const irep_idt &tag=to_struct_type(type).get_tag(); + return tag=="java.lang.String"; + } + return false; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::is_java_string_builder_type + + Inputs: a type + + Outputs: Boolean telling whether the type is that of java string builder + +\*******************************************************************/ + +bool string_refine_preprocesst::is_java_string_builder_type(const typet &type) +{ + if(type.id()==ID_pointer) + { + const pointer_typet &pt=to_pointer_type(type); + const typet &subtype=pt.subtype(); + if(subtype.id()==ID_struct) + { + const irep_idt &tag=to_struct_type(subtype).get_tag(); + return tag=="java.lang.StringBuilder"; + } + } + return false; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::is_java_string_builder_pointer_type + + Inputs: a type + + Outputs: Boolean telling whether the type is that of java StringBuilder + pointers + +\*******************************************************************/ + +bool string_refine_preprocesst::is_java_string_builder_pointer_type( + const typet &type) +{ + if(type.id()==ID_pointer) + { + const pointer_typet &pt=to_pointer_type(type); + const typet &subtype=pt.subtype(); + return is_java_string_builder_type(subtype); + } + return false; +} +/*******************************************************************\ + +Function: string_refine_preprocesst::is_java_char_sequence_type + + Inputs: a type + + Outputs: Boolean telling whether the type is that of java char sequence + +\*******************************************************************/ + +bool string_refine_preprocesst::is_java_char_sequence_type(const typet &type) +{ + if(type.id()==ID_pointer) + { + const pointer_typet &pt=to_pointer_type(type); + const typet &subtype=pt.subtype(); + if(subtype.id()==ID_struct) + { + const irep_idt &tag=to_struct_type(subtype).get_tag(); + return tag=="java.lang.CharSequence"; + } + } + return false; +} + +/*******************************************************************\ Function: string_refine_preprocesst::fresh_array @@ -114,8 +232,8 @@ Function: string_refine_preprocesst::get_data_and_length_type_of_string void string_refine_preprocesst::get_data_and_length_type_of_string( const exprt &expr, typet &data_type, typet &length_type) { - assert(refined_string_typet::is_java_string_type(expr.type()) || - refined_string_typet::is_java_string_builder_type(expr.type())); + assert(is_java_string_type(expr.type()) || + is_java_string_builder_type(expr.type())); typet object_type=ns.follow(expr.type()); const struct_typet &struct_type=to_struct_type(object_type); for(const auto &component : struct_type.components()) @@ -146,7 +264,7 @@ exprt string_refine_preprocesst::make_cprover_string_assign( const exprt &rhs, const source_locationt &location) { - if(refined_string_typet::is_java_string_pointer_type(rhs.type())) + if(is_java_string_pointer_type(rhs.type())) { auto pair=java_to_cprover_strings.insert( std::pair(rhs, nil_exprt())); @@ -183,7 +301,7 @@ exprt string_refine_preprocesst::make_cprover_string_assign( return pair.first->second; } else if(rhs.id()==ID_typecast && - refined_string_typet::is_java_string_pointer_type(rhs.op0().type())) + is_java_string_pointer_type(rhs.op0().type())) { exprt new_rhs=make_cprover_string_assign( goto_program, target, rhs.op0(), location); @@ -303,8 +421,7 @@ void string_refine_preprocesst::make_string_assign( const source_locationt &location, const std::string &signature) { - assert(refined_string_typet::is_java_string_pointer_type( - function_type.return_type())); + assert(is_java_string_pointer_type(function_type.return_type())); dereference_exprt deref(lhs, lhs.type().subtype()); typet object_type=ns.follow(deref.type()); exprt object_size=size_of_expr(object_type, ns); @@ -371,8 +488,7 @@ void string_refine_preprocesst::make_assign( const source_locationt &loc, const std::string &sig) { - if(refined_string_typet::is_java_string_pointer_type( - function_type.return_type())) + if(is_java_string_pointer_type(function_type.return_type())) make_string_assign( goto_program, target, lhs, function_type, function_name, arg, loc, sig); else @@ -404,8 +520,8 @@ void string_refine_preprocesst::make_string_copy( const source_locationt &location) { // TODO : treat CharSequence and StringBuffer - assert(refined_string_typet::is_java_string_pointer_type(lhs.type()) || - refined_string_typet::is_java_string_builder_pointer_type(lhs.type())); + assert(is_java_string_pointer_type(lhs.type()) || + is_java_string_builder_pointer_type(lhs.type())); exprt deref=dereference_exprt(lhs, lhs.type().subtype()); typet length_type, data_type; @@ -451,8 +567,7 @@ void string_refine_preprocesst::make_string_function( const source_locationt &location, const std::string &signature) { - if(refined_string_typet::is_java_string_pointer_type( - function_type.return_type())) + if(is_java_string_pointer_type(function_type.return_type())) make_string_assign( goto_program, target, @@ -633,8 +748,7 @@ void string_refine_preprocesst::make_to_char_array_function( assert(!function_call.arguments().empty()); const exprt &string_argument=function_call.arguments()[0]; - assert(refined_string_typet::is_java_string_pointer_type( - string_argument.type())); + assert(is_java_string_pointer_type(string_argument.type())); dereference_exprt deref(string_argument, string_argument.type().subtype()); typet length_type, data_type; @@ -870,7 +984,7 @@ exprt::operandst string_refine_preprocesst::process_arguments( { while(arg.id()==ID_typecast) arg=arg.op0(); - if(!refined_string_typet::is_java_string_type(arg.type())) + if(!is_java_string_type(arg.type())) arg=typecast_exprt(arg, jls_ptr); } exprt arg2=make_cprover_string_assign( diff --git a/src/goto-programs/string_refine_preprocess.h b/src/goto-programs/string_refine_preprocess.h index 37e178f799a..613d0161926 100644 --- a/src/goto-programs/string_refine_preprocess.h +++ b/src/goto-programs/string_refine_preprocess.h @@ -51,6 +51,16 @@ class string_refine_preprocesst:public messaget void initialize_string_function_table(); + static bool is_java_string_pointer_type(const typet &type); + + static bool is_java_string_type(const typet &type); + + static bool is_java_string_builder_type(const typet &type); + + static bool is_java_string_builder_pointer_type(const typet &type); + + static bool is_java_char_sequence_type(const typet &type); + symbol_exprt fresh_array( const typet &type, const source_locationt &location); symbol_exprt fresh_string( diff --git a/src/solvers/refinement/refined_string_type.cpp b/src/solvers/refinement/refined_string_type.cpp index 012d30eb8de..3362c71e0db 100644 --- a/src/solvers/refinement/refined_string_type.cpp +++ b/src/solvers/refinement/refined_string_type.cpp @@ -48,98 +48,3 @@ bool refined_string_typet::is_c_string_type(const typet &type) to_struct_type(type).get_tag()==CPROVER_PREFIX"string"; } -/*******************************************************************\ - -Function: refined_string_typet::is_java_string_pointer_type - - Inputs: a type - - Outputs: Boolean telling whether the type is that of java string pointers - -\*******************************************************************/ - -bool refined_string_typet::is_java_string_pointer_type(const typet &type) -{ - if(type.id()==ID_pointer) - { - const pointer_typet &pt=to_pointer_type(type); - const typet &subtype=pt.subtype(); - return is_java_string_type(subtype); - } - return false; -} - -/*******************************************************************\ - -Function: refined_string_typet::is_java_string_type - - Inputs: a type - - Outputs: Boolean telling whether the type is that of java string - -\*******************************************************************/ - -bool refined_string_typet::is_java_string_type(const typet &type) -{ - if(type.id()==ID_symbol) - { - irep_idt tag=to_symbol_type(type).get_identifier(); - return tag=="java::java.lang.String"; - } - else if(type.id()==ID_struct) - { - irep_idt tag=to_struct_type(type).get_tag(); - return tag=="java.lang.String"; - } - return false; -} - -/*******************************************************************\ - -Function: refined_string_typet::is_java_string_builder_type - - Inputs: a type - - Outputs: Boolean telling whether the type is that of java string builder - -\*******************************************************************/ - -bool refined_string_typet::is_java_string_builder_type(const typet &type) -{ - if(type.id()==ID_pointer) - { - const pointer_typet &pt=to_pointer_type(type); - const typet &subtype=pt.subtype(); - if(subtype.id()==ID_struct) - { - irep_idt tag=to_struct_type(subtype).get_tag(); - return tag=="java.lang.StringBuilder"; - } - } - return false; -} - -/*******************************************************************\ - -Function: refined_string_typet::is_java_char_sequence_type - - Inputs: a type - - Outputs: Boolean telling whether the type is that of java char sequence - -\*******************************************************************/ - -bool refined_string_typet::is_java_char_sequence_type(const typet &type) -{ - if(type.id()==ID_pointer) - { - const pointer_typet &pt=to_pointer_type(type); - const typet &subtype=pt.subtype(); - if(subtype.id()==ID_struct) - { - const irep_idt &tag=to_struct_type(subtype).get_tag(); - return tag=="java.lang.CharSequence"; - } - } - return false; -} diff --git a/src/solvers/refinement/refined_string_type.h b/src/solvers/refinement/refined_string_type.h index 3ecc0ac3a9f..3b36b19e826 100644 --- a/src/solvers/refinement/refined_string_type.h +++ b/src/solvers/refinement/refined_string_type.h @@ -33,41 +33,20 @@ class refined_string_typet: public struct_typet const typet &get_char_type() const { - assert(components().size()==2); - return components()[0].type(); + return get_content_type().subtype(); } const typet &get_index_type() const { - return get_content_type().size().type(); + assert(components().size()==2); + return components()[0].type(); } - // For C the unrefined string type is __CPROVER_string, for java it is a - // pointer to a struct with tag java.lang.String + // For C the unrefined string type is __CPROVER_string static bool is_c_string_type(const typet &type); - static bool is_java_string_pointer_type(const typet &type); - - static bool is_java_string_type(const typet &type); - - static bool is_java_string_builder_type(const typet &type); - - static bool is_java_char_sequence_type(const typet &type); - - static bool is_unrefined_string_type(const typet &type) - { - return ( - is_c_string_type(type) || - is_java_string_pointer_type(type) || - is_java_string_builder_type(type) || - is_java_char_sequence_type(type)); - } - - static bool is_unrefined_string(const exprt &expr) - { - return (is_unrefined_string_type(expr.type())); - } + static bool is_refined_string_type(const typet &type); constant_exprt index_of_int(int i) const { @@ -75,9 +54,10 @@ class refined_string_typet: public struct_typet } }; -const refined_string_typet &to_refined_string_type(const typet &type) +extern inline const refined_string_typet &to_refined_string_type( + const typet &type) { - assert(type.id()==ID_struct); + assert(refined_string_typet::is_refined_string_type(type)); return static_cast(type); } diff --git a/src/solvers/refinement/string_constraint_generator_constants.cpp b/src/solvers/refinement/string_constraint_generator_constants.cpp index 90769747949..64ffabfd266 100644 --- a/src/solvers/refinement/string_constraint_generator_constants.cpp +++ b/src/solvers/refinement/string_constraint_generator_constants.cpp @@ -132,7 +132,7 @@ string_exprt string_constraint_generatort::add_axioms_from_literal( else { // Java string constant - assert(refined_string_typet::is_unrefined_string_type(arg.type())); + assert(arg.id()==ID_symbol); const exprt &s=arg.op0(); // It seems the value of the string is lost, diff --git a/src/solvers/refinement/string_constraint_generator_indexof.cpp b/src/solvers/refinement/string_constraint_generator_indexof.cpp index 93db048458b..283de683bd6 100644 --- a/src/solvers/refinement/string_constraint_generator_indexof.cpp +++ b/src/solvers/refinement/string_constraint_generator_indexof.cpp @@ -186,14 +186,16 @@ exprt string_constraint_generatort::add_axioms_for_index_of( else assert(false); - if(refined_string_typet::is_java_string_pointer_type(c.type())) + if(c.type().id()==ID_unsignedbv) + { + return add_axioms_for_index_of( + str, typecast_exprt(c, ref_type.get_char_type()), from_index); + } + else { string_exprt sub=add_axioms_for_string_expr(c); return add_axioms_for_index_of_string(str, sub, from_index); } - else - return add_axioms_for_index_of( - str, typecast_exprt(c, ref_type.get_char_type()), from_index); } exprt string_constraint_generatort::add_axioms_for_last_index_of( @@ -280,12 +282,14 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of( else assert(false); - if(refined_string_typet::is_java_string_pointer_type(c.type())) + if(c.type().id()==ID_unsignedbv) + { + return add_axioms_for_last_index_of( + str, typecast_exprt(c, ref_type.get_char_type()), from_index); + } + else { string_exprt sub=add_axioms_for_string_expr(c); return add_axioms_for_last_index_of_string(str, sub, from_index); } - else - return add_axioms_for_last_index_of( - str, typecast_exprt(c, ref_type.get_char_type()), from_index); } diff --git a/src/solvers/refinement/string_constraint_generator_main.cpp b/src/solvers/refinement/string_constraint_generator_main.cpp index 5a269e5ad3b..0179a2fcb61 100644 --- a/src/solvers/refinement/string_constraint_generator_main.cpp +++ b/src/solvers/refinement/string_constraint_generator_main.cpp @@ -215,10 +215,10 @@ string_exprt string_constraint_generatort::add_axioms_for_if( const if_exprt &expr) { assert( - refined_string_typet::is_unrefined_string_type(expr.true_case().type())); + refined_string_typet::is_c_string_type(expr.true_case().type())); string_exprt t=add_axioms_for_string_expr(expr.true_case()); assert( - refined_string_typet::is_unrefined_string_type(expr.false_case().type())); + refined_string_typet::is_c_string_type(expr.false_case().type())); string_exprt f=add_axioms_for_string_expr(expr.false_case()); const refined_string_typet &ref_type=to_refined_string_type(t.type()); const typet &index_type=ref_type.get_index_type(); diff --git a/src/solvers/refinement/string_refinement.cpp b/src/solvers/refinement/string_refinement.cpp index 16b89bc43c8..db9a2c460cc 100644 --- a/src/solvers/refinement/string_refinement.cpp +++ b/src/solvers/refinement/string_refinement.cpp @@ -146,7 +146,7 @@ bvt string_refinementt::convert_symbol(const exprt &expr) const irep_idt &identifier=expr.get(ID_identifier); assert(!identifier.empty()); - if(refined_string_typet::is_unrefined_string_type(type)) + if(refined_string_typet::is_refined_string_type(type)) { string_exprt str= generator.find_or_add_string_of_symbol(to_symbol_expr(expr)); @@ -216,7 +216,7 @@ bool string_refinementt::boolbv_set_equality_to_true(const equal_exprt &expr) if(expr.rhs().id()==ID_typecast) { exprt uncast=to_typecast_expr(expr.rhs()).op(); - if(refined_string_typet::is_unrefined_string_type(uncast.type())) + if(refined_string_typet::is_refined_string_type(uncast.type())) { debug() << "(sr) detected casted string" << eom; symbol_exprt sym=to_symbol_expr(expr.lhs()); @@ -225,7 +225,7 @@ bool string_refinementt::boolbv_set_equality_to_true(const equal_exprt &expr) } } - if(refined_string_typet::is_unrefined_string_type(type)) + if(refined_string_typet::is_refined_string_type(type)) { symbol_exprt sym=to_symbol_expr(expr.lhs()); generator.set_string_symbol_equal_to_expr(sym, expr.rhs()); From 70af9ce6148e03ed7c2179642486651db06ff47f Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 24 Feb 2017 11:02:55 +0000 Subject: [PATCH 03/10] Moving refined_string_type to util This is a more appropriate location for this module since it's used both in the preprocessing of goto-programs and the string solver. --- src/goto-programs/string_refine_preprocess.cpp | 3 +-- src/solvers/refinement/string_constraint.h | 2 +- src/solvers/refinement/string_constraint_generator.h | 2 +- src/{solvers/refinement => util}/refined_string_type.cpp | 0 src/{solvers/refinement => util}/refined_string_type.h | 4 ++-- 5 files changed, 5 insertions(+), 6 deletions(-) rename src/{solvers/refinement => util}/refined_string_type.cpp (100%) rename src/{solvers/refinement => util}/refined_string_type.h (93%) diff --git a/src/goto-programs/string_refine_preprocess.cpp b/src/goto-programs/string_refine_preprocess.cpp index b14153c26c1..ec02988d577 100644 --- a/src/goto-programs/string_refine_preprocess.cpp +++ b/src/goto-programs/string_refine_preprocess.cpp @@ -14,10 +14,9 @@ Date: September 2016 #include #include #include +#include #include #include -// TODO: refined_string_type should be moved to util -#include #include #include "string_refine_preprocess.h" diff --git a/src/solvers/refinement/string_constraint.h b/src/solvers/refinement/string_constraint.h index 61a6f3ebdd6..4b8d1229e09 100644 --- a/src/solvers/refinement/string_constraint.h +++ b/src/solvers/refinement/string_constraint.h @@ -15,7 +15,7 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com #include #include -#include +#include class string_constraintt: public exprt { diff --git a/src/solvers/refinement/string_constraint_generator.h b/src/solvers/refinement/string_constraint_generator.h index 2a56f09fddd..ed898cb9a18 100644 --- a/src/solvers/refinement/string_constraint_generator.h +++ b/src/solvers/refinement/string_constraint_generator.h @@ -14,7 +14,7 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com #define CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H #include -#include +#include #include class string_constraint_generatort diff --git a/src/solvers/refinement/refined_string_type.cpp b/src/util/refined_string_type.cpp similarity index 100% rename from src/solvers/refinement/refined_string_type.cpp rename to src/util/refined_string_type.cpp diff --git a/src/solvers/refinement/refined_string_type.h b/src/util/refined_string_type.h similarity index 93% rename from src/solvers/refinement/refined_string_type.h rename to src/util/refined_string_type.h index 3b36b19e826..477b00139ed 100644 --- a/src/solvers/refinement/refined_string_type.h +++ b/src/util/refined_string_type.h @@ -10,8 +10,8 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com \*******************************************************************/ -#ifndef CPROVER_SOLVERS_REFINEMENT_REFINED_STRING_TYPE_H -#define CPROVER_SOLVERS_REFINEMENT_REFINED_STRING_TYPE_H +#ifndef CPROVER_UTIL_REFINED_STRING_TYPE_H +#define CPROVER_UTIL_REFINED_STRING_TYPE_H #include #include From 2929d7f04a77c3a805c61e09d19c1a9d99423411 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Mon, 27 Feb 2017 11:14:11 +0000 Subject: [PATCH 04/10] Removed distinction between c string type and refined string type --- src/util/refined_string_type.cpp | 9 +++++---- src/util/refined_string_type.h | 4 ---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/util/refined_string_type.cpp b/src/util/refined_string_type.cpp index 3362c71e0db..0625149cf83 100644 --- a/src/util/refined_string_type.cpp +++ b/src/util/refined_string_type.cpp @@ -29,22 +29,23 @@ refined_string_typet::refined_string_typet( array_typet char_array(char_type, infinite_index); components().emplace_back("length", index_type); components().emplace_back("content", char_array); + set_tag(CPROVER_PREFIX"refined_string_type"); } /*******************************************************************\ -Function: refined_string_typet::is_c_string_type +Function: refined_string_typet::is_refined_string_type Inputs: a type - Outputs: Boolean telling whether the type is that of C strings + Outputs: Boolean telling whether the input is a refined string type \*******************************************************************/ -bool refined_string_typet::is_c_string_type(const typet &type) +bool refined_string_typet::is_refined_string_type(const typet &type) { return type.id()==ID_struct && - to_struct_type(type).get_tag()==CPROVER_PREFIX"string"; + to_struct_type(type).get_tag()==CPROVER_PREFIX"refined_string_type"; } diff --git a/src/util/refined_string_type.h b/src/util/refined_string_type.h index 477b00139ed..a0cb7500e7f 100644 --- a/src/util/refined_string_type.h +++ b/src/util/refined_string_type.h @@ -42,10 +42,6 @@ class refined_string_typet: public struct_typet return components()[0].type(); } - // For C the unrefined string type is __CPROVER_string - - static bool is_c_string_type(const typet &type); - static bool is_refined_string_type(const typet &type); constant_exprt index_of_int(int i) const From 5cb0e5e09eac930280c6aa53a0c6be0410700820 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Mon, 27 Feb 2017 11:14:21 +0000 Subject: [PATCH 05/10] Removed mention of c string type Refined string type should be used instead as we are trying to be language independent. --- src/solvers/refinement/string_constraint_generator_main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solvers/refinement/string_constraint_generator_main.cpp b/src/solvers/refinement/string_constraint_generator_main.cpp index 0179a2fcb61..7fe510c2e35 100644 --- a/src/solvers/refinement/string_constraint_generator_main.cpp +++ b/src/solvers/refinement/string_constraint_generator_main.cpp @@ -215,10 +215,10 @@ string_exprt string_constraint_generatort::add_axioms_for_if( const if_exprt &expr) { assert( - refined_string_typet::is_c_string_type(expr.true_case().type())); + refined_string_typet::is_refined_string_type(expr.true_case().type())); string_exprt t=add_axioms_for_string_expr(expr.true_case()); assert( - refined_string_typet::is_c_string_type(expr.false_case().type())); + refined_string_typet::is_refined_string_type(expr.false_case().type())); string_exprt f=add_axioms_for_string_expr(expr.false_case()); const refined_string_typet &ref_type=to_refined_string_type(t.type()); const typet &index_type=ref_type.get_index_type(); From 32cecfba886909ae1c272b1a6780f3ae958023b5 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Tue, 7 Feb 2017 11:11:47 +0000 Subject: [PATCH 06/10] Making add_string_type more generic The class_name is now passed as argument so that we can reuse this function for StringBuilder and other "String-like" classes. --- .../java_bytecode_convert_class.cpp | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index f21b0bb1ce2..7f52c6ef77b 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -50,7 +50,16 @@ class java_bytecode_convert_classt:public messaget convert(parse_tree.parsed_class); else if(string_refinement_enabled && parse_tree.parsed_class.name=="java.lang.String") - add_string_type(); + add_string_type("java.lang.String"); + else if(string_refinement_enabled && + parse_tree.parsed_class.name=="java.lang.StringBuilder") + add_string_type("java.lang.StringBuilder"); + else if(string_refinement_enabled && + parse_tree.parsed_class.name=="java.lang.CharSequence") + add_string_type("java.lang.CharSequence"); + else if(string_refinement_enabled && + parse_tree.parsed_class.name=="java.lang.StringBuffer") + add_string_type("java.lang.StringBuffer"); else generate_class_stub(parse_tree.parsed_class.name); } @@ -72,7 +81,7 @@ class java_bytecode_convert_classt:public messaget void generate_class_stub(const irep_idt &class_name); void add_array_types(); - void add_string_type(); + void add_string_type(const irep_idt &class_name); }; /*******************************************************************\ @@ -406,15 +415,17 @@ bool java_bytecode_convert_class( Function: java_bytecode_convert_classt::add_string_type + Inputs: a name for the class such as "java.lang.String" + Purpose: Implements the java.lang.String type in the case that we provide an internal implementation. \*******************************************************************/ -void java_bytecode_convert_classt::add_string_type() +void java_bytecode_convert_classt::add_string_type(const irep_idt &class_name) { class_typet string_type; - string_type.set_tag("java.lang.String"); + string_type.set_tag(class_name); string_type.components().resize(3); string_type.components()[0].set_name("@java.lang.Object"); string_type.components()[0].set_pretty_name("@java.lang.Object"); @@ -432,8 +443,8 @@ void java_bytecode_convert_classt::add_string_type() string_type.add_base(symbol_typet("java::java.lang.Object")); symbolt string_symbol; - string_symbol.name="java::java.lang.String"; - string_symbol.base_name="java.lang.String"; + string_symbol.name="java::"+id2string(class_name); + string_symbol.base_name=id2string(class_name); string_symbol.type=string_type; string_symbol.is_type=true; @@ -445,8 +456,8 @@ void java_bytecode_convert_classt::add_string_type() symbolt string_equals_symbol; string_equals_symbol.name= "java::java.lang.String.equals:(Ljava/lang/Object;)Z"; - string_equals_symbol.base_name="java.lang.String.equals"; - string_equals_symbol.pretty_name="java.lang.String.equals"; + string_equals_symbol.base_name=id2string(class_name)+".equals"; + string_equals_symbol.pretty_name=id2string(class_name)+".equals"; string_equals_symbol.mode=ID_java; code_typet string_equals_type; From c97d82ff561c55079ae9639c26100112d8e40059 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Thu, 9 Mar 2017 15:02:08 +0000 Subject: [PATCH 07/10] new identifier for converting char pointer to array --- src/util/irep_ids.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/irep_ids.txt b/src/util/irep_ids.txt index 066a5f831cc..470a0f01c78 100644 --- a/src/util/irep_ids.txt +++ b/src/util/irep_ids.txt @@ -743,6 +743,7 @@ string_constraint string_not_contains_constraint cprover_char_literal_func cprover_string_literal_func +cprover_string_array_of_char_pointer_func cprover_string_char_at_func cprover_string_char_set_func cprover_string_code_point_at_func From 37650c9cfb24bc59c87e202433045015f5fed305 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 17 Feb 2017 13:18:54 +0000 Subject: [PATCH 08/10] Many corrections in preprocessing of strings Better signatures and string detection Better detection of string-like types and handling of char arrays Changing the way we deal with string initialisation from array Factorized part of type recognition and added StringBuilder and CharSequence to the list of java classes that should be considered as string. Changed the way we deal with StringBuilders: instead of having a map we add an assignment to the instructions. We also detect char arrays and handle them better. We now use substring and copy functions for initialisation from char array since the argument are always transformed into refined strings. For each string returned by a string function we also add into the java_string_to_cprover_string map a string_exprt. Corrected detection of typecast in make_cprover_string_assign Ensuring refined_string arguments of function applications are string_exprt Correct string_refine_preprocesst constructor. Order of initialisation is now the same as the order of declaration. This was picked up by g++ and clang. Added signatures for some StringBuilder functions. Removed map java_to_cprover_string and adapt signature for side effects. The usage of a map is not correct since strings can be modified by side effects. Signature is necessary for StringBuilders to be assigned in the right way with methods with side effects. Assign all string_exprt to refined string symbols in preprocessing. This makes it then easier to debug and to find witnesses for counter examples in the solver. Make signatures take priority over actual type and add signature for intern. Linting corrections Adding malloc for char arrays for String.toCharArray Fixing preprocessing of string function with side effect This fixes problems we were getting with some StringBuilder functions. The return value should contain a pointer to the original StringBuilder and the fields of the StringBuilder should be filled with the result of the function call. Corrected mistake in preprocessing of string functions with side effects char array assignements returns a string_exprt This is to be uniform with other preprocessing functions also returning string_exprt Preprocessing for StringBuilder.append on char array Corrected update of signature and commented out some unused code Corrected the initialization from char array We cannot use the substring function because the meaning of the third argument is different between `String.([CII)` and `String.substring(SII)` Using new id for conversion between char pointer and array Cleaning of preprocessing for strings Removed useless functions and merged some maps Make a copy of the function call to be modified Removed redeclaration of location --- .../string_refine_preprocess.cpp | 797 +++++++++--------- src/goto-programs/string_refine_preprocess.h | 71 +- 2 files changed, 416 insertions(+), 452 deletions(-) diff --git a/src/goto-programs/string_refine_preprocess.cpp b/src/goto-programs/string_refine_preprocess.cpp index ec02988d577..8403d4bf044 100644 --- a/src/goto-programs/string_refine_preprocess.cpp +++ b/src/goto-programs/string_refine_preprocess.cpp @@ -23,6 +23,32 @@ Date: September 2016 /*******************************************************************\ +Function: string_refine_preprocesst::check_java_type + + Inputs: a type and a string + + Outputs: Boolean telling whether the type is a struct with the given + tag or a symbolic type with the tag prefixed by "java::" + +\*******************************************************************/ + +bool string_refine_preprocesst::check_java_type( + const typet &type, const std::string &tag) +{ + if(type.id()==ID_symbol) + { + irep_idt tag_id=to_symbol_type(type).get_identifier(); + return tag_id=="java::"+tag; + } + else if(type.id()==ID_struct) + { + irep_idt tag_id=to_struct_type(type).get_tag(); + return tag_id==tag; + } + return false; +} +/*******************************************************************\ + Function: string_refine_preprocesst::is_java_string_pointer_type Inputs: a type @@ -54,17 +80,7 @@ Function: string_refine_preprocesst::is_java_string_type bool string_refine_preprocesst::is_java_string_type(const typet &type) { - if(type.id()==ID_symbol) - { - const irep_idt &tag=to_symbol_type(type).get_identifier(); - return tag=="java::java.lang.String"; - } - else if(type.id()==ID_struct) - { - const irep_idt &tag=to_struct_type(type).get_tag(); - return tag=="java.lang.String"; - } - return false; + return check_java_type(type, "java.lang.String"); } /*******************************************************************\ @@ -79,17 +95,7 @@ Function: string_refine_preprocesst::is_java_string_builder_type bool string_refine_preprocesst::is_java_string_builder_type(const typet &type) { - if(type.id()==ID_pointer) - { - const pointer_typet &pt=to_pointer_type(type); - const typet &subtype=pt.subtype(); - if(subtype.id()==ID_struct) - { - const irep_idt &tag=to_struct_type(subtype).get_tag(); - return tag=="java.lang.StringBuilder"; - } - } - return false; + return check_java_type(type, "java.lang.StringBuilder"); } /*******************************************************************\ @@ -114,6 +120,7 @@ bool string_refine_preprocesst::is_java_string_builder_pointer_type( } return false; } + /*******************************************************************\ Function: string_refine_preprocesst::is_java_char_sequence_type @@ -125,16 +132,67 @@ Function: string_refine_preprocesst::is_java_char_sequence_type \*******************************************************************/ bool string_refine_preprocesst::is_java_char_sequence_type(const typet &type) +{ + return check_java_type(type, "java.lang.CharSequence"); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::is_java_char_sequence_pointer_type + + Inputs: a type + + Outputs: Boolean telling whether the type is that of a pointer + to a java char sequence + +\*******************************************************************/ + +bool string_refine_preprocesst::is_java_char_sequence_pointer_type( + const typet &type) { if(type.id()==ID_pointer) { const pointer_typet &pt=to_pointer_type(type); const typet &subtype=pt.subtype(); - if(subtype.id()==ID_struct) - { - const irep_idt &tag=to_struct_type(subtype).get_tag(); - return tag=="java.lang.CharSequence"; - } + return is_java_char_sequence_type(subtype); + } + return false; +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::is_java_char_array_type + + Inputs: a type + + Outputs: Boolean telling whether the type is that of java char array + +\*******************************************************************/ + +bool string_refine_preprocesst::is_java_char_array_type(const typet &type) +{ + return check_java_type(type, "array[char]"); +} + +/*******************************************************************\ + +Function: string_refine_preprocesst::is_java_char_array_pointer_type + + Inputs: a type + + Outputs: Boolean telling whether the type is that of a pointer + to a java char array + +\*******************************************************************/ + +bool string_refine_preprocesst::is_java_char_array_pointer_type( + const typet &type) +{ + if(type.id()==ID_pointer) + { + const pointer_typet &pt=to_pointer_type(type); + const typet &subtype=pt.subtype(); + return is_java_char_array_type(subtype); } return false; } @@ -217,6 +275,32 @@ void string_refine_preprocesst::declare_function( /*******************************************************************\ +Function: string_refine_preprocesst::get_data_and_length_type_of_char_array + + Inputs: an expression, a reference to a data type and a reference to a + length type + + Purpose: assuming the expression is a char array, figure out what + the types for length and data are and put them into the references + given as argument + +\*******************************************************************/ + +void string_refine_preprocesst::get_data_and_length_type_of_char_array( + const exprt &expr, typet &data_type, typet &length_type) +{ + typet object_type=ns.follow(expr.type()); + assert(object_type.id()==ID_struct); + const struct_typet &struct_type=to_struct_type(object_type); + for(auto component : struct_type.components()) + if(component.get_name()=="length") + length_type=component.type(); + else if(component.get_name()=="data") + data_type=component.type(); +} + +/*******************************************************************\ + Function: string_refine_preprocesst::get_data_and_length_type_of_string Inputs: an expression, a reference to a data type and a reference to a @@ -232,7 +316,8 @@ void string_refine_preprocesst::get_data_and_length_type_of_string( const exprt &expr, typet &data_type, typet &length_type) { assert(is_java_string_type(expr.type()) || - is_java_string_builder_type(expr.type())); + is_java_string_builder_type(expr.type()) || + is_java_char_sequence_type(expr.type())); typet object_type=ns.follow(expr.type()); const struct_typet &struct_type=to_struct_type(object_type); for(const auto &component : struct_type.components()) @@ -263,44 +348,43 @@ exprt string_refine_preprocesst::make_cprover_string_assign( const exprt &rhs, const source_locationt &location) { - if(is_java_string_pointer_type(rhs.type())) + if(implements_java_char_sequence(rhs.type())) { - auto pair=java_to_cprover_strings.insert( - std::pair(rhs, nil_exprt())); - - if(pair.second) - { - // We do the following assignments: - // cprover_string_array = *(rhs->data) - // cprover_string = { rhs->length; cprover_string_array } - - dereference_exprt deref(rhs, rhs.type().subtype()); - - typet data_type, length_type; - get_data_and_length_type_of_string(deref, data_type, length_type); - member_exprt length(deref, "length", length_type); - symbol_exprt array_lhs=fresh_array(data_type.subtype(), location); - - // string expression for the rhs of the second assignment - string_exprt new_rhs( - length, array_lhs, refined_string_typet(length_type, data_type)); - - member_exprt data(deref, "data", data_type); - dereference_exprt deref_data(data, data_type.subtype()); - symbol_exprt lhs=fresh_string(new_rhs.type(), location); - - std::list assignments; - assignments.emplace_back(array_lhs, deref_data); - assignments.emplace_back(lhs, new_rhs); - insert_assignments( - goto_program, target, target->function, location, assignments); - target=goto_program.insert_after(target); - pair.first->second=lhs; - } - return pair.first->second; + // We do the following assignments: + // 1 length= *(rhs->length) + // 2 cprover_string_array = *(rhs->data) + // 3 cprover_string = { length; cprover_string_array } + + dereference_exprt deref(rhs, rhs.type().subtype()); + typet data_type, length_type; + get_data_and_length_type_of_string(deref, data_type, length_type); + std::list assignments; + + // 1) cprover_string_length= *(rhs->length) + member_exprt length(deref, "length", length_type); + + // 2) cprover_string_array = *(rhs->data) + symbol_exprt array_lhs=fresh_array(data_type.subtype(), location); + member_exprt data(deref, "data", data_type); + dereference_exprt deref_data(data, data_type.subtype()); + assignments.emplace_back(array_lhs, deref_data); + + // 3) cprover_string = { cprover_string_length; cprover_string_array } + // This assignment is useful for finding witnessing strings for counter + // examples + refined_string_typet ref_type(length_type, java_char_type()); + string_exprt new_rhs(length, array_lhs, ref_type); + + symbol_exprt lhs=fresh_string(new_rhs.type(), location); + assignments.emplace_back(lhs, new_rhs); + + insert_assignments( + goto_program, target, target->function, location, assignments); + target=goto_program.insert_after(target); + return new_rhs; } else if(rhs.id()==ID_typecast && - is_java_string_pointer_type(rhs.op0().type())) + implements_java_char_sequence(rhs.op0().type())) { exprt new_rhs=make_cprover_string_assign( goto_program, target, rhs.op0(), location); @@ -312,6 +396,75 @@ exprt string_refine_preprocesst::make_cprover_string_assign( /*******************************************************************\ +Function: string_refine_preprocesst::make_cprover_char_array_assign + + Inputs: a goto_program, a position in this program, an expression of + type char array pointer and a location + + Outputs: a string expression + + Purpose: Introduce a temporary variable for cprover strings; + returns the cprover_string corresponding to rhs + +\*******************************************************************/ + +string_exprt string_refine_preprocesst::make_cprover_char_array_assign( + goto_programt &goto_program, + goto_programt::targett &target, + const exprt &rhs, + const source_locationt &location) +{ + assert(is_java_char_array_pointer_type(rhs.type())); + + // We do the following assignments: + // deref=*(rhs->data) + // array= typecast(&deref); + // string={ rhs->length; array } + + dereference_exprt deref(rhs, rhs.type().subtype()); + typet length_type, data_type; + get_data_and_length_type_of_char_array(deref, data_type, length_type); + assert(data_type.id()==ID_pointer); + typet char_type=to_pointer_type(data_type).subtype(); + + refined_string_typet ref_type(length_type, java_char_type()); + typet content_type=ref_type.get_content_type(); + std::list assignments; + + // deref=*(rhs->data) + member_exprt array_rhs(deref, "data", data_type); + dereference_exprt deref_array(array_rhs, data_type.subtype()); + symbolt sym_lhs_deref=get_fresh_aux_symbol( + data_type.subtype(), + "char_array_assign$deref", + "char_array_assign$deref", + location, + ID_java, + symbol_table); + symbol_exprt lhs_deref=sym_lhs_deref.symbol_expr(); + assignments.emplace_back(lhs_deref, deref_array); + + // array=convert_pointer_to_char_array(*rhs->data) + declare_function(ID_cprover_string_array_of_char_pointer_func, content_type); + function_application_exprt fun_app(symbol_exprt( + ID_cprover_string_array_of_char_pointer_func), content_type); + fun_app.arguments().push_back(deref_array); + symbol_exprt array=fresh_array(content_type, location); + assignments.emplace_back(array, fun_app); + + // string={ rhs->length; string_array } + string_exprt new_rhs(get_length(deref, length_type), array, ref_type); + symbol_exprt lhs=fresh_string(ref_type, location); + assignments.emplace_back(lhs, new_rhs); + + insert_assignments( + goto_program, target, target->function, location, assignments); + target=goto_program.insert_after(target); + return new_rhs; +} + +/*******************************************************************\ + Function: string_refine_preprocesst::make_normal_assign Inputs: a goto_program, a position in this program, an expression lhs, @@ -336,27 +489,19 @@ void string_refine_preprocesst::make_normal_assign( const source_locationt &location, const std::string &signature) { - if(function_name==ID_cprover_string_copy_func) - { - assert(!arguments.empty()); - make_string_copy(goto_program, target, lhs, arguments[0], location); - } - else - { - function_application_exprt rhs( - symbol_exprt(function_name), function_type.return_type()); - rhs.add_source_location()=location; - declare_function(function_name, function_type); + function_application_exprt rhs( + symbol_exprt(function_name), function_type.return_type()); + rhs.add_source_location()=location; + declare_function(function_name, function_type); - exprt::operandst processed_arguments=process_arguments( - goto_program, target, arguments, location, signature); - rhs.arguments()=processed_arguments; + exprt::operandst processed_arguments=process_arguments( + goto_program, target, arguments, location, signature); + rhs.arguments()=processed_arguments; - code_assignt assignment(lhs, rhs); - assignment.add_source_location()=location; - target->make_assignment(); - target->code=assignment; - } + code_assignt assignment(lhs, rhs); + assignment.add_source_location()=location; + target->make_assignment(); + target->code=assignment; } /*******************************************************************\ @@ -420,7 +565,7 @@ void string_refine_preprocesst::make_string_assign( const source_locationt &location, const std::string &signature) { - assert(is_java_string_pointer_type(function_type.return_type())); + assert(implements_java_char_sequence(function_type.return_type())); dereference_exprt deref(lhs, lhs.type().subtype()); typet object_type=ns.follow(deref.type()); exprt object_size=size_of_expr(object_type, ns); @@ -454,98 +599,22 @@ void string_refine_preprocesst::make_string_assign( malloc_expr.type()=pointer_typet(object_type); malloc_expr.add_source_location()=location; + refined_string_typet ref_type(length_type, data_type.subtype().subtype()); + string_exprt str(tmp_length, tmp_array, ref_type); + symbol_exprt cprover_string_sym=fresh_string(ref_type, location); + std::list assigns; assigns.emplace_back(lhs, malloc_expr); assigns.emplace_back(tmp_length, rhs_length); assigns.emplace_back(lhs_length, tmp_length); assigns.emplace_back(tmp_array, rhs_data); + assigns.emplace_back(cprover_string_sym, str); assigns.emplace_back(lhs_data, address_of_exprt(tmp_array)); insert_assignments(goto_program, target, target->function, location, assigns); } /*******************************************************************\ -Function: string_refine_preprocesst::make_assign - - Inputs: a goto_program, a position in this program, an expression lhs, - a function type, a function name, a vector of arguments, a location - and a signature - - Purpose: assign the result of the function application to lhs, - in case the function type is string, it does a special assignment - using `make_string_assign` - -\*******************************************************************/ - -void string_refine_preprocesst::make_assign( - goto_programt &goto_program, - goto_programt::targett &target, - const exprt &lhs, - const code_typet &function_type, - const irep_idt &function_name, - const exprt::operandst &arg, - const source_locationt &loc, - const std::string &sig) -{ - if(is_java_string_pointer_type(function_type.return_type())) - make_string_assign( - goto_program, target, lhs, function_type, function_name, arg, loc, sig); - else - make_normal_assign( - goto_program, target, lhs, function_type, function_name, arg, loc, sig); -} - -/*******************************************************************\ - -Function: string_refine_preprocesst::make_string_copy - - Inputs: a goto_program, a position in this program, a lhs expression, - an argument expression and a location - - Outputs: an expression - - Purpose: replace the current instruction by: - > lhs->length=argument->length - > tmp_data=*(argument->data) - > lhs->data=&tmp_data - -\*******************************************************************/ - -void string_refine_preprocesst::make_string_copy( - goto_programt &goto_program, - goto_programt::targett &target, - const exprt &lhs, - const exprt &argument, - const source_locationt &location) -{ - // TODO : treat CharSequence and StringBuffer - assert(is_java_string_pointer_type(lhs.type()) || - is_java_string_builder_pointer_type(lhs.type())); - exprt deref=dereference_exprt(lhs, lhs.type().subtype()); - - typet length_type, data_type; - get_data_and_length_type_of_string(deref, data_type, length_type); - - dereference_exprt deref_arg(argument, argument.type().subtype()); - std::list assignments; - - exprt lhs_length=get_length(deref, length_type); - exprt rhs_length=get_length(deref_arg, length_type); - assignments.emplace_back(lhs_length, rhs_length); - - symbol_exprt tmp_data=fresh_array(data_type.subtype(), location); - exprt rhs_data=get_data(deref_arg, data_type); - exprt lhs_data=get_data(deref, data_type); - assignments.emplace_back( - tmp_data, dereference_exprt(rhs_data, data_type.subtype())); - assignments.emplace_back(lhs_data, address_of_exprt(tmp_data)); - - insert_assignments( - goto_program, target, target->function, location, assignments); -} - -/*******************************************************************\ - Function: string_refine_preprocesst::make_string_function Inputs: a position in a goto program, a function name, an expression lhs, @@ -566,7 +635,36 @@ void string_refine_preprocesst::make_string_function( const source_locationt &location, const std::string &signature) { - if(is_java_string_pointer_type(function_type.return_type())) + if(signature.length()>0) + { + if(signature.back()=='S') + { + code_typet ft=function_type; + ft.return_type()=jls_ptr; + typecast_exprt lhs2(lhs, jls_ptr); + + make_string_assign( + goto_program, + target, + lhs2, + ft, + function_name, + arguments, + location, + signature); + } + else + make_normal_assign( + goto_program, + target, + lhs, + function_type, + function_name, + arguments, + location, + signature); + } + else if(implements_java_char_sequence(function_type.return_type())) make_string_assign( goto_program, target, @@ -597,9 +695,11 @@ Function: string_refine_preprocesst::make_string_function Purpose: at the current position replace `lhs=s.some_function(x,...)` by `lhs=function_name(s,x,...)`; option `assign_first_arg` uses `s` instead of `lhs` in the resulting - expression; + expression, Warning : it assumes that `s` is string-like option `skip_first_arg`, removes `s` from the arguments, ie `x` is - the first one + the first one; + arguments that are string (TODO: and char array) are replaced + by string_exprt \*******************************************************************/ @@ -635,11 +735,17 @@ void string_refine_preprocesst::make_string_function( new_type.parameters().push_back(function_type.parameters()[i]); } + std::string new_sig=signature; exprt lhs; if(assign_first_arg) { assert(!function_call.arguments().empty()); lhs=function_call.arguments()[0]; + std::size_t size=function_call.arguments().size(); + if(signature.length()<=size) + new_sig.resize(size+1, '_'); + + new_sig.replace(size, 1, "S"); } else lhs=function_call.lhs(); @@ -650,7 +756,7 @@ void string_refine_preprocesst::make_string_function( new_type.return_type()=lhs.type(); make_string_function( - goto_program, target, lhs, new_type, function_name, args, loc, signature); + goto_program, target, lhs, new_type, function_name, args, loc, new_sig); } /*******************************************************************\ @@ -680,9 +786,11 @@ Function: string_refine_preprocesst::make_string_function_side_effect Inputs: a position in a goto program and a function name - Purpose: at the current position, replace `r=s.some_function(x,...)` - by `s=function_name(s,x,...)` and add a correspondance from r - to s in the `string_builders` map + Purpose: at the current position, replace `r=s.some_function(x,...)` by + > tmp=function_name(x,...) + > s->data=tmp.data + > s->length=tmp.length + > r=s \*******************************************************************/ @@ -692,11 +800,48 @@ void string_refine_preprocesst::make_string_function_side_effect( const irep_idt &function_name, const std::string &signature) { - const code_function_callt function_call=to_code_function_call(target->code); - assert(!function_call.arguments().empty()); - string_builders[function_call.lhs()]=function_call.arguments()[0]; - make_string_function( - goto_program, target, function_name, signature, true, false); + code_function_callt function_call=to_code_function_call(target->code); + source_locationt loc=function_call.source_location(); + std::list assignments; + exprt lhs=function_call.lhs(); + exprt s=function_call.arguments()[0]; + code_typet function_type=to_code_type(function_call.type()); + + function_type.return_type()=s.type(); + + if(lhs.is_not_nil()) + { + symbol_exprt tmp_string=fresh_string(lhs.type(), loc); + + make_string_assign( + goto_program, + target, + tmp_string, + function_type, + function_name, + function_call.arguments(), + loc, + signature); + dereference_exprt deref_lhs(s, s.type().subtype()); + typet data_type, length_type; + get_data_and_length_type_of_string(deref_lhs, data_type, length_type); + member_exprt lhs_data(deref_lhs, "data", data_type); + member_exprt lhs_length(deref_lhs, "length", length_type); + dereference_exprt deref_rhs(tmp_string, s.type().subtype()); + member_exprt rhs_data(deref_rhs, "data", data_type); + member_exprt rhs_length(deref_rhs, "length", length_type); + assignments.emplace_back(lhs_length, rhs_length); + assignments.emplace_back(lhs_data, rhs_data); + assignments.emplace_back(lhs, s); + target=goto_program.insert_after(target); + insert_assignments( + goto_program, target, target->function, loc, assignments); + } + else + { + make_string_function( + goto_program, target, function_name, signature, true, false); + } } /*******************************************************************\ @@ -735,6 +880,7 @@ Function: string_refine_preprocesst::make_to_char_array_function Inputs: a goto program and a position in that goto program Purpose: at the given position replace `return_tmp0=s.toCharArray()` with: + > return_tmp0 = malloc(array[char]); > return_tmp0->data=&((s->data)[0]) > return_tmp0->length=s->length @@ -744,16 +890,36 @@ void string_refine_preprocesst::make_to_char_array_function( goto_programt &goto_program, goto_programt::targett &target) { const code_function_callt &function_call=to_code_function_call(target->code); + source_locationt location=function_call.source_location(); - assert(!function_call.arguments().empty()); + assert(function_call.arguments().size()>=1); const exprt &string_argument=function_call.arguments()[0]; assert(is_java_string_pointer_type(string_argument.type())); + typet deref_type=function_call.lhs().type().subtype(); + const exprt &lhs=function_call.lhs(); + dereference_exprt deref_lhs(lhs, deref_type); + dereference_exprt deref(string_argument, string_argument.type().subtype()); typet length_type, data_type; get_data_and_length_type_of_string(deref, data_type, length_type); std::list assignments; + // lhs=malloc(array[char]) + typet object_type=ns.follow(deref_type); + exprt object_size=size_of_expr(object_type, ns); + + if(object_size.is_nil()) + debug() << "string_refine_preprocesst::make_to_char_array_function " + << "got nil object_size" << eom; + + side_effect_exprt malloc_expr(ID_malloc); + malloc_expr.copy_to_operands(object_size); + malloc_expr.type()=pointer_typet(object_type); + malloc_expr.add_source_location()=location; + assignments.emplace_back(lhs, malloc_expr); + + // &((s->data)[0]) exprt rhs_data=get_data(deref, data_type); dereference_exprt rhs_array(rhs_data, data_type.subtype()); @@ -762,8 +928,6 @@ void string_refine_preprocesst::make_to_char_array_function( address_of_exprt rhs_pointer(first_element); // return_tmp0->data=&((s->data)[0]) - typet deref_type=function_call.lhs().type().subtype(); - dereference_exprt deref_lhs(function_call.lhs(), deref_type); exprt lhs_data=get_data(deref_lhs, data_type); assignments.emplace_back(lhs_data, rhs_pointer); @@ -771,178 +935,8 @@ void string_refine_preprocesst::make_to_char_array_function( exprt rhs_length=get_length(deref, length_type); exprt lhs_length=get_length(deref_lhs, length_type); assignments.emplace_back(lhs_length, rhs_length); - source_locationt location=target->source_location; - insert_assignments( - goto_program, target, target->function, location, assignments); -} - -/*******************************************************************\ - -Function: string_refine_preprocesst::make_cprover_char_array_assign - - Inputs: a goto_program, a position in this program, an expression and a - location - - Outputs: a char array expression (not a pointer) - - Purpose: Introduce a temporary variable for cprover strings; - returns the cprover_string corresponding to rhs - -\*******************************************************************/ - -exprt string_refine_preprocesst::make_cprover_char_array_assign( - goto_programt &goto_program, - goto_programt::targett &target, - const exprt &rhs, - const source_locationt &location) -{ - // TODO : add an assertion on the type of rhs - - // We do the following assignments: - // cprover_string_array = rhs.data - // cprover_string = { rhs.length; cprover_string_array } - - // string expression for the rhs of the second assignment - string_exprt new_rhs(java_char_type()); - - typet data_type=new_rhs.content().type(); - typet length_type=java_int_type(); - - symbol_exprt array_lhs=fresh_array(data_type, location); - exprt array_rhs=get_data(rhs, new_rhs.content().type()); - symbol_exprt lhs=fresh_string(new_rhs.type(), location); - new_rhs.length()=get_length(rhs, length_type); - new_rhs.content()=array_lhs; - - std::list assignments; - assignments.emplace_back(array_lhs, array_rhs); - assignments.emplace_back(lhs, new_rhs); insert_assignments( goto_program, target, target->function, location, assignments); - target=goto_program.insert_after(target); - return lhs; -} - -/*******************************************************************\ - -Function: string_refine_preprocesst::make_char_array_function - - Inputs: a position in a goto program, a function name, two Boolean options, - and the index of the char array argument in the function - - Purpose: at the given position replace - `lhs=s.some_function(...,char_array,...)` by - > cprover_string = { char_array->length, *char_array } - > tmp_string=function_name(s, cprover_string, ...) - option `assign_first_arg` uses `s` instead of `lhs` in the second - assignment; - option `skip_first_arg`, removes `s` from the arguments, ie `x` is - the first one; - argument index gives the index of the argument containing char_array - -\*******************************************************************/ - -void string_refine_preprocesst::make_char_array_function( - goto_programt &goto_program, - goto_programt::targett &target, - const irep_idt &function_name, - const std::string &signature, - std::size_t index, - bool assign_first_arg, - bool skip_first_arg) -{ - code_function_callt &function_call=to_code_function_call(target->code); - code_typet function_type=to_code_type(function_call.function().type()); - code_typet new_function_type; - const source_locationt &location=function_call.source_location(); - assert(!function_call.arguments().size()>index); - const std::vector &args=function_call.arguments(); - std::vector new_args; - - exprt lhs; - if(assign_first_arg) - { - assert(!function_call.arguments().empty()); - lhs=function_call.arguments()[0]; - else - lhs=function_call.lhs(); - - if(lhs.id()==ID_typecast) - lhs=to_typecast_expr(lhs).op(); - - exprt char_array=dereference_exprt( - function_call.arguments()[index], - function_call.arguments()[index].type().subtype()); - exprt string=make_cprover_char_array_assign( - goto_program, target, char_array, location); - - std::size_t start_index=skip_first_arg?1:0; - for(std::size_t i=start_index; icode); - assert(!function_call.arguments().empty()); - string_builders[function_call.lhs()]=function_call.arguments()[0]; } /*******************************************************************\ @@ -974,22 +968,20 @@ exprt::operandst string_refine_preprocesst::process_arguments( for(std::size_t i=0; isecond); - else + if(iis_function_call()) { code_function_callt &function_call=to_code_function_call(target->code); - for(auto &arg : function_call.arguments()) - { - auto sb_it=string_builders.find(arg); - if(sb_it!=string_builders.end()) - arg=sb_it->second; - } if(function_call.function().id()==ID_symbol) { @@ -1070,21 +1056,6 @@ void string_refine_preprocesst::replace_string_calls( make_string_function_call( goto_program, target, it->second, signature); - it=string_of_char_array_functions.find(function_id); - if(it!=string_of_char_array_functions.end()) - make_char_array_function( - goto_program, target, it->second, signature, 0); - - it=string_of_char_array_function_calls.find(function_id); - if(it!=string_of_char_array_function_calls.end()) - make_char_array_function_call( - goto_program, target, it->second, signature); - - it=side_effect_char_array_functions.find(function_id); - if(it!=side_effect_char_array_functions.end()) - make_char_array_side_effect( - goto_program, target, it->second, signature); - if(function_id==irep_idt("java::java.lang.String.toCharArray:()[C")) make_to_char_array_function(goto_program, target); } @@ -1299,12 +1270,18 @@ void string_refine_preprocesst::initialize_string_function_table() ID_cprover_string_set_length_func; - side_effect_char_array_functions + + side_effect_functions + ["java::java.lang.StringBuilder.append:([C)" + "Ljava/lang/StringBuilder;"]= + ID_cprover_string_concat_func; + side_effect_functions ["java::java.lang.StringBuilder.insert:(I[CII)Ljava/lang/StringBuilder;"]= - ID_cprover_string_insert_char_array_func; - side_effect_char_array_functions + ID_cprover_string_insert_func; + side_effect_functions ["java::java.lang.StringBuilder.insert:(I[C)Ljava/lang/StringBuilder;"]= - ID_cprover_string_insert_char_array_func; + ID_cprover_string_insert_func; + // TODO clean irep ids from insert_char_array etc... string_function_calls ["java::java.lang.String.:(Ljava/lang/String;)V"]= @@ -1320,23 +1297,23 @@ void string_refine_preprocesst::initialize_string_function_table() string_function_calls["java::java.lang.StringBuilder.:()V"]= ID_cprover_string_empty_string_func; - string_of_char_array_function_calls["java::java.lang.String.:([C)V"]= - ID_cprover_string_of_char_array_func; - string_of_char_array_function_calls["java::java.lang.String.:([CII)V"]= - ID_cprover_string_of_char_array_func; + string_function_calls["java::java.lang.String.:([C)V"]= + ID_cprover_string_copy_func; + string_function_calls["java::java.lang.String.:([CII)V"]= + ID_cprover_string_copy_func; - string_of_char_array_functions + string_functions ["java::java.lang.String.valueOf:([CII)Ljava/lang/String;"]= - ID_cprover_string_of_char_array_func; - string_of_char_array_functions + ID_cprover_string_copy_func; + string_functions ["java::java.lang.String.valueOf:([C)Ljava/lang/String;"]= - ID_cprover_string_of_char_array_func; - string_of_char_array_functions + ID_cprover_string_copy_func; + string_functions ["java::java.lang.String.copyValueOf:([CII)Ljava/lang/String;"]= - ID_cprover_string_of_char_array_func; - string_of_char_array_functions + ID_cprover_string_copy_func; + string_functions ["java::java.lang.String.copyValueOf:([C)Ljava/lang/String;"]= - ID_cprover_string_of_char_array_func; + ID_cprover_string_copy_func; c_string_functions["__CPROVER_uninterpreted_string_literal_func"]= ID_cprover_string_literal_func; @@ -1370,9 +1347,23 @@ void string_refine_preprocesst::initialize_string_function_table() ID_cprover_string_of_int_func; signatures["java::java.lang.String.equals:(Ljava/lang/Object;)Z"]="SSZ"; - signatures - ["java::java.lang.String.contains:(Ljava/lang/CharSequence;)Z"]= - "SSZ"; + signatures["java::java.lang.String.contains:(Ljava/lang/CharSequence;)Z"]= + "SSZ"; + signatures["java::java.lang.StringBuilder.insert:(IZ)" + "Ljava/lang/StringBuilder;"]="SIZS"; + signatures["java::java.lang.StringBuilder.insert:(IJ)" + "Ljava/lang/StringBuilder;"]="SIJS"; + signatures["java::java.lang.StringBuilder.insert:(II)" + "Ljava/lang/StringBuilder;"]="SIIS"; + signatures["java::java.lang.StringBuilder.insert:(IC)" + "Ljava/lang/StringBuilder;"]="SICS"; + signatures["java::java.lang.StringBuilder.insert:(ILjava/lang/String;)" + "Ljava/lang/StringBuilder;"]="SISS"; + signatures["java::java.lang.StringBuilder.insert:(ILjava/lang/String;)" + "Ljava/lang/StringBuilder;"]="SISS"; + signatures["java::java.lang.StringBuilder.insert:(I[C)" + "Ljava/lang/StringBuilder;"]="SI[S"; + signatures["java::java.lang.String.intern:()Ljava/lang/String;"]="SV"; } /*******************************************************************\ diff --git a/src/goto-programs/string_refine_preprocess.h b/src/goto-programs/string_refine_preprocess.h index 613d0161926..5ae398b757a 100644 --- a/src/goto-programs/string_refine_preprocess.h +++ b/src/goto-programs/string_refine_preprocess.h @@ -14,6 +14,7 @@ Date: September 2016 #include #include +#include class string_refine_preprocesst:public messaget { @@ -29,28 +30,21 @@ class string_refine_preprocesst:public messaget typedef std::unordered_map id_mapt; typedef std::unordered_map expr_mapt; - // String builders maps the different names of a same StringBuilder object - // to a unique expression. - expr_mapt string_builders; - // Map name of Java string functions to there equivalent in the solver id_mapt side_effect_functions; id_mapt string_functions; id_mapt c_string_functions; id_mapt string_function_calls; - id_mapt string_of_char_array_functions; - id_mapt string_of_char_array_function_calls; - id_mapt side_effect_char_array_functions; std::unordered_map signatures; - expr_mapt hidden_strings; - expr_mapt java_to_cprover_strings; // unique id for each newly created symbols int next_symbol_id; void initialize_string_function_table(); + static bool check_java_type(const typet &type, const std::string &tag); + static bool is_java_string_pointer_type(const typet &type); static bool is_java_string_type(const typet &type); @@ -61,6 +55,20 @@ class string_refine_preprocesst:public messaget static bool is_java_char_sequence_type(const typet &type); + static bool is_java_char_sequence_pointer_type(const typet &type); + + static bool is_java_char_array_type(const typet &type); + + static bool is_java_char_array_pointer_type(const typet &type); + + static bool implements_java_char_sequence(const typet &type) + { + return + is_java_char_sequence_pointer_type(type) || + is_java_string_builder_pointer_type(type) || + is_java_string_pointer_type(type); + } + symbol_exprt fresh_array( const typet &type, const source_locationt &location); symbol_exprt fresh_string( @@ -110,6 +118,9 @@ class string_refine_preprocesst:public messaget void get_data_and_length_type_of_string( const exprt &expr, typet &data_type, typet &length_type); + void get_data_and_length_type_of_char_array( + const exprt &expr, typet &data_type, typet &length_type); + function_application_exprt build_function_application( const irep_idt &function_name, const typet &type, @@ -136,27 +147,16 @@ class string_refine_preprocesst:public messaget const source_locationt &location, const std::string &signature); - void make_assign( - goto_programt &goto_program, - goto_programt::targett &target, - const exprt &lhs, - const code_typet &function_type, - const irep_idt &function_name, - const exprt::operandst &arg, - const source_locationt &loc, - const std::string &sig); - exprt make_cprover_string_assign( goto_programt &goto_program, goto_programt::targett &target, const exprt &rhs, const source_locationt &location); - void make_string_copy( + string_exprt make_cprover_char_array_assign( goto_programt &goto_program, goto_programt::targett &target, - const exprt &lhs, - const exprt &argument, + const exprt &rhs, const source_locationt &location); void make_string_function( @@ -192,33 +192,6 @@ class string_refine_preprocesst:public messaget void make_to_char_array_function( goto_programt &goto_program, goto_programt::targett &); - exprt make_cprover_char_array_assign( - goto_programt &goto_program, - goto_programt::targett &target, - const exprt &rhs, - const source_locationt &location); - - void make_char_array_function( - goto_programt &goto_program, - goto_programt::targett &target, - const irep_idt &function_name, - const std::string &signature, - std::size_t index, - bool assign_first_arg=false, - bool skip_first_arg=false); - - void make_char_array_function_call( - goto_programt &goto_program, - goto_programt::targett &target, - const irep_idt &function_name, - const std::string &signature); - - void make_char_array_side_effect( - goto_programt &goto_program, - goto_programt::targett &target, - const irep_idt &function_name, - const std::string &signature); - void replace_string_calls(goto_functionst::function_mapt::iterator f_it); }; From b75d745dc62d078257e1cdc3c4a5a504a0e270e2 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Tue, 28 Feb 2017 13:50:25 +0000 Subject: [PATCH 09/10] Many corrections in string refinement Overhaul of string solver contributions The code adding lemmas to the solver for each equality has been completely remastered. It has been simplified and should now cover all foreseable cases. Add overflow constraints on sums for string solver When creating sum expressions during string refinement, e.g. when adding string lengths, we shall add axioms to prevent the solver from finding values that actually come from an integer overflow. Therefore, we introduce a new method plus_exprt_with_overflow_check() that wraps around plus_exprt and generates the relevant axioms. Cache function applications Cache converted function applications to avoid re-generating the axioms if it has already been done for a given function application. This seems to happen for function applications that are in an assertion, and thus are treated separately by convert_bitvector. Remove string_refinement::convert_symbol: the behaviour of this function was to convert java strings to strings of symbols. In hindsight, this was not a good idea, as we still refer to the actual java string fields in some cases, e.g. to read its length. Replace add_axioms_for_string_expr In all add_axioms_... methods, we replace all calls to add_axioms_for_string_expr by the newly created function get_string_expr, which simply returns a string_exprt when we give it an refined expr (such as a string_exprt or a symbol). Update doc in add_axioms_for_index_string Simplify constraint for is_prefix: apply distribution law and update (and refactor) documentation. Remove set_string_symbol_equal_to_expr() Removed mentions of java string type in the string solver Removing mentions of is_c_string_type To use the string solver in C, we should use a struct type with tag __CPROVER_refined_string_type Keep non-string axioms in a list Instead of giving axioms to super::boolbv_set_equality_to_true, which may contain un-substituted symbols, we keep them in a list and substitute them in dec_solve() before giving them to the function. Cleaning the add_axioms_for_string_expr method and renamed it to add_axioms_for_refined_string to signify that it should only be called on expression of type refined string. An assertion was added at the beginning to ensure that. Better get_array and string_of_array functions. Cleaned the implementation of get_array and factorized part of it. Made string_of_array directly take a array_exprt, which can be obtained from get_array. Improved string_of_array for non printable characters Resolve symbol to char arrays in non-string axioms. We introduce a mapping that expresses the maximal traversal of symbols of char array type. We use that map to, either obtain a char array from a symbol, either get a unique symbol the aliases equivalence class. This map is used to replace all symbols of char array type in the axioms that are added using the parent method: supert::boolbv_set_equality_to_true. Defining several intermediary functions for check_axioms and cleaning. Check axioms is quite complicated so we splitted it in several parts. Avoid using same universal variable name in string comparison function. Corrected test in index_of as characters could be signed Corrected return type retrieval in from_float functions. The return type should be given as argument of the helper function add_axioms_from_float. Fixed type of contains in constraint generation Introduce string_refinementt::set_to. We now override the set_to() method instead of set_equality_to_true(). This solves a problem where many lemmas were being dropped. Handle array_of in set_char_array_equality. Java assignments such as char[] str=new char[10] involves assigning the char array to 0, which is done using the array_of operator. This operator is now handled when found on the rhs of a char array assignment. Optimized string hash code and intern functions to only look at seen strings. We only compare the argument to the strings on which hash_code (resp. intern) was already called. Add missing override keyword in declarations Integrate strings into symbol resolution. We now use for strings the mechanism that was made for resolving symbols to char arrays. As a result, the symbol_to_string map has been removed. We introduce an unresolved_symbol map to associate symbols to string expressions that were introduced during constraint generation. Preventing return of nil exprt in sum_over_map Enforce -1 for witnesses when strings are unequal. This makes it easier to see when models for string have different length. Correct array index in get_array Correct a bad array access that caused a segmentation fault on the java_delete test. Adding option to concretize result and get method in string solver The option to concretize makes sure that the model that we get in the end is correct. Overiding the get method is necessary to get the actual valuation of string gotten by the solver. This two additions makes the trace generation for program with strings more likely to be actual traces of the program. Avoid adding axioms for copy Corrected `get` to not replace strings Simplifying lemmas before handing them to the solver This seems to improve performances Ignoring char array that are not symbol or constants Avoid creating new length variable for concat Adding constraint on positive length for refined strings Using get method of the parent class for the size Add function to fill the found_length map Signature for get_array should be constant Corrected overflow problem when integer get to the max size Removing overflow check in universal constraint Enforcing witness -1 when length is not sufficient in suffix Corrected index variable which should be universally quantified Factorizing addition to index set and more debug information Avoiding generating a fresh string for the empty string Enabling string solver to treat more cases and more debug infos Conversion from char pointer to array in the solver Raise a warning if found length is negative Ensure the arguments of parseInt are of the right format For now we add axioms asking for the argument to have the right format but ultimately we should raise an exception when it is not the case (which is not done right now). Corrects the specification of int to string conversion Some problems where encountered for strings with the maximal size possible for an int, which could cause an overflow. Disallow + sign in string from int Java will not add the sign for positive numbers Use get instead of current_model in check_axioms Streamline code of check_axioms() by calling get() insteand of relying on the 'current_model' variable. get() has been adapted to convert array-lists into with expressions, the former not being handled by the string solver. --- src/solvers/refinement/string_constraint.h | 1 - .../refinement/string_constraint_generator.h | 45 +- ...tring_constraint_generator_code_points.cpp | 18 +- ...string_constraint_generator_comparison.cpp | 102 +- .../string_constraint_generator_concat.cpp | 31 +- .../string_constraint_generator_constants.cpp | 9 +- .../string_constraint_generator_indexof.cpp | 27 +- .../string_constraint_generator_insert.cpp | 24 +- .../string_constraint_generator_main.cpp | 422 +++++--- .../string_constraint_generator_testing.cpp | 46 +- ...ng_constraint_generator_transformation.cpp | 39 +- .../string_constraint_generator_valueof.cpp | 101 +- src/solvers/refinement/string_refinement.cpp | 917 ++++++++++++++---- src/solvers/refinement/string_refinement.h | 66 +- 14 files changed, 1323 insertions(+), 525 deletions(-) diff --git a/src/solvers/refinement/string_constraint.h b/src/solvers/refinement/string_constraint.h index 4b8d1229e09..1bb460349b7 100644 --- a/src/solvers/refinement/string_constraint.h +++ b/src/solvers/refinement/string_constraint.h @@ -48,7 +48,6 @@ class string_constraintt: public exprt return operands()[4]; } - private: string_constraintt(); diff --git a/src/solvers/refinement/string_constraint_generator.h b/src/solvers/refinement/string_constraint_generator.h index ed898cb9a18..12447e0cf04 100644 --- a/src/solvers/refinement/string_constraint_generator.h +++ b/src/solvers/refinement/string_constraint_generator.h @@ -14,6 +14,7 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com #define CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H #include +#include #include #include @@ -65,21 +66,20 @@ class string_constraint_generatort symbol_exprt fresh_univ_index(const irep_idt &prefix, const typet &type); symbol_exprt fresh_boolean(const irep_idt &prefix); string_exprt fresh_string(const refined_string_typet &type); + string_exprt get_string_expr(const exprt &expr); + string_exprt convert_java_string_to_string_exprt( + const exprt &underlying); + plus_exprt plus_exprt_with_overflow_check(const exprt &op1, const exprt &op2); - // We maintain a map from symbols to strings. - std::map symbol_to_string; + // Maps unresolved symbols to the string_exprt that was created for them + std::map unresolved_symbols; - string_exprt find_or_add_string_of_symbol(const symbol_exprt &sym); - void assign_to_symbol( - const symbol_exprt &sym, const string_exprt &expr) - { - symbol_to_string[sym.get_identifier()]=expr; - } + string_exprt find_or_add_string_of_symbol( + const symbol_exprt &sym, + const refined_string_typet &ref_type); - string_exprt add_axioms_for_string_expr(const exprt &expr); - void set_string_symbol_equal_to_expr( - const symbol_exprt &sym, const exprt &str); + string_exprt add_axioms_for_refined_string(const exprt &expr); exprt add_axioms_for_function_application( const function_application_exprt &expr); @@ -96,6 +96,8 @@ class string_constraint_generatort const std::size_t MAX_FLOAT_LENGTH=15; const std::size_t MAX_DOUBLE_LENGTH=30; + std::map function_application_cache; + static irep_idt extract_java_string(const symbol_exprt &s); exprt axiom_for_is_positive_index(const exprt &x); @@ -117,6 +119,9 @@ class string_constraint_generatort // The specification is partial: the actual value is not actually computed // but we ensure that hash codes of equal strings are equal. exprt add_axioms_for_hash_code(const function_application_exprt &f); + // To each string on which hash_code was called we associate a symbol + // representing the return value of the hash_code function. + std::map hash_code_of_string; exprt add_axioms_for_is_empty(const function_application_exprt &f); exprt add_axioms_for_is_prefix( @@ -224,7 +229,9 @@ class string_constraint_generatort // the start for negative number string_exprt add_axioms_from_float(const function_application_exprt &f); string_exprt add_axioms_from_float( - const exprt &f, bool double_precision=false); + const exprt &f, + const refined_string_typet &ref_type, + bool double_precision); // Add axioms corresponding to the String.valueOf(D) java function // TODO: the specifications is only partial @@ -253,6 +260,7 @@ class string_constraint_generatort string_exprt add_axioms_for_code_point( const exprt &code_point, const refined_string_typet &ref_type); string_exprt add_axioms_for_java_char_array(const exprt &char_array); + exprt add_axioms_for_char_pointer(const function_application_exprt &fun); string_exprt add_axioms_for_if(const if_exprt &expr); exprt add_axioms_for_char_literal(const function_application_exprt &f); @@ -270,6 +278,8 @@ class string_constraint_generatort const function_application_exprt &f); exprt add_axioms_for_parse_int(const function_application_exprt &f); + exprt add_axioms_for_correct_number_format( + const string_exprt &str, std::size_t max_size=10); exprt add_axioms_for_to_char_array(const function_application_exprt &f); exprt add_axioms_for_compare_to(const function_application_exprt &f); @@ -278,6 +288,9 @@ class string_constraint_generatort // string pointers symbol_exprt add_axioms_for_intern(const function_application_exprt &f); + // Pool used for the intern method + std::map intern_of_string; + // Tells which language is used. C and Java are supported irep_idt mode; @@ -293,14 +306,8 @@ class string_constraint_generatort exprt int_of_hex_char(const exprt &chr) const; exprt is_high_surrogate(const exprt &chr) const; exprt is_low_surrogate(const exprt &chr) const; - static exprt character_equals_ignore_case( + exprt character_equals_ignore_case( exprt char1, exprt char2, exprt char_a, exprt char_A, exprt char_Z); - - // Pool used for the intern method - std::map pool; - - // Used to determine whether hashcode should be equal - std::map hash; }; #endif diff --git a/src/solvers/refinement/string_constraint_generator_code_points.cpp b/src/solvers/refinement/string_constraint_generator_code_points.cpp index 7c035a0d3e4..16763dfc97c 100644 --- a/src/solvers/refinement/string_constraint_generator_code_points.cpp +++ b/src/solvers/refinement/string_constraint_generator_code_points.cpp @@ -160,17 +160,18 @@ exprt string_constraint_generatort::add_axioms_for_code_point_at( { typet return_type=f.type(); assert(return_type.id()==ID_signedbv); - string_exprt str=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt str=get_string_expr(args(f, 2)[0]); const exprt &pos=args(f, 2)[1]; symbol_exprt result=fresh_symbol("char", return_type); exprt index1=from_integer(1, str.length().type()); const exprt &char1=str[pos]; - const exprt &char2=str[plus_exprt(pos, index1)]; + const exprt &char2=str[plus_exprt_with_overflow_check(pos, index1)]; exprt char1_as_int=typecast_exprt(char1, return_type); exprt char2_as_int=typecast_exprt(char2, return_type); exprt pair=pair_value(char1_as_int, char2_as_int, return_type); - exprt is_low=is_low_surrogate(str[plus_exprt(pos, index1)]); + exprt is_low=is_low_surrogate( + str[plus_exprt_with_overflow_check(pos, index1)]); exprt return_pair=and_exprt(is_high_surrogate(str[pos]), is_low); axioms.push_back(implies_exprt(return_pair, equal_exprt(result, pair))); @@ -199,7 +200,7 @@ exprt string_constraint_generatort::add_axioms_for_code_point_before( typet return_type=f.type(); assert(return_type.id()==ID_signedbv); symbol_exprt result=fresh_symbol("char", return_type); - string_exprt str=add_axioms_for_string_expr(args[0]); + string_exprt str=get_string_expr(args[0]); const exprt &char1= str[minus_exprt(args[1], from_integer(2, str.length().type()))]; @@ -234,7 +235,7 @@ Function: string_constraint_generatort::add_axioms_for_code_point_count exprt string_constraint_generatort::add_axioms_for_code_point_count( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt str=get_string_expr(args(f, 3)[0]); const exprt &begin=args(f, 3)[1]; const exprt &end=args(f, 3)[2]; const typet &return_type=f.type(); @@ -265,14 +266,15 @@ Function: string_constraint_generatort::add_axioms_for_offset_by_code_point exprt string_constraint_generatort::add_axioms_for_offset_by_code_point( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt str=get_string_expr(args(f, 3)[0]); const exprt &index=args(f, 3)[1]; const exprt &offset=args(f, 3)[2]; const typet &return_type=f.type(); symbol_exprt result=fresh_symbol("offset_by_code_point", return_type); - exprt minimum=plus_exprt(index, offset); - exprt maximum=plus_exprt(index, plus_exprt(offset, offset)); + exprt minimum=plus_exprt_with_overflow_check(index, offset); + exprt maximum=plus_exprt_with_overflow_check( + index, plus_exprt_with_overflow_check(offset, offset)); axioms.push_back(binary_relation_exprt(result, ID_le, maximum)); axioms.push_back(binary_relation_exprt(result, ID_ge, minimum)); diff --git a/src/solvers/refinement/string_constraint_generator_comparison.cpp b/src/solvers/refinement/string_constraint_generator_comparison.cpp index 321282ee9c1..a51e2abe3cd 100644 --- a/src/solvers/refinement/string_constraint_generator_comparison.cpp +++ b/src/solvers/refinement/string_constraint_generator_comparison.cpp @@ -18,7 +18,9 @@ Function: string_constraint_generatort::add_axioms_for_equals Outputs: a expression of Boolean type Purpose: add axioms stating that the result is true exactly when the strings - represented by the arguments are equal + represented by the arguments are equal. + the variable ending in `witness_unequal` is -1 if the length differs + or an index at which the strings are different \*******************************************************************/ @@ -29,8 +31,8 @@ exprt string_constraint_generatort::add_axioms_for_equals( symbol_exprt eq=fresh_boolean("equal"); typecast_exprt tc_eq(eq, f.type()); - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); - string_exprt s2=add_axioms_for_string_expr(args(f, 2)[1]); + string_exprt s1=get_string_expr(args(f, 2)[0]); + string_exprt s2=get_string_expr(args(f, 2)[1]); typet index_type=s1.length().type(); // We want to write: @@ -54,9 +56,10 @@ exprt string_constraint_generatort::add_axioms_for_equals( binary_relation_exprt(witness, ID_lt, s1.length()), binary_relation_exprt(witness, ID_ge, zero)); and_exprt witnessing(bound_witness, notequal_exprt(s1[witness], s2[witness])); - implies_exprt a3( - not_exprt(eq), - or_exprt(notequal_exprt(s1.length(), s2.length()), witnessing)); + and_exprt diff_length( + notequal_exprt(s1.length(), s2.length()), + equal_exprt(witness, from_integer(-1, index_type))); + implies_exprt a3(not_exprt(eq), or_exprt(diff_length, witnessing)); axioms.push_back(a3); return tc_eq; @@ -92,8 +95,13 @@ exprt string_constraint_generatort::character_equals_ignore_case( // p3 : (is_up2&&'a'-'A'+char2=char1) equal_exprt p1(char1, char2); minus_exprt diff=minus_exprt(char_a, char_A); - and_exprt p2(is_upper_case_1, equal_exprt(plus_exprt(diff, char1), char2)); - and_exprt p3(is_upper_case_2, equal_exprt(plus_exprt(diff, char2), char1)); + + // Overflow is not a problem here because is_upper_case conditions + // ensure that we are within a safe range. + and_exprt p2(is_upper_case_1, + equal_exprt(plus_exprt(diff, char1), char2)); + and_exprt p3(is_upper_case_2, + equal_exprt(plus_exprt(diff, char2), char1)); return or_exprt(or_exprt(p1, p2), p3); } @@ -116,8 +124,8 @@ exprt string_constraint_generatort::add_axioms_for_equals_ignore_case( symbol_exprt eq=fresh_boolean("equal_ignore_case"); typecast_exprt tc_eq(eq, f.type()); - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); - string_exprt s2=add_axioms_for_string_expr(args(f, 2)[1]); + string_exprt s1=get_string_expr(args(f, 2)[0]); + string_exprt s2=get_string_expr(args(f, 2)[1]); typet char_type=to_refined_string_type(s1.type()).get_char_type(); exprt char_a=constant_char('a', char_type); exprt char_A=constant_char('A', char_type); @@ -174,37 +182,35 @@ Function: string_constraint_generatort::add_axioms_for_hash_code exprt string_constraint_generatort::add_axioms_for_hash_code( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 1)[0]); + string_exprt str=get_string_expr(args(f, 1)[0]); typet return_type=f.type(); typet index_type=str.length().type(); - // initialisation of the missing pool variable - std::map::iterator it; - for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++) - if(hash.find(it->second)==hash.end()) - hash[it->second]=fresh_symbol("hash", return_type); + auto pair=hash_code_of_string.insert( + std::make_pair(str, fresh_symbol("hash", return_type))); + exprt hash=pair.first->second; // for each string s. either: // c1: hash(str)=hash(s) // c2: |str|!=|s| - // c3: (|str|==|s| &&exists i<|s|. s[i]!=str[i]) + // c3: (|str|==|s| && exists i<|s|. s[i]!=str[i]) // WARNING: the specification may be incomplete - for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++) + for(auto it : hash_code_of_string) { symbol_exprt i=fresh_exist_index("index_hash", index_type); - equal_exprt c1(hash[it->second], hash[str]); - not_exprt c2(equal_exprt(it->second.length(), str.length())); + equal_exprt c1(it.second, hash); + not_exprt c2(equal_exprt(it.first.length(), str.length())); and_exprt c3( - equal_exprt(it->second.length(), str.length()), + equal_exprt(it.first.length(), str.length()), and_exprt( - not_exprt(equal_exprt(str[i], it->second[i])), + not_exprt(equal_exprt(str[i], it.first[i])), and_exprt( str.axiom_for_is_strictly_longer_than(i), axiom_for_is_positive_index(i)))); axioms.push_back(or_exprt(c1, or_exprt(c2, c3))); } - return hash[str]; + return hash; } /*******************************************************************\ @@ -222,8 +228,8 @@ Function: string_constraint_generatort::add_axioms_for_compare_to exprt string_constraint_generatort::add_axioms_for_compare_to( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); - string_exprt s2=add_axioms_for_string_expr(args(f, 2)[1]); + string_exprt s1=get_string_expr(args(f, 2)[0]); + string_exprt s2=get_string_expr(args(f, 2)[1]); const typet &return_type=f.type(); symbol_exprt res=fresh_symbol("compare_to", return_type); typet index_type=s1.length().type(); @@ -234,12 +240,12 @@ exprt string_constraint_generatort::add_axioms_for_compare_to( // a1 : res==0 => |s1|=|s2| // a2 : forall i<|s1|. s1[i]==s2[i] // a3 : exists x. - // res!=0 ==> x> 0 && - // ((|s1| <= |s2| &&x<|s1|) || (|s1| >= |s2| &&x<|s2|) - // &&res=s1[x]-s2[x] ) - // || cond2: - // (|s1|<|s2| &&x=|s1|) || (|s1| > |s2| &&x=|s2|) &&res=|s1|-|s2|) - // a4 : forall i s1[i]=s2[i] + // res!=0 ==> x > 0 + // && ((|s1| <= |s2| && x<|s1|) || (|s1| >= |s2| &&x<|s2|) + // && res=s1[x]-s2[x] ) + // || cond2: + // (|s1|<|s2| &&x=|s1|) || (|s1| > |s2| &&x=|s2|) &&res=|s1|-|s2|) + // a4 : forall i' s1[i]=s2[i] assert(return_type.id()==ID_signedbv); @@ -282,7 +288,9 @@ exprt string_constraint_generatort::add_axioms_for_compare_to( or_exprt(cond1, cond2))); axioms.push_back(a3); - string_constraintt a4(i, x, not_exprt(res_null), equal_exprt(s1[i], s2[i])); + symbol_exprt i2=fresh_univ_index("QA_compare_to", index_type); + string_constraintt a4( + i2, x, not_exprt(res_null), equal_exprt(s1[i2], s2[i2])); axioms.push_back(a4); return res; @@ -304,15 +312,15 @@ Function: string_constraint_generatort::add_axioms_for_intern symbol_exprt string_constraint_generatort::add_axioms_for_intern( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 1)[0]); + string_exprt str=get_string_expr(args(f, 1)[0]); + // For now we only enforce content equality and not pointer equality const typet &return_type=f.type(); + typet index_type=str.length().type(); - // initialisation of the missing pool variable - std::map::iterator it; - for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++) - if(pool.find(it->second)==pool.end()) - pool[it->second]=fresh_symbol("pool", return_type); + auto pair=intern_of_string.insert( + std::make_pair(str, fresh_symbol("pool", return_type))); + symbol_exprt intern=pair.first->second; // intern(str)=s_0 || s_1 || ... // for each string s. @@ -320,30 +328,30 @@ symbol_exprt string_constraint_generatort::add_axioms_for_intern( // || (|str|==|s| &&exists i<|s|. s[i]!=str[i]) exprt disj=false_exprt(); - for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++) + for(auto it : intern_of_string) disj=or_exprt( - disj, equal_exprt(pool[str], symbol_exprt(it->first, return_type))); + disj, equal_exprt(intern, it.second)); axioms.push_back(disj); // WARNING: the specification may be incomplete or incorrect - for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++) - if(it->second!=str) + for(auto it : intern_of_string) + if(it.second!=str) { symbol_exprt i=fresh_exist_index("index_intern", index_type); axioms.push_back( or_exprt( - equal_exprt(pool[it->second], pool[str]), + equal_exprt(it.second, intern), or_exprt( - not_exprt(str.axiom_for_has_same_length_as(it->second)), + not_exprt(str.axiom_for_has_same_length_as(it.first)), and_exprt( - str.axiom_for_has_same_length_as(it->second), + str.axiom_for_has_same_length_as(it.first), and_exprt( - not_exprt(equal_exprt(str[i], it->second[i])), + not_exprt(equal_exprt(str[i], it.first[i])), and_exprt(str.axiom_for_is_strictly_longer_than(i), axiom_for_is_positive_index(i))))))); } - return pool[str]; + return intern; } diff --git a/src/solvers/refinement/string_constraint_generator_concat.cpp b/src/solvers/refinement/string_constraint_generator_concat.cpp index a7d9c4921c4..fb8e24d5320 100644 --- a/src/solvers/refinement/string_constraint_generator_concat.cpp +++ b/src/solvers/refinement/string_constraint_generator_concat.cpp @@ -35,9 +35,7 @@ string_exprt string_constraint_generatort::add_axioms_for_concat( // a4 : forall i<|s1|. res[i]=s1[i] // a5 : forall i<|s2|. res[i+|s1|]=s2[i] - exprt a1=res.axiom_for_has_length( - plus_exprt(s1.length(), s2.length())); - axioms.push_back(a1); + res.length()=plus_exprt_with_overflow_check(s1.length(), s2.length()); axioms.push_back(s1.axiom_for_is_shorter_than(res)); axioms.push_back(s2.axiom_for_is_shorter_than(res)); @@ -73,8 +71,8 @@ string_exprt string_constraint_generatort::add_axioms_for_concat( const function_application_exprt::argumentst &args=f.arguments(); assert(args.size()==2); - string_exprt s1=add_axioms_for_string_expr(args[0]); - string_exprt s2=add_axioms_for_string_expr(args[1]); + string_exprt s1=get_string_expr(args[0]); + string_exprt s2=get_string_expr(args[1]); return add_axioms_for_concat(s1, s2); } @@ -95,7 +93,7 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_int( const function_application_exprt &f) { const refined_string_typet &ref_type=to_refined_string_type(f.type()); - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt s1=get_string_expr(args(f, 2)[0]); string_exprt s2=add_axioms_from_int( args(f, 2)[1], MAX_INTEGER_LENGTH, ref_type); return add_axioms_for_concat(s1, s2); @@ -118,7 +116,7 @@ string_exprt string_constraint_generatort::add_axioms_for_concat_long( const function_application_exprt &f) { const refined_string_typet &ref_type=to_refined_string_type(f.type()); - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt s1=get_string_expr(args(f, 2)[0]); string_exprt s2=add_axioms_from_int(args(f, 2)[1], MAX_LONG_LENGTH, ref_type); return add_axioms_for_concat(s1, s2); } @@ -138,7 +136,7 @@ Function: string_constraint_generatort::add_axioms_for_concat_bool string_exprt string_constraint_generatort::add_axioms_for_concat_bool( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt s1=get_string_expr(args(f, 2)[0]); const refined_string_typet &ref_type=to_refined_string_type(s1.type()); string_exprt s2=add_axioms_from_bool(args(f, 2)[1], ref_type); return add_axioms_for_concat(s1, s2); @@ -159,7 +157,7 @@ Function: string_constraint_generatort::add_axioms_for_concat_char string_exprt string_constraint_generatort::add_axioms_for_concat_char( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt s1=get_string_expr(args(f, 2)[0]); const refined_string_typet &ref_type=to_refined_string_type(s1.type()); string_exprt s2=add_axioms_from_char(args(f, 2)[1], ref_type); return add_axioms_for_concat(s1, s2); @@ -180,9 +178,10 @@ Function: string_constraint_generatort::add_axioms_for_concat_double string_exprt string_constraint_generatort::add_axioms_for_concat_double( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); - string_exprt s2=add_axioms_from_float( - args(f, 2)[1], MAX_DOUBLE_LENGTH); + string_exprt s1=get_string_expr(args(f, 2)[0]); + assert(refined_string_typet::is_refined_string_type(f.type())); + refined_string_typet ref_type=to_refined_string_type(f.type()); + string_exprt s2=add_axioms_from_float(args(f, 2)[1], ref_type, true); return add_axioms_for_concat(s1, s2); } @@ -201,8 +200,10 @@ Function: string_constraint_generatort::add_axioms_for_concat_float string_exprt string_constraint_generatort::add_axioms_for_concat_float( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); - string_exprt s2=add_axioms_from_float(args(f, 2)[1], MAX_FLOAT_LENGTH); + string_exprt s1=get_string_expr(args(f, 2)[0]); + assert(refined_string_typet::is_refined_string_type(f.type())); + refined_string_typet ref_type=to_refined_string_type(f.type()); + string_exprt s2=add_axioms_from_float(args(f, 2)[1], ref_type, false); return add_axioms_for_concat(s1, s2); } @@ -222,7 +223,7 @@ Function: string_constraint_generatort::add_axioms_for_concat_code_point string_exprt string_constraint_generatort::add_axioms_for_concat_code_point( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt s1=get_string_expr(args(f, 2)[0]); const refined_string_typet &ref_type=to_refined_string_type(s1.type()); string_exprt s2=add_axioms_for_code_point(args(f, 2)[1], ref_type); return add_axioms_for_concat(s1, s2); diff --git a/src/solvers/refinement/string_constraint_generator_constants.cpp b/src/solvers/refinement/string_constraint_generator_constants.cpp index 64ffabfd266..2905c6a5f21 100644 --- a/src/solvers/refinement/string_constraint_generator_constants.cpp +++ b/src/solvers/refinement/string_constraint_generator_constants.cpp @@ -93,9 +93,13 @@ string_exprt string_constraint_generatort::add_axioms_for_empty_string( const function_application_exprt &f) { assert(f.arguments().empty()); + assert(refined_string_typet::is_refined_string_type(f.type())); const refined_string_typet &ref_type=to_refined_string_type(f.type()); - string_exprt res=fresh_string(ref_type); - axioms.push_back(res.axiom_for_has_length(0)); + exprt size=from_integer(0, ref_type.get_index_type()); + const array_typet &content_type=ref_type.get_content_type(); + array_of_exprt empty_array( + from_integer(0, ref_type.get_content_type().subtype()), content_type); + string_exprt res(size, empty_array, ref_type); return res; } @@ -132,6 +136,7 @@ string_exprt string_constraint_generatort::add_axioms_from_literal( else { // Java string constant + assert(false); // TODO: Check if used. On the contrary, discard else. assert(arg.id()==ID_symbol); const exprt &s=arg.op0(); diff --git a/src/solvers/refinement/string_constraint_generator_indexof.cpp b/src/solvers/refinement/string_constraint_generator_indexof.cpp index 283de683bd6..d799091a573 100644 --- a/src/solvers/refinement/string_constraint_generator_indexof.cpp +++ b/src/solvers/refinement/string_constraint_generator_indexof.cpp @@ -92,15 +92,16 @@ exprt string_constraint_generatort::add_axioms_for_index_of_string( symbol_exprt contains=fresh_boolean("contains_substring"); // We add axioms: - // a1 : contains => |substring|>=offset>=from_index + // a1 : contains => |str|-|substring|>=offset>=from_index // a2 : !contains => offset=-1 - // a3 : forall 0 <= witness str[witness+offset]=substring[witness] + // a3 : forall 0<=witness<|substring|. + // contains => str[witness+offset]=substring[witness] implies_exprt a1( contains, and_exprt( - str.axiom_for_is_longer_than(plus_exprt(substring.length(), offset)), + str.axiom_for_is_longer_than(plus_exprt_with_overflow_check( + substring.length(), offset)), binary_relation_exprt(offset, ID_ge, from_index))); axioms.push_back(a1); @@ -138,7 +139,8 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of_string( implies_exprt a1( contains, and_exprt( - str.axiom_for_is_longer_than(plus_exprt(substring.length(), offset)), + str.axiom_for_is_longer_than( + plus_exprt_with_overflow_check(substring.length(), offset)), binary_relation_exprt(offset, ID_le, from_index))); axioms.push_back(a1); @@ -173,7 +175,7 @@ exprt string_constraint_generatort::add_axioms_for_index_of( const function_application_exprt &f) { const function_application_exprt::argumentst &args=f.arguments(); - string_exprt str=add_axioms_for_string_expr(args[0]); + string_exprt str=get_string_expr(args[0]); const exprt &c=args[1]; const refined_string_typet &ref_type=to_refined_string_type(str.type()); assert(f.type()==ref_type.get_index_type()); @@ -186,14 +188,15 @@ exprt string_constraint_generatort::add_axioms_for_index_of( else assert(false); - if(c.type().id()==ID_unsignedbv) + if(c.type().id()==ID_unsignedbv || c.type().id()==ID_signedbv) { return add_axioms_for_index_of( str, typecast_exprt(c, ref_type.get_char_type()), from_index); } else { - string_exprt sub=add_axioms_for_string_expr(c); + assert(refined_string_typet::is_refined_string_type(c.type())); + string_exprt sub=get_string_expr(c); return add_axioms_for_index_of_string(str, sub, from_index); } } @@ -215,7 +218,7 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of( exprt index1=from_integer(1, index_type); exprt minus1=from_integer(-1, index_type); - exprt from_index_plus_one=plus_exprt(from_index, index1); + exprt from_index_plus_one=plus_exprt_with_overflow_check(from_index, index1); and_exprt a1( binary_relation_exprt(index, ID_ge, minus1), binary_relation_exprt(index, ID_lt, from_index_plus_one)); @@ -269,7 +272,7 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of( const function_application_exprt &f) { const function_application_exprt::argumentst &args=f.arguments(); - string_exprt str=add_axioms_for_string_expr(args[0]); + string_exprt str=get_string_expr(args[0]); exprt c=args[1]; const refined_string_typet &ref_type=to_refined_string_type(str.type()); exprt from_index; @@ -282,14 +285,14 @@ exprt string_constraint_generatort::add_axioms_for_last_index_of( else assert(false); - if(c.type().id()==ID_unsignedbv) + if(c.type().id()==ID_unsignedbv || c.type().id()==ID_signedbv) { return add_axioms_for_last_index_of( str, typecast_exprt(c, ref_type.get_char_type()), from_index); } else { - string_exprt sub=add_axioms_for_string_expr(c); + string_exprt sub=get_string_expr(c); return add_axioms_for_last_index_of_string(str, sub, from_index); } } diff --git a/src/solvers/refinement/string_constraint_generator_insert.cpp b/src/solvers/refinement/string_constraint_generator_insert.cpp index 6a080a5dc6c..cd5f4376a93 100644 --- a/src/solvers/refinement/string_constraint_generator_insert.cpp +++ b/src/solvers/refinement/string_constraint_generator_insert.cpp @@ -48,8 +48,8 @@ Function: string_constraint_generatort::add_axioms_for_insert string_exprt string_constraint_generatort::add_axioms_for_insert( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); - string_exprt s2=add_axioms_for_string_expr(args(f, 3)[2]); + string_exprt s1=get_string_expr(args(f, 3)[0]); + string_exprt s2=get_string_expr(args(f, 3)[2]); return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } @@ -70,7 +70,7 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_int( const function_application_exprt &f) { const refined_string_typet &ref_type=to_refined_string_type(f.type()); - string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt s1=get_string_expr(args(f, 3)[0]); string_exprt s2=add_axioms_from_int( args(f, 3)[2], MAX_INTEGER_LENGTH, ref_type); return add_axioms_for_insert(s1, s2, args(f, 3)[1]); @@ -93,7 +93,7 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_long( const function_application_exprt &f) { const refined_string_typet &ref_type=to_refined_string_type(f.type()); - string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt s1=get_string_expr(args(f, 3)[0]); string_exprt s2=add_axioms_from_int(args(f, 3)[2], MAX_LONG_LENGTH, ref_type); return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } @@ -115,7 +115,7 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_bool( const function_application_exprt &f) { const refined_string_typet &ref_type=to_refined_string_type(f.type()); - string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt s1=get_string_expr(args(f, 3)[0]); string_exprt s2=add_axioms_from_bool(args(f, 3)[2], ref_type); return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } @@ -136,7 +136,7 @@ Function: string_constraint_generatort::add_axioms_for_insert_char string_exprt string_constraint_generatort::add_axioms_for_insert_char( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt s1=get_string_expr(args(f, 3)[0]); const refined_string_typet &ref_type=to_refined_string_type(s1.type()); string_exprt s2=add_axioms_from_char(args(f, 3)[2], ref_type); return add_axioms_for_insert(s1, s2, args(f, 3)[1]); @@ -158,8 +158,9 @@ Function: string_constraint_generatort::add_axioms_for_insert_double string_exprt string_constraint_generatort::add_axioms_for_insert_double( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); - string_exprt s2=add_axioms_from_float(args(f, 3)[2]); + string_exprt s1=get_string_expr(args(f, 3)[0]); + const refined_string_typet &ref_type=to_refined_string_type(s1.type()); + string_exprt s2=add_axioms_from_float(args(f, 3)[2], ref_type, true); return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } @@ -179,8 +180,9 @@ Function: string_constraint_generatort::add_axioms_for_insert_float string_exprt string_constraint_generatort::add_axioms_for_insert_float( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); - string_exprt s2=add_axioms_from_float(args(f, 3)[2]); + string_exprt s1=get_string_expr(args(f, 3)[0]); + const refined_string_typet &ref_type=to_refined_string_type(s1.type()); + string_exprt s2=add_axioms_from_float(args(f, 3)[2], ref_type, false); return add_axioms_for_insert(s1, s2, args(f, 3)[1]); } @@ -216,7 +218,7 @@ string_exprt string_constraint_generatort::add_axioms_for_insert_char_array( offset=from_integer(0, count.type()); } - string_exprt str=add_axioms_for_string_expr(f.arguments()[0]); + string_exprt str=get_string_expr(f.arguments()[0]); const exprt &length=f.arguments()[2]; const exprt &data=f.arguments()[3]; string_exprt arr=add_axioms_from_char_array( diff --git a/src/solvers/refinement/string_constraint_generator_main.cpp b/src/solvers/refinement/string_constraint_generator_main.cpp index 7fe510c2e35..f8dedaab9a7 100644 --- a/src/solvers/refinement/string_constraint_generator_main.cpp +++ b/src/solvers/refinement/string_constraint_generator_main.cpp @@ -16,6 +16,7 @@ Author: Romain Brenguier, romain.brenguier@diffblue.com #include #include #include +#include unsigned string_constraint_generatort::next_symbol_id=1; @@ -122,6 +123,42 @@ symbol_exprt string_constraint_generatort::fresh_boolean( /*******************************************************************\ +Function: string_constraint_generatort::plus_exprt_with_overflow_check + + Inputs: + op1 - First term of the sum + op2 - Second term of the sum + + Outputs: A plus expression representing the sum of the arguments + + Purpose: Create a plus expression while adding extra constraints to + axioms in order to prevent overflows. + +\*******************************************************************/ +plus_exprt string_constraint_generatort::plus_exprt_with_overflow_check( + const exprt &op1, const exprt &op2) +{ + plus_exprt sum(plus_exprt(op1, op2)); + + exprt zero=from_integer(0, op1.type()); + + binary_relation_exprt neg1(op1, ID_lt, zero); + binary_relation_exprt neg2(op2, ID_lt, zero); + binary_relation_exprt neg_sum(sum, ID_lt, zero); + + // We prevent overflows by adding the following constraint: + // If the signs of the two operands are the same, then the sign of the sum + // should also be the same. + implies_exprt no_overflow(equal_exprt(neg1, neg2), + equal_exprt(neg1, neg_sum)); + + axioms.push_back(no_overflow); + + return sum; +} + +/*******************************************************************\ + Function: string_constraint_generatort::fresh_string Inputs: a type for string @@ -144,59 +181,113 @@ string_exprt string_constraint_generatort::fresh_string( /*******************************************************************\ -Function: string_constraint_generatort::add_axioms_for_string_expr +Function: string_constraint_generatort::get_string_expr + + Inputs: an expression of refined string type + + Outputs: a string expression + + Purpose: casts an expression to a string expression, or fetches the + actual string_exprt in the case of a symbol. + +\*******************************************************************/ + +string_exprt string_constraint_generatort::get_string_expr(const exprt &expr) +{ + assert(refined_string_typet::is_refined_string_type(expr.type())); + + if(expr.id()==ID_symbol) + { + return find_or_add_string_of_symbol( + to_symbol_expr(expr), + to_refined_string_type(expr.type())); + } + else + { + return to_string_expr(expr); + } +} + +string_exprt string_constraint_generatort::convert_java_string_to_string_exprt( + const exprt &jls) +{ + assert(get_mode()==ID_java); + assert(jls.id()==ID_struct); + + exprt length(to_struct_expr(jls).op1()); + // TODO: Add assertion on the type. + // assert(length.type()==refined_string_typet::index_type()); + exprt java_content(to_struct_expr(jls).op2()); + if(java_content.id()==ID_address_of) + { + java_content=to_address_of_expr(java_content).object(); + } + else + { + java_content=dereference_exprt(java_content, java_content.type()); + } + + refined_string_typet type(java_int_type(), java_char_type()); + + return string_exprt(length, java_content, type); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_refined_string - Inputs: an expression of type string + Inputs: an expression of refined string type Outputs: a string expression that is linked to the argument through axioms that are added to the list - Purpose: obtain a refined string expression corresponding to string - variable of string function call + Purpose: obtain a refined string expression corresponding to a expression + of type string \*******************************************************************/ -string_exprt string_constraint_generatort::add_axioms_for_string_expr( - const exprt &unrefined_string) + +string_exprt string_constraint_generatort::add_axioms_for_refined_string( + const exprt &string) { - string_exprt s; + assert(refined_string_typet::is_refined_string_type(string.type())); + refined_string_typet type=to_refined_string_type(string.type()); - if(unrefined_string.id()==ID_function_application) + // Function applications should have been removed before + assert(string.id()!=ID_function_application); + + if(string.id()==ID_symbol) { - exprt res=add_axioms_for_function_application( - to_function_application_expr(unrefined_string)); - s=to_string_expr(res); + const symbol_exprt &sym=to_symbol_expr(string); + string_exprt s=find_or_add_string_of_symbol(sym, type); + axioms.push_back( + s.axiom_for_is_longer_than(from_integer(0, s.length().type()))); + return s; } - else if(unrefined_string.id()==ID_symbol) - s=find_or_add_string_of_symbol(to_symbol_expr(unrefined_string)); - else if(unrefined_string.id()==ID_address_of) + else if(string.id()==ID_nondet_symbol) { - assert(unrefined_string.op0().id()==ID_symbol); - s=find_or_add_string_of_symbol(to_symbol_expr(unrefined_string.op0())); + string_exprt s=fresh_string(type); + axioms.push_back( + s.axiom_for_is_longer_than(from_integer(0, s.length().type()))); + return s; } - else if(unrefined_string.id()==ID_if) - s=add_axioms_for_if(to_if_expr(unrefined_string)); - else if(unrefined_string.id()==ID_nondet_symbol || - unrefined_string.id()==ID_struct) + else if(string.id()==ID_if) { - // TODO: for now we ignore non deterministic symbols and struct + return add_axioms_for_if(to_if_expr(string)); } - else if(unrefined_string.id()==ID_typecast) + else if(string.id()==ID_struct) { - exprt arg=to_typecast_expr(unrefined_string).op(); - exprt res=add_axioms_for_string_expr(arg); - s=to_string_expr(res); + const string_exprt &s=to_string_expr(string); + axioms.push_back( + s.axiom_for_is_longer_than(from_integer(0, s.length().type()))); + return s; } else { - throw "add_axioms_for_string_expr:\n"+unrefined_string.pretty()+ + throw "add_axioms_for_refined_string:\n"+string.pretty()+ "\nwhich is not a function application, "+ - "a symbol or an if expression"; + "a symbol, a struct or an if expression"; } - - axioms.push_back( - s.axiom_for_is_longer_than(from_integer(0, s.length().type()))); - return s; } /*******************************************************************\ @@ -216,10 +307,10 @@ string_exprt string_constraint_generatort::add_axioms_for_if( { assert( refined_string_typet::is_refined_string_type(expr.true_case().type())); - string_exprt t=add_axioms_for_string_expr(expr.true_case()); + string_exprt t=get_string_expr(expr.true_case()); assert( refined_string_typet::is_refined_string_type(expr.false_case().type())); - string_exprt f=add_axioms_for_string_expr(expr.false_case()); + string_exprt f=get_string_expr(expr.false_case()); const refined_string_typet &ref_type=to_refined_string_type(t.type()); const typet &index_type=ref_type.get_index_type(); string_exprt res=fresh_string(ref_type); @@ -246,7 +337,7 @@ Function: string_constraint_generatort::find_or_add_string_of_symbol Outputs: a string expression - Purpose: if a symbol represent a string is present in the symbol_to_string + Purpose: if a symbol representing a string is present in the symbol_to_string table, returns the corresponding string, if the symbol is not yet present, creates a new string with the correct type depending on whether the mode is java or c, adds it to the table and returns it. @@ -254,12 +345,11 @@ Function: string_constraint_generatort::find_or_add_string_of_symbol \*******************************************************************/ string_exprt string_constraint_generatort::find_or_add_string_of_symbol( - const symbol_exprt &sym) + const symbol_exprt &sym, const refined_string_typet &ref_type) { irep_idt id=sym.get_identifier(); - const refined_string_typet &ref_type=to_refined_string_type(sym.type()); string_exprt str=fresh_string(ref_type); - auto entry=symbol_to_string.insert(std::make_pair(id, str)); + auto entry=unresolved_symbols.insert(std::make_pair(id, str)); return entry.first->second; } @@ -286,125 +376,180 @@ exprt string_constraint_generatort::add_axioms_for_function_application( const irep_idt &id=is_ssa_expr(name)?to_ssa_expr(name).get_object_name(): to_symbol_expr(name).get_identifier(); + std::string str_id(id.c_str()); + + size_t pos=str_id.find("func_length"); + if(pos!=std::string::npos) + { + function_application_exprt new_expr(expr); + // TODO: This part needs some improvement. + // Stripping the symbol name is not a very robust process. + new_expr.function() = symbol_exprt(str_id.substr(0, pos+4)); + assert(get_mode()==ID_java); + new_expr.type() = refined_string_typet(java_int_type(), java_char_type()); + + auto res_it=function_application_cache.insert(std::make_pair(new_expr, + nil_exprt())); + if(res_it.second) + { + string_exprt res=to_string_expr( + add_axioms_for_function_application(new_expr)); + res_it.first->second=res; + return res.length(); + } + else + return to_string_expr(res_it.first->second).length(); + } + + pos = str_id.find("func_data"); + if(pos!=std::string::npos) + { + function_application_exprt new_expr(expr); + new_expr.function() = symbol_exprt(str_id.substr(0, pos+4)); + new_expr.type() = refined_string_typet(java_int_type(), java_char_type()); + + auto res_it=function_application_cache.insert(std::make_pair(new_expr, + nil_exprt())); + if(res_it.second) + { + string_exprt res=to_string_expr( + add_axioms_for_function_application(new_expr)); + res_it.first->second=res; + return res.content(); + } + else + return to_string_expr(res_it.first->second).content(); + } + // TODO: improve efficiency of this test by either ordering test by frequency // or using a map + auto res_it=function_application_cache.find(expr); + if(res_it!=function_application_cache.end() && res_it->second!=nil_exprt()) + return res_it->second; + + exprt res; + if(id==ID_cprover_char_literal_func) - return add_axioms_for_char_literal(expr); + res=add_axioms_for_char_literal(expr); else if(id==ID_cprover_string_length_func) - return add_axioms_for_length(expr); + res=add_axioms_for_length(expr); else if(id==ID_cprover_string_equal_func) - return add_axioms_for_equals(expr); + res=add_axioms_for_equals(expr); else if(id==ID_cprover_string_equals_ignore_case_func) - return add_axioms_for_equals_ignore_case(expr); + res=add_axioms_for_equals_ignore_case(expr); else if(id==ID_cprover_string_is_empty_func) - return add_axioms_for_is_empty(expr); + res=add_axioms_for_is_empty(expr); else if(id==ID_cprover_string_char_at_func) - return add_axioms_for_char_at(expr); + res=add_axioms_for_char_at(expr); else if(id==ID_cprover_string_is_prefix_func) - return add_axioms_for_is_prefix(expr); + res=add_axioms_for_is_prefix(expr); else if(id==ID_cprover_string_is_suffix_func) - return add_axioms_for_is_suffix(expr); + res=add_axioms_for_is_suffix(expr); else if(id==ID_cprover_string_startswith_func) - return add_axioms_for_is_prefix(expr, true); + res=add_axioms_for_is_prefix(expr, true); else if(id==ID_cprover_string_endswith_func) - return add_axioms_for_is_suffix(expr, true); + res=add_axioms_for_is_suffix(expr, true); else if(id==ID_cprover_string_contains_func) - return add_axioms_for_contains(expr); + res=add_axioms_for_contains(expr); else if(id==ID_cprover_string_hash_code_func) - return add_axioms_for_hash_code(expr); + res=add_axioms_for_hash_code(expr); else if(id==ID_cprover_string_index_of_func) - return add_axioms_for_index_of(expr); + res=add_axioms_for_index_of(expr); else if(id==ID_cprover_string_last_index_of_func) - return add_axioms_for_last_index_of(expr); + res=add_axioms_for_last_index_of(expr); else if(id==ID_cprover_string_parse_int_func) - return add_axioms_for_parse_int(expr); + res=add_axioms_for_parse_int(expr); else if(id==ID_cprover_string_to_char_array_func) - return add_axioms_for_to_char_array(expr); + res=add_axioms_for_to_char_array(expr); else if(id==ID_cprover_string_code_point_at_func) - return add_axioms_for_code_point_at(expr); + res=add_axioms_for_code_point_at(expr); else if(id==ID_cprover_string_code_point_before_func) - return add_axioms_for_code_point_before(expr); + res=add_axioms_for_code_point_before(expr); else if(id==ID_cprover_string_code_point_count_func) - return add_axioms_for_code_point_count(expr); + res=add_axioms_for_code_point_count(expr); else if(id==ID_cprover_string_offset_by_code_point_func) - return add_axioms_for_offset_by_code_point(expr); + res=add_axioms_for_offset_by_code_point(expr); else if(id==ID_cprover_string_compare_to_func) - return add_axioms_for_compare_to(expr); + res=add_axioms_for_compare_to(expr); else if(id==ID_cprover_string_literal_func) - return add_axioms_from_literal(expr); + res=add_axioms_from_literal(expr); else if(id==ID_cprover_string_concat_func) - return add_axioms_for_concat(expr); + res=add_axioms_for_concat(expr); else if(id==ID_cprover_string_concat_int_func) - return add_axioms_for_concat_int(expr); + res=add_axioms_for_concat_int(expr); else if(id==ID_cprover_string_concat_long_func) - return add_axioms_for_concat_long(expr); + res=add_axioms_for_concat_long(expr); else if(id==ID_cprover_string_concat_bool_func) - return add_axioms_for_concat_bool(expr); + res=add_axioms_for_concat_bool(expr); else if(id==ID_cprover_string_concat_char_func) - return add_axioms_for_concat_char(expr); + res=add_axioms_for_concat_char(expr); else if(id==ID_cprover_string_concat_double_func) - return add_axioms_for_concat_double(expr); + res=add_axioms_for_concat_double(expr); else if(id==ID_cprover_string_concat_float_func) - return add_axioms_for_concat_float(expr); + res=add_axioms_for_concat_float(expr); else if(id==ID_cprover_string_concat_code_point_func) - return add_axioms_for_concat_code_point(expr); + res=add_axioms_for_concat_code_point(expr); else if(id==ID_cprover_string_insert_func) - return add_axioms_for_insert(expr); + res=add_axioms_for_insert(expr); else if(id==ID_cprover_string_insert_int_func) - return add_axioms_for_insert_int(expr); + res=add_axioms_for_insert_int(expr); else if(id==ID_cprover_string_insert_long_func) - return add_axioms_for_insert_long(expr); + res=add_axioms_for_insert_long(expr); else if(id==ID_cprover_string_insert_bool_func) - return add_axioms_for_insert_bool(expr); + res=add_axioms_for_insert_bool(expr); else if(id==ID_cprover_string_insert_char_func) - return add_axioms_for_insert_char(expr); + res=add_axioms_for_insert_char(expr); else if(id==ID_cprover_string_insert_double_func) - return add_axioms_for_insert_double(expr); + res=add_axioms_for_insert_double(expr); else if(id==ID_cprover_string_insert_float_func) - return add_axioms_for_insert_float(expr); + res=add_axioms_for_insert_float(expr); +#if 0 else if(id==ID_cprover_string_insert_char_array_func) - return add_axioms_for_insert_char_array(expr); + res=add_axioms_for_insert_char_array(expr); +#endif else if(id==ID_cprover_string_substring_func) - return add_axioms_for_substring(expr); + res=add_axioms_for_substring(expr); else if(id==ID_cprover_string_trim_func) - return add_axioms_for_trim(expr); + res=add_axioms_for_trim(expr); else if(id==ID_cprover_string_to_lower_case_func) - return add_axioms_for_to_lower_case(expr); + res=add_axioms_for_to_lower_case(expr); else if(id==ID_cprover_string_to_upper_case_func) - return add_axioms_for_to_upper_case(expr); + res=add_axioms_for_to_upper_case(expr); else if(id==ID_cprover_string_char_set_func) - return add_axioms_for_char_set(expr); + res=add_axioms_for_char_set(expr); else if(id==ID_cprover_string_value_of_func) - return add_axioms_for_value_of(expr); + res=add_axioms_for_value_of(expr); else if(id==ID_cprover_string_empty_string_func) - return add_axioms_for_empty_string(expr); + res=add_axioms_for_empty_string(expr); else if(id==ID_cprover_string_copy_func) - return add_axioms_for_copy(expr); + res=add_axioms_for_copy(expr); else if(id==ID_cprover_string_of_int_func) - return add_axioms_from_int(expr); + res=add_axioms_from_int(expr); else if(id==ID_cprover_string_of_int_hex_func) - return add_axioms_from_int_hex(expr); + res=add_axioms_from_int_hex(expr); else if(id==ID_cprover_string_of_float_func) - return add_axioms_from_float(expr); + res=add_axioms_from_float(expr); else if(id==ID_cprover_string_of_double_func) - return add_axioms_from_double(expr); + res=add_axioms_from_double(expr); else if(id==ID_cprover_string_of_long_func) - return add_axioms_from_long(expr); + res=add_axioms_from_long(expr); else if(id==ID_cprover_string_of_bool_func) - return add_axioms_from_bool(expr); + res=add_axioms_from_bool(expr); else if(id==ID_cprover_string_of_char_func) - return add_axioms_from_char(expr); - else if(id==ID_cprover_string_of_char_array_func) - return add_axioms_from_char_array(expr); + res=add_axioms_from_char(expr); else if(id==ID_cprover_string_set_length_func) - return add_axioms_for_set_length(expr); + res=add_axioms_for_set_length(expr); else if(id==ID_cprover_string_delete_func) - return add_axioms_for_delete(expr); + res=add_axioms_for_delete(expr); else if(id==ID_cprover_string_delete_char_at_func) - return add_axioms_for_delete_char_at(expr); + res=add_axioms_for_delete_char_at(expr); else if(id==ID_cprover_string_replace_func) - return add_axioms_for_replace(expr); + res=add_axioms_for_replace(expr); + else if(id==ID_cprover_string_intern_func) + res=add_axioms_for_intern(expr); + else if(id==ID_cprover_string_array_of_char_pointer_func) + res=add_axioms_for_char_pointer(expr); else { std::string msg( @@ -412,13 +557,16 @@ exprt string_constraint_generatort::add_axioms_for_function_application( msg+=id2string(id); throw msg; } + function_application_cache[expr]=res; + return res; } /*******************************************************************\ Function: string_constraint_generatort::add_axioms_for_copy - Inputs: function application with one argument, which is a string + Inputs: function application with one argument, which is a string, + or three arguments: string, integer offset and count Outputs: a new string expression @@ -430,20 +578,20 @@ Function: string_constraint_generatort::add_axioms_for_copy string_exprt string_constraint_generatort::add_axioms_for_copy( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 1)[0]); - const refined_string_typet &ref_type=to_refined_string_type(s1.type()); - string_exprt res=fresh_string(ref_type); - - // We add axioms: - // a1 : |res|=|s1| - // a2 : forall i<|s1|. s1[i]=res[i] - - axioms.push_back(res.axiom_for_has_same_length_as(s1)); - - symbol_exprt idx=fresh_univ_index("QA_index_copy", ref_type.get_index_type()); - string_constraintt a2(idx, s1.length(), equal_exprt(s1[idx], res[idx])); - axioms.push_back(a2); - return res; + const auto &args=f.arguments(); + if(args.size()==1) + { + string_exprt s1=get_string_expr(args[0]); + return s1; + } + else + { + assert(args.size()==3); + string_exprt s1=get_string_expr(args[0]); + exprt offset=args[1]; + exprt count=args[2]; + return add_axioms_for_substring(s1, offset, plus_exprt(offset, count)); + } } /*******************************************************************\ @@ -473,6 +621,28 @@ string_exprt string_constraint_generatort::add_axioms_for_java_char_array( /*******************************************************************\ +Function: string_constraint_generatort::add_axioms_for_char_pointer + + Inputs: an expression of type char + + Outputs: an array expression + + Purpose: for an expression of the form `array[0]` returns `array` + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_char_pointer( + const function_application_exprt &fun) +{ + exprt char_pointer=args(fun, 1)[0]; + if(char_pointer.id()==ID_index) + return char_pointer.op0(); + // TODO: we do not know what to do in the other cases + assert(false); +} + +/*******************************************************************\ + Function: string_constraint_generatort::add_axioms_for_length Inputs: function application with one string argument @@ -486,7 +656,7 @@ Function: string_constraint_generatort::add_axioms_for_length exprt string_constraint_generatort::add_axioms_for_length( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 1)[0]); + string_exprt str=get_string_expr(args(f, 1)[0]); return str.length(); } @@ -511,6 +681,7 @@ string_exprt string_constraint_generatort::add_axioms_from_char_array( const exprt &offset, const exprt &count) { + assert(false); // deprecated, we should use add_axioms_for_substring instead const typet &char_type=to_array_type(data.type()).subtype(); const typet &index_type=length.type(); refined_string_typet ref_type(index_type, char_type); @@ -523,7 +694,7 @@ string_exprt string_constraint_generatort::add_axioms_from_char_array( symbol_exprt qvar=fresh_univ_index("QA_string_of_char_array", index_type); exprt char_in_tab=data; assert(char_in_tab.id()==ID_index); - char_in_tab.op1()=plus_exprt(qvar, offset); + char_in_tab.op1()=plus_exprt_with_overflow_check(qvar, offset); string_constraintt a1(qvar, count, equal_exprt(str[qvar], char_in_tab)); axioms.push_back(a1); @@ -549,6 +720,7 @@ Function: string_constraint_generatort::add_axioms_from_char_array string_exprt string_constraint_generatort::add_axioms_from_char_array( const function_application_exprt &f) { + assert(false); // deprecated, we should use add_axioms_for_substring instead exprt offset; exprt count; if(f.arguments().size()==4) @@ -638,7 +810,7 @@ Function: string_constraint_generatort::add_axioms_for_char_at exprt string_constraint_generatort::add_axioms_for_char_at( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt str=get_string_expr(args(f, 2)[0]); const refined_string_typet &ref_type=to_refined_string_type(str.type()); symbol_exprt char_sym=fresh_symbol("char", ref_type.get_char_type()); axioms.push_back(equal_exprt(char_sym, str[args(f, 2)[1]])); @@ -660,26 +832,6 @@ Function: string_constraint_generatort::add_axioms_for_to_char_array exprt string_constraint_generatort::add_axioms_for_to_char_array( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 1)[0]); + string_exprt str=get_string_expr(args(f, 1)[0]); return str.content(); } - -/*******************************************************************\ - -Function: string_constraint_generatort::set_string_symbol_equal_to_expr - - Inputs: a symbol and a string - - Purpose: add a correspondence to make sure the symbol points to the - same string as the second argument - -\*******************************************************************/ - -void string_constraint_generatort::set_string_symbol_equal_to_expr( - const symbol_exprt &sym, const exprt &str) -{ - if(str.id()==ID_symbol) - assign_to_symbol(sym, find_or_add_string_of_symbol(to_symbol_expr(str))); - else - assign_to_symbol(sym, add_axioms_for_string_expr(str)); -} diff --git a/src/solvers/refinement/string_constraint_generator_testing.cpp b/src/solvers/refinement/string_constraint_generator_testing.cpp index 8b1c7bca9d4..2a08b021070 100644 --- a/src/solvers/refinement/string_constraint_generator_testing.cpp +++ b/src/solvers/refinement/string_constraint_generator_testing.cpp @@ -31,15 +31,15 @@ exprt string_constraint_generatort::add_axioms_for_is_prefix( // We add axioms: // a1 : isprefix => |str| >= |prefix|+offset - // a2 : forall 0<=qvar - // s0[witness+offset]=s2[witness] - // a3 : !isprefix => |str| < |prefix|+offset - // || (|str| >= |prefix|+offset &&0<=witness<|prefix| - // &&str[witness+ofsset]!=prefix[witness]) + // a2 : forall 0<=qvar<|prefix|. isprefix => s0[witness+offset]=s2[witness] + // a3 : !isprefix => + // |str|<|prefix|+offset || + // (0<=witness<|prefix| && str[witness+offset]!=prefix[witness]) implies_exprt a1( isprefix, - str.axiom_for_is_longer_than(plus_exprt(prefix.length(), offset))); + str.axiom_for_is_longer_than(plus_exprt_with_overflow_check( + prefix.length(), offset))); axioms.push_back(a1); symbol_exprt qvar=fresh_univ_index("QA_isprefix", index_type); @@ -47,7 +47,8 @@ exprt string_constraint_generatort::add_axioms_for_is_prefix( qvar, prefix.length(), isprefix, - equal_exprt(str[plus_exprt(qvar, offset)], prefix[qvar])); + equal_exprt(str[plus_exprt_with_overflow_check(qvar, offset)], + prefix[qvar])); axioms.push_back(a2); symbol_exprt witness=fresh_exist_index("witness_not_isprefix", index_type); @@ -55,14 +56,13 @@ exprt string_constraint_generatort::add_axioms_for_is_prefix( axiom_for_is_positive_index(witness), and_exprt( prefix.axiom_for_is_strictly_longer_than(witness), - notequal_exprt(str[plus_exprt(witness, offset)], prefix[witness]))); + notequal_exprt(str[plus_exprt_with_overflow_check(witness, offset)], + prefix[witness]))); or_exprt s0_notpref_s1( not_exprt( - str.axiom_for_is_longer_than(plus_exprt(prefix.length(), offset))), - and_exprt( - witness_diff, str.axiom_for_is_longer_than( - plus_exprt(prefix.length(), offset)))); + plus_exprt_with_overflow_check(prefix.length(), offset))), + witness_diff); implies_exprt a3(not_exprt(isprefix), s0_notpref_s1); axioms.push_back(a3); @@ -88,8 +88,8 @@ exprt string_constraint_generatort::add_axioms_for_is_prefix( { const function_application_exprt::argumentst &args=f.arguments(); assert(f.type()==bool_typet() || f.type().id()==ID_c_bool); - string_exprt s0=add_axioms_for_string_expr(args[swap_arguments?1:0]); - string_exprt s1=add_axioms_for_string_expr(args[swap_arguments?0:1]); + string_exprt s0=get_string_expr(args[swap_arguments?1:0]); + string_exprt s1=get_string_expr(args[swap_arguments?0:1]); exprt offset; if(args.size()==2) offset=from_integer(0, s0.length().type()); @@ -121,7 +121,7 @@ exprt string_constraint_generatort::add_axioms_for_is_empty( // a2 : s0 => is_empty symbol_exprt is_empty=fresh_boolean("is_empty"); - string_exprt s0=add_axioms_for_string_expr(args(f, 1)[0]); + string_exprt s0=get_string_expr(args(f, 1)[0]); axioms.push_back(implies_exprt(is_empty, s0.axiom_for_has_length(0))); axioms.push_back(implies_exprt(s0.axiom_for_has_length(0), is_empty)); return typecast_exprt(is_empty, f.type()); @@ -150,8 +150,8 @@ exprt string_constraint_generatort::add_axioms_for_is_suffix( symbol_exprt issuffix=fresh_boolean("issuffix"); typecast_exprt tc_issuffix(issuffix, f.type()); - string_exprt s0=add_axioms_for_string_expr(args[swap_arguments?1:0]); - string_exprt s1=add_axioms_for_string_expr(args[swap_arguments?0:1]); + string_exprt s0=get_string_expr(args[swap_arguments?1:0]); + string_exprt s1=get_string_expr(args[swap_arguments?0:1]); const typet &index_type=s0.length().type(); // We add axioms: @@ -159,7 +159,7 @@ exprt string_constraint_generatort::add_axioms_for_is_suffix( // a2 : forall witness s1[witness]=s0[witness + s0.length-s1.length] // a3 : !issuffix => - // s1.length > s0.length + // (s1.length > s0.length && witness=-1) // || (s1.length > witness>=0 // &&s1[witness]!=s0[witness + s0.length-s1.length] @@ -177,7 +177,8 @@ exprt string_constraint_generatort::add_axioms_for_is_suffix( exprt shifted=plus_exprt( witness, minus_exprt(s1.length(), s0.length())); or_exprt constr3( - s0.axiom_for_is_strictly_longer_than(s1), + and_exprt(s0.axiom_for_is_strictly_longer_than(s1), + equal_exprt(witness, from_integer(-1, index_type))), and_exprt( notequal_exprt(s0[witness], s1[shifted]), and_exprt( @@ -207,9 +208,10 @@ exprt string_constraint_generatort::add_axioms_for_contains( assert(f.type()==bool_typet() || f.type().id()==ID_c_bool); symbol_exprt contains=fresh_boolean("contains"); typecast_exprt tc_contains(contains, f.type()); - string_exprt s0=add_axioms_for_string_expr(args(f, 2)[0]); - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[1]); - const typet &index_type=s0.type(); + string_exprt s0=get_string_expr(args(f, 2)[0]); + string_exprt s1=get_string_expr(args(f, 2)[1]); + const refined_string_typet ref_type=to_refined_string_type(s0.type()); + const typet &index_type=ref_type.get_index_type(); // We add axioms: // a1 : contains => s0.length >= s1.length diff --git a/src/solvers/refinement/string_constraint_generator_transformation.cpp b/src/solvers/refinement/string_constraint_generator_transformation.cpp index 83735e0d5b5..f27fe5d4317 100644 --- a/src/solvers/refinement/string_constraint_generator_transformation.cpp +++ b/src/solvers/refinement/string_constraint_generator_transformation.cpp @@ -29,7 +29,7 @@ Function: string_constraint_generatort::add_axioms_for_set_length string_exprt string_constraint_generatort::add_axioms_for_set_length( const function_application_exprt &f) { - string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt s1=get_string_expr(args(f, 2)[0]); exprt k=args(f, 2)[1]; const refined_string_typet &ref_type=to_refined_string_type(s1.type()); string_exprt res=fresh_string(ref_type); @@ -76,7 +76,7 @@ string_exprt string_constraint_generatort::add_axioms_for_substring( { const function_application_exprt::argumentst &args=f.arguments(); assert(args.size()>=2); - string_exprt str=add_axioms_for_string_expr(args[0]); + string_exprt str=get_string_expr(args[0]); exprt i(args[1]); exprt j; if(args.size()==3) @@ -110,7 +110,6 @@ string_exprt string_constraint_generatort::add_axioms_for_substring( { const refined_string_typet &ref_type=to_refined_string_type(str.type()); const typet &index_type=ref_type.get_index_type(); - symbol_exprt idx=fresh_exist_index("index_substring", index_type); assert(start.type()==index_type); assert(end.type()==index_type); string_exprt res=fresh_string(ref_type); @@ -133,8 +132,11 @@ string_exprt string_constraint_generatort::add_axioms_for_substring( // Warning: check what to do if the string is not long enough axioms.push_back(str.axiom_for_is_longer_than(end)); - string_constraintt a4( - idx, res.length(), equal_exprt(res[idx], str[plus_exprt(start, idx)])); + symbol_exprt idx=fresh_univ_index("QA_index_substring", index_type); + string_constraintt a4(idx, + res.length(), + equal_exprt(res[idx], + str[plus_exprt_with_overflow_check(start, idx)])); axioms.push_back(a4); return res; } @@ -154,7 +156,7 @@ Function: string_constraint_generatort::add_axioms_for_trim string_exprt string_constraint_generatort::add_axioms_for_trim( const function_application_exprt &expr) { - string_exprt str=add_axioms_for_string_expr(args(expr, 1)[0]); + string_exprt str=get_string_expr(args(expr, 1)[0]); const refined_string_typet &ref_type=to_refined_string_type(str.type()); const typet &index_type=ref_type.get_index_type(); string_exprt res=fresh_string(ref_type); @@ -173,7 +175,8 @@ string_exprt string_constraint_generatort::add_axioms_for_trim( // a8 : forall n<|s1|, s[idx+n]=s1[n] // a9 : (s[m]>' ' &&s[m+|s1|-1]>' ') || m=|s| - exprt a1=str.axiom_for_is_longer_than(plus_exprt(idx, res.length())); + exprt a1=str.axiom_for_is_longer_than( + plus_exprt_with_overflow_check(idx, res.length())); axioms.push_back(a1); binary_relation_exprt a2(idx, ID_ge, from_integer(0, index_type)); @@ -195,7 +198,8 @@ string_exprt string_constraint_generatort::add_axioms_for_trim( axioms.push_back(a6); symbol_exprt n2=fresh_univ_index("QA_index_trim2", index_type); - minus_exprt bound(str.length(), plus_exprt(idx, res.length())); + minus_exprt bound(str.length(), plus_exprt_with_overflow_check(idx, + res.length())); binary_relation_exprt eqn2( str[plus_exprt(idx, plus_exprt(res.length(), n2))], ID_le, @@ -210,7 +214,8 @@ string_exprt string_constraint_generatort::add_axioms_for_trim( axioms.push_back(a8); minus_exprt index_before( - plus_exprt(idx, res.length()), from_integer(1, index_type)); + plus_exprt_with_overflow_check(idx, res.length()), + from_integer(1, index_type)); binary_relation_exprt no_space_before(str[index_before], ID_gt, space_char); or_exprt a9( equal_exprt(idx, str.length()), @@ -236,7 +241,7 @@ Function: string_constraint_generatort::add_axioms_for_to_lower_case string_exprt string_constraint_generatort::add_axioms_for_to_lower_case( const function_application_exprt &expr) { - string_exprt str=add_axioms_for_string_expr(args(expr, 1)[0]); + string_exprt str=get_string_expr(args(expr, 1)[0]); const refined_string_typet &ref_type=to_refined_string_type(str.type()); const typet &char_type=ref_type.get_char_type(); const typet &index_type=ref_type.get_index_type(); @@ -289,7 +294,7 @@ Function: string_constraint_generatort::add_axioms_for_to_upper_case string_exprt string_constraint_generatort::add_axioms_for_to_upper_case( const function_application_exprt &expr) { - string_exprt str=add_axioms_for_string_expr(args(expr, 1)[0]); + string_exprt str=get_string_expr(args(expr, 1)[0]); const refined_string_typet &ref_type=to_refined_string_type(str.type()); const typet &char_type=ref_type.get_char_type(); const typet &index_type=ref_type.get_index_type(); @@ -345,7 +350,7 @@ Function: string_constraint_generatort::add_axioms_for_char_set string_exprt string_constraint_generatort::add_axioms_for_char_set( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt str=get_string_expr(args(f, 3)[0]); const refined_string_typet &ref_type=to_refined_string_type(str.type()); string_exprt res=fresh_string(ref_type); with_exprt sarrnew(str.content(), args(f, 3)[1], args(f, 3)[2]); @@ -378,7 +383,7 @@ Function: string_constraint_generatort::add_axioms_for_replace string_exprt string_constraint_generatort::add_axioms_for_replace( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt str=get_string_expr(args(f, 3)[0]); const refined_string_typet &ref_type=to_refined_string_type(str.type()); const exprt &old_char=args(f, 3)[1]; const exprt &new_char=args(f, 3)[2]; @@ -421,10 +426,12 @@ Function: string_constraint_generatort::add_axioms_for_delete_char_at string_exprt string_constraint_generatort::add_axioms_for_delete_char_at( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt str=get_string_expr(args(f, 2)[0]); exprt index_one=from_integer(1, str.length().type()); return add_axioms_for_delete( - str, args(f, 2)[1], plus_exprt(args(f, 2)[1], index_one)); + str, + args(f, 2)[1], + plus_exprt_with_overflow_check(args(f, 2)[1], index_one)); } /*******************************************************************\ @@ -468,6 +475,6 @@ Function: string_constraint_generatort::add_axioms_for_delete string_exprt string_constraint_generatort::add_axioms_for_delete( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt str=get_string_expr(args(f, 3)[0]); return add_axioms_for_delete(str, args(f, 3)[1], args(f, 3)[2]); } diff --git a/src/solvers/refinement/string_constraint_generator_valueof.cpp b/src/solvers/refinement/string_constraint_generator_valueof.cpp index d1030e5e085..10fe490259a 100644 --- a/src/solvers/refinement/string_constraint_generator_valueof.cpp +++ b/src/solvers/refinement/string_constraint_generator_valueof.cpp @@ -63,7 +63,8 @@ Function: string_constraint_generatort::add_axioms_from_float string_exprt string_constraint_generatort::add_axioms_from_float( const function_application_exprt &f) { - return add_axioms_from_float(args(f, 1)[0], false); + const refined_string_typet &ref_type=to_refined_string_type(f.type()); + return add_axioms_from_float(args(f, 1)[0], ref_type, false); } /*******************************************************************\ @@ -81,7 +82,8 @@ Function: string_constraint_generatort::add_axioms_from_double string_exprt string_constraint_generatort::add_axioms_from_double( const function_application_exprt &f) { - return add_axioms_from_float(args(f, 1)[0], true); + const refined_string_typet &ref_type=to_refined_string_type(f.type()); + return add_axioms_from_float(args(f, 1)[0], ref_type, true); } /*******************************************************************\ @@ -99,13 +101,12 @@ Function: string_constraint_generatort::add_axioms_from_float \*******************************************************************/ string_exprt string_constraint_generatort::add_axioms_from_float( - const exprt &f, bool double_precision) + const exprt &f, const refined_string_typet &ref_type, bool double_precision) { - const refined_string_typet &ref_type=to_refined_string_type(f.type()); + string_exprt res=fresh_string(ref_type); const typet &index_type=ref_type.get_index_type(); const typet &char_type=ref_type.get_char_type(); - string_exprt res=fresh_string(ref_type); - const exprt &index24=from_integer(24, ref_type.get_index_type()); + const exprt &index24=from_integer(24, index_type); axioms.push_back(res.axiom_for_is_shorter_than(index24)); string_exprt magnitude=fresh_string(ref_type); @@ -323,13 +324,22 @@ string_exprt string_constraint_generatort::add_axioms_from_int( axioms.push_back(a1); exprt chr=res[0]; - exprt starts_with_minus=equal_exprt(chr, minus_char); - exprt starts_with_digit=and_exprt( + equal_exprt starts_with_minus(chr, minus_char); + and_exprt starts_with_digit( binary_relation_exprt(chr, ID_ge, zero_char), binary_relation_exprt(chr, ID_le, nine_char)); or_exprt a2(starts_with_digit, starts_with_minus); axioms.push_back(a2); + // These are constraints to detect number that requiere the maximum number + // of digits + exprt smallest_with_max_digits= + from_integer(smallest_by_digit(max_size-1), type); + binary_relation_exprt big_negative( + i, ID_le, unary_minus_exprt(smallest_with_max_digits)); + binary_relation_exprt big_positive(i, ID_ge, smallest_with_max_digits); + or_exprt requieres_max_digits(big_negative, big_positive); + for(size_t size=1; size<=max_size; size++) { // For each possible size, we add axioms: @@ -387,13 +397,18 @@ string_exprt string_constraint_generatort::add_axioms_from_int( axioms.push_back(a6); } - // we have to be careful when exceeding the maximal size of integers + // when the size is close to the maximum, either the number is very big + // or it is negative + if(size==max_size-1) + { + implies_exprt a7(premise, or_exprt(requieres_max_digits, + starts_with_minus)); + axioms.push_back(a7); + } + // when we reach the maximal size the number is very big in the negative if(size==max_size) { - exprt smallest_with_10_digits=from_integer( - smallest_by_digit(max_size), type); - binary_relation_exprt big(i, ID_ge, smallest_with_10_digits); - implies_exprt a7(premise, big); + implies_exprt a7(premise, and_exprt(starts_with_minus, big_negative)); axioms.push_back(a7); } } @@ -597,6 +612,60 @@ string_exprt string_constraint_generatort::add_axioms_for_value_of( /*******************************************************************\ +Function: string_constraint_generatort::add_axioms_for_correct_number_format + + Inputs: function application with one string expression + + Outputs: an boolean expression + + Purpose: add axioms making the return value true if the given string is + a correct number + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_correct_number_format( + const string_exprt &str, std::size_t max_size) +{ + symbol_exprt correct=fresh_boolean("correct_number_format"); + const refined_string_typet &ref_type=to_refined_string_type(str.type()); + const typet &char_type=ref_type.get_char_type(); + const typet &index_type=ref_type.get_index_type(); + exprt zero_char=constant_char('0', char_type); + exprt nine_char=constant_char('9', char_type); + exprt minus_char=constant_char('-', char_type); + exprt plus_char=constant_char('+', char_type); + + exprt chr=str[0]; + equal_exprt starts_with_minus(chr, minus_char); + equal_exprt starts_with_plus(chr, plus_char); + and_exprt starts_with_digit( + binary_relation_exprt(chr, ID_ge, zero_char), + binary_relation_exprt(chr, ID_le, nine_char)); + + or_exprt correct_first( + or_exprt(starts_with_minus, starts_with_plus), starts_with_digit); + exprt has_first=str.axiom_for_is_longer_than(from_integer(1, index_type)); + implies_exprt a1(correct, and_exprt(has_first, correct_first)); + axioms.push_back(a1); + + exprt not_too_long=str.axiom_for_is_shorter_than(max_size); + axioms.push_back(not_too_long); + + symbol_exprt qvar=fresh_univ_index("number_format", index_type); + + and_exprt is_digit( + binary_relation_exprt(str[qvar], ID_ge, zero_char), + binary_relation_exprt(str[qvar], ID_le, nine_char)); + + string_constraintt a2( + qvar, from_integer(1, index_type), str.length(), correct, is_digit); + + axioms.push_back(a2); + return correct; +} + +/*******************************************************************\ + Function: string_constraint_generatort::add_axioms_for_parse_int Inputs: function application with one string expression @@ -610,7 +679,7 @@ Function: string_constraint_generatort::add_axioms_for_parse_int exprt string_constraint_generatort::add_axioms_for_parse_int( const function_application_exprt &f) { - string_exprt str=add_axioms_for_string_expr(args(f, 1)[0]); + string_exprt str=get_string_expr(args(f, 1)[0]); const typet &type=f.type(); symbol_exprt i=fresh_symbol("parsed_int", type); const refined_string_typet &ref_type=to_refined_string_type(str.type()); @@ -626,6 +695,10 @@ exprt string_constraint_generatort::add_axioms_for_parse_int( exprt starts_with_plus=equal_exprt(chr, plus_char); exprt starts_with_digit=binary_relation_exprt(chr, ID_ge, zero_char); + // TODO: we should throw an exception when this does not hold: + exprt correct=add_axioms_for_correct_number_format(str); + axioms.push_back(correct); + for(unsigned size=1; size<=10; size++) { exprt sum=from_integer(0, type); diff --git a/src/solvers/refinement/string_refinement.cpp b/src/solvers/refinement/string_refinement.cpp index db9a2c460cc..1391ffd2315 100644 --- a/src/solvers/refinement/string_refinement.cpp +++ b/src/solvers/refinement/string_refinement.cpp @@ -11,17 +11,38 @@ Author: Alberto Griggio, alberto.griggio@gmail.com \*******************************************************************/ #include +#include #include #include #include +#include +#include #include #include #include +#include + +/*******************************************************************\ + +Constructor: string_refinementt + + Inputs: a namespace, a decision procedure, a bound on the number + of refinements and a boolean flag `concretize_result` + + Purpose: refinement_bound is a bound on the number of refinement allowed. + if `concretize_result` is set to true, at the end of the decision + procedure, the solver try to find a concrete value for each + character + +\*******************************************************************/ string_refinementt::string_refinementt( - const namespacet &_ns, propt &_prop, unsigned refinement_bound): + const namespacet &_ns, + propt &_prop, + unsigned refinement_bound): supert(_ns, _prop), use_counter_example(false), + do_concretizing(false), initial_loop_bound(refinement_bound) { } @@ -52,15 +73,27 @@ Function: string_refinementt::display_index_set void string_refinementt::display_index_set() { + std::size_t count=0; + std::size_t count_current=0; for(const auto &i : index_set) { const exprt &s=i.first; - debug() << "IS(" << from_expr(s) << ")=={"; + debug() << "IS(" << from_expr(s) << ")=={" << eom; for(auto j : i.second) - debug() << from_expr(j) << "; "; + { + if(current_index_set[i.first].find(j)!=current_index_set[i.first].end()) + { + count_current++; + debug() << "**"; + } + debug() << " " << from_expr(j) << ";" << eom; + count++; + } debug() << "}" << eom; } + debug() << count << " elements in index set (" << count_current + << " newly added)" << eom; } /*******************************************************************\ @@ -100,152 +133,320 @@ void string_refinementt::add_instantiations() /*******************************************************************\ -Function: string_refinementt::convert_rest - - Inputs: an expression +Function: string_refinementt::add_symbol_to_symbol_map() - Outputs: a literal + Inputs: a symbol and the expression to map it to - Purpose: if the expression is a function application, we convert it - using our own convert_function_application method + Purpose: keeps a map of symbols to expressions, such as none of the + mapped values exist as a key \*******************************************************************/ -literalt string_refinementt::convert_rest(const exprt &expr) +void string_refinementt::add_symbol_to_symbol_map +(const exprt &lhs, const exprt &rhs) { - if(expr.id()==ID_function_application) + assert(lhs.id()==ID_symbol); + + // We insert the mapped value of the rhs, if it exists. + auto it=symbol_resolve.find(rhs); + const exprt &new_rhs=it!=symbol_resolve.end()?it->second:rhs; + + symbol_resolve[lhs]=new_rhs; + reverse_symbol_resolve[new_rhs].push_back(lhs); + + std::list symbols_to_update_with_new_rhs(reverse_symbol_resolve[rhs]); + for(exprt item : symbols_to_update_with_new_rhs) { - // can occur in __CPROVER_assume - bvt bv=convert_function_application(to_function_application_expr(expr)); - assert(bv.size()==1); - return bv[0]; + symbol_resolve[item]=new_rhs; + reverse_symbol_resolve[new_rhs].push_back(item); } - else +} + +/*******************************************************************\ + +Function: string_refinementt::set_char_array_equality() + + Inputs: the rhs and lhs of an equality over character arrays + + Purpose: add axioms if the rhs is a character array + +\*******************************************************************/ + +void string_refinementt::set_char_array_equality( + const exprt &lhs, const exprt &rhs) +{ + assert(lhs.id()==ID_symbol); + + if(rhs.id()==ID_array && rhs.type().id()==ID_array) { - return supert::convert_rest(expr); + const typet &index_type=to_array_type(rhs.type()).size().type(); + for(size_t i=0, ilim=rhs.operands().size(); i!=ilim; ++i) + { + // Introduce axioms to map symbolic rhs to its char array. + index_exprt arraycell(rhs, from_integer(i, index_type)); + equal_exprt arrayeq(arraycell, rhs.operands()[i]); + add_lemma(arrayeq, false); +#if 0 + generator.axioms.push_back(arrayeq); +#endif + } } + // At least for Java (as it is currently pre-processed), we need not consider + // other cases, because all character arrays find themselves on the rhs of an + // equality. Note that this might not be the case for other languages. } /*******************************************************************\ -Function: string_refinementt::convert_symbol +Function: string_refinementt::substitute_function_applications() - Inputs: an expression + Inputs: an expression containing function applications - Outputs: a bitvector + Outputs: an epression containing no function application - Purpose: if the expression as string type, look up for the string in the - list of string symbols that we maintain, and convert it; - otherwise use the method of the parent class + Purpose: remove functions applications and create the necessary + axioms \*******************************************************************/ -bvt string_refinementt::convert_symbol(const exprt &expr) +exprt string_refinementt::substitute_function_applications(exprt expr) { - const typet &type=expr.type(); - const irep_idt &identifier=expr.get(ID_identifier); - assert(!identifier.empty()); + for(size_t i=0; iMAX_CONCRETE_STRING_SIZE? + MAX_CONCRETE_STRING_SIZE:concretize_limit; + exprt content_expr=str.content(); + replace_expr(current_model, content_expr); + for(size_t i=0; i &pair : non_string_axioms) + { + replace_expr(symbol_resolve, pair.first); + debug() << "super::set_to " << from_expr(pair.first) << eom; + supert::set_to(pair.first, pair.second); + } + + for(exprt &axiom : generator.axioms) + { + replace_expr(symbol_resolve, axiom); if(axiom.id()==ID_string_constraint) { string_constraintt c=to_string_constraint(axiom); @@ -282,6 +494,7 @@ decision_proceduret::resultt string_refinementt::dec_solve() { add_lemma(axiom); } + } initial_index_set(universal_axioms); update_index_set(cur); @@ -302,6 +515,7 @@ decision_proceduret::resultt string_refinementt::dec_solve() else { debug() << "check_SAT: the model is correct" << eom; + concretize_lengths(); return D_SATISFIABLE; } @@ -318,7 +532,13 @@ decision_proceduret::resultt string_refinementt::dec_solve() if(current_index_set.empty()) { debug() << "current index set is empty" << eom; - return D_SATISFIABLE; + if(do_concretizing) + { + concretize_results(); + do_concretizing=false; + } + else + return D_SATISFIABLE; } display_index_set(); @@ -367,131 +587,337 @@ bvt string_refinementt::convert_bool_bv(const exprt &boole, const exprt &orig) Function: string_refinementt::add_lemma - Inputs: a lemma + Inputs: a lemma and Boolean value stating whether the lemma should + be added to the index set. Purpose: add the given lemma to the solver \*******************************************************************/ -void string_refinementt::add_lemma(const exprt &lemma, bool add_to_index_set) +void string_refinementt::add_lemma( + const exprt &lemma, bool _simplify, bool add_to_index_set) { if(!seen_instances.insert(lemma).second) return; - if(lemma.is_true()) + if(add_to_index_set) + cur.push_back(lemma); + + exprt simple_lemma=lemma; + if(_simplify) + simplify(simple_lemma, ns); + + if(simple_lemma.is_true()) { +#if 0 debug() << "string_refinementt::add_lemma : tautology" << eom; +#endif return; } - debug() << "adding lemma " << from_expr(lemma) << eom; + debug() << "adding lemma " << from_expr(simple_lemma) << eom; - prop.l_set_to_true(convert(lemma)); - if(add_to_index_set) - cur.push_back(lemma); + prop.l_set_to_true(convert(simple_lemma)); } /*******************************************************************\ -Function: string_refinementt::string_of_array +Function: string_refinementt::get_array - Inputs: a constant array expression and a integer expression + Inputs: an expression representing an array and an expression + representing an integer - Outputs: a string + Outputs: an array expression or an array_of_exprt - Purpose: convert the content of a string to a more readable representation. - This should only be used for debbuging. + Purpose: get a model of an array and put it in a certain form. + If the size cannot be obtained or if it is too big, return an + empty array. \*******************************************************************/ -std::string string_refinementt::string_of_array( - const exprt &arr, const exprt &size) const +exprt string_refinementt::get_array(const exprt &arr, const exprt &size) const { - if(size.id()!=ID_constant) - return "string of unknown size"; + exprt arr_val=get_array(arr); + exprt size_val=supert::get(size); + size_val=simplify_expr(size_val, ns); + typet char_type=arr.type().subtype(); + typet index_type=size.type(); + array_typet empty_ret_type(char_type, from_integer(0, index_type)); + array_of_exprt empty_ret(from_integer(0, char_type), empty_ret_type); + + if(size_val.id()!=ID_constant) + { +#if 0 + debug() << "(sr::get_array) string of unknown size: " + << from_expr(size_val) << eom; +#endif + return empty_ret; + } + unsigned n; - if(to_unsigned_integer(to_constant_expr(size), n)) - n=0; + if(to_unsigned_integer(to_constant_expr(size_val), n)) + { +#if 0 + debug() << "(sr::get_array) size is not valid" << eom; +#endif + return empty_ret; + } + + array_typet ret_type(char_type, from_integer(n, index_type)); + array_exprt ret(ret_type); if(n>MAX_CONCRETE_STRING_SIZE) - return "very long string"; + { +#if 0 + debug() << "(sr::get_array) long string (size=" << n << ")" << eom; +#endif + return empty_ret; + } + if(n==0) - return "\"\""; + { +#if 0 + debug() << "(sr::get_array) empty string" << eom; +#endif + return empty_ret; + } - std::ostringstream buf; - buf << "\""; - exprt val=get(arr); + std::vector concrete_array(n); - if(val.id()=="array-list") + if(arr_val.id()=="array-list") { - for(size_t i=0; i(c); + exprt value=arr_val.operands()[i*2+1]; + to_unsigned_integer(to_constant_expr(value), concrete_array[idx]); } } } } + else if(arr_val.id()==ID_array) + { + for(size_t i=0; i=32) + result << (unsigned char) c; + else + { + result << "\\u" << std::hex << std::setw(4) << std::setfill('0') + << (unsigned int) c; + } + } + + return result.str(); +} + +/*******************************************************************\ - for(size_t i=0; i &m, bool negated) const + std::map &m, const typet &type, bool negated) const { exprt sum=nil_exprt(); mp_integer constants=0; typet index_type; if(m.empty()) - return nil_exprt(); + return from_integer(0, type); else index_type=m.begin()->first.type(); @@ -723,12 +1122,20 @@ exprt string_refinementt::sum_over_map( default: if(second>1) { - for(int i=0; isecond; i--) + if(sum.is_nil()) + sum=unary_minus_exprt(t); + else + sum=minus_exprt(sum, t); + for(int i=-1; i>second; i--) sum=minus_exprt(sum, t); } } @@ -755,7 +1162,7 @@ Function: string_refinementt::simplify_sum exprt string_refinementt::simplify_sum(const exprt &f) const { std::map map=map_representation_of_sum(f); - return sum_over_map(map); + return sum_over_map(map, f.type()); } /*******************************************************************\ @@ -800,7 +1207,7 @@ exprt string_refinementt::compute_inverse_function( } elems.erase(it); - return sum_over_map(elems, neg); + return sum_over_map(elems, f.type(), neg); } @@ -830,7 +1237,7 @@ Function: find_qvar Outputs: a Boolean - Purpose: looks for the symbol and return true if it is found + Purpose: look for the symbol and return true if it is found \*******************************************************************/ @@ -885,6 +1292,26 @@ Function: string_refinementt::initial_index_set and the upper bound minus one \*******************************************************************/ +void string_refinementt::add_to_index_set(const exprt &s, exprt i) +{ + simplify(i, ns); + if(i.id()==ID_constant) + { + mp_integer mpi; + to_integer(i, mpi); + if(mpi<0) + { + debug() << "add_to_index_set : ignoring negative number " << mpi << eom; + return; + } + } + if(index_set[s].insert(i).second) + { + debug() << "adding to index set of " << from_expr(s) + << ": " << from_expr(i) << eom; + current_index_set[s].insert(i); + } +} void string_refinementt::initial_index_set(const string_constraintt &axiom) { @@ -906,8 +1333,7 @@ void string_refinementt::initial_index_set(const string_constraintt &axiom) // if cur is of the form s[i] and no quantified variable appears in i if(!has_quant_var) { - current_index_set[s].insert(i); - index_set[s].insert(i); + add_to_index_set(s, i); } else { @@ -917,8 +1343,7 @@ void string_refinementt::initial_index_set(const string_constraintt &axiom) axiom.upper_bound(), from_integer(1, axiom.upper_bound().type())); replace_expr(qvar, kminus1, e); - current_index_set[s].insert(e); - index_set[s].insert(e); + add_to_index_set(s, e); } } else @@ -952,12 +1377,7 @@ void string_refinementt::update_index_set(const exprt &formula) const exprt &i=cur.op1(); assert(s.type().id()==ID_array); exprt simplified=simplify_sum(i); - if(index_set[s].insert(simplified).second) - { - debug() << "adding to index set of " << from_expr(s) - << ": " << from_expr(simplified) << eom; - current_index_set[s].insert(simplified); - } + add_to_index_set(s, simplified); } else { @@ -1014,19 +1434,18 @@ exprt find_index(const exprt &expr, const exprt &str) catch (exprt i) { return i; } } - /*******************************************************************\ Function: string_refinementt::instantiate - Inputs: an universaly quantified formula `axiom`, an array of char + Inputs: a universally quantified formula `axiom`, an array of char variable `str`, and an index expression `val`. - Outputs: substitute `qvar` the universaly quantified variable of `axiom`, by + Outputs: substitute `qvar` the universally quantified variable of `axiom`, by an index `val`, in `axiom`, so that the index used for `str` equals `val`. For instance, if `axiom` corresponds to - $\forall q. s[q+x]='a' && t[q]='b'$, `instantiate(axom,s,v)` would return - an expression for $s[v]='a' && t[v-x]='b'$. + $\forall q. s[q+x]='a' && t[q]='b'$, `instantiate(axom,s,v)` + would return an expression for $s[v]='a' && t[v-x]='b'$. \*******************************************************************/ @@ -1051,6 +1470,17 @@ exprt string_refinementt::instantiate( return implies_exprt(bounds, instance); } +/*******************************************************************\ + +Function: string_refinementt::instantiate_not_contains + + Inputs: a quantified formula representing `not_contains`, and a + list to which to add the created lemmas to + + Purpose: instantiate a quantified formula representing `not_contains` + by substituting the quantifiers and generating axioms + +\*******************************************************************/ void string_refinementt::instantiate_not_contains( const string_not_contains_constraintt &axiom, std::list &new_lemmas) @@ -1102,3 +1532,76 @@ void string_refinementt::instantiate_not_contains( new_lemmas.push_back(witness_bounds); } } + +/*******************************************************************\ + +Function: string_refinementt::substitute_array_lists() + + Inputs: an expression containing array-list expressions + + Outputs: an epression containing no array-list + + Purpose: replace array-lists by 'with' expressions + +\*******************************************************************/ + +exprt string_refinementt::substitute_array_lists(exprt expr) const +{ + for(size_t i=0; i=2); + typet &char_type=expr.operands()[1].type(); + array_typet arr_type(char_type, infinity_exprt(char_type)); + array_of_exprt new_arr(from_integer(0, char_type), + arr_type); + + with_exprt ret_expr(new_arr, + expr.operands()[0], + expr.operands()[1]); + + for(size_t i=2; isecond); + } + + ecopy=supert::get(ecopy); + + return substitute_array_lists(ecopy); +} diff --git a/src/solvers/refinement/string_refinement.h b/src/solvers/refinement/string_refinement.h index be0cd332bc3..252146f4620 100644 --- a/src/solvers/refinement/string_refinement.h +++ b/src/solvers/refinement/string_refinement.h @@ -14,6 +14,7 @@ Author: Alberto Griggio, alberto.griggio@gmail.com #define CPROVER_SOLVERS_REFINEMENT_STRING_REFINEMENT_H #include +#include #include #include @@ -27,30 +28,32 @@ Author: Alberto Griggio, alberto.griggio@gmail.com class string_refinementt: public bv_refinementt { public: - // refinement_bound is a bound on the number of refinement allowed string_refinementt( - const namespacet &_ns, propt &_prop, unsigned refinement_bound); + const namespacet &_ns, + propt &_prop, + unsigned refinement_bound); void set_mode(); // Should we use counter examples at each iteration? bool use_counter_example; - virtual std::string decision_procedure_text() const + bool do_concretizing; + + virtual std::string decision_procedure_text() const override { return "string refinement loop with "+prop.solver_text(); } static exprt is_positive(const exprt &x); + exprt get(const exprt &expr) const override; + protected: typedef std::set expr_sett; + typedef std::list exprt_listt; - virtual bvt convert_symbol(const exprt &expr); - virtual bvt convert_function_application( - const function_application_exprt &expr); - - decision_proceduret::resultt dec_solve(); + decision_proceduret::resultt dec_solve() override; bvt convert_bool_bv(const exprt &boole, const exprt &orig); @@ -60,6 +63,9 @@ class string_refinementt: public bv_refinementt unsigned initial_loop_bound; + // Is the current model correct + bool concrete_model; + string_constraint_generatort generator; // Simple constraints that have been given to the solver @@ -76,23 +82,42 @@ class string_refinementt: public bv_refinementt // Warning: this is indexed by array_expressions and not string expressions std::map current_index_set; std::map index_set; + replace_mapt symbol_resolve; + std::map reverse_symbol_resolve; + std::list> non_string_axioms; - void display_index_set(); + // Valuation in the current model of the symbols that have been created + // by the solver + replace_mapt current_model; - void add_lemma(const exprt &lemma, bool add_to_index_set=true); + void add_equivalence(const irep_idt & lhs, const exprt & rhs); - bool boolbv_set_equality_to_true(const equal_exprt &expr); + void display_index_set(); - literalt convert_rest(const exprt &expr); + void add_lemma(const exprt &lemma, + bool simplify=true, + bool add_to_index_set=true); - void add_instantiations(); + exprt substitute_function_applications(exprt expr); + typet substitute_java_string_types(typet type); + exprt substitute_java_strings(exprt expr); + void add_symbol_to_symbol_map(const exprt &lhs, const exprt &rhs); + bool is_char_array(const typet &type) const; + bool add_axioms_for_string_assigns(const exprt &lhs, const exprt &rhs); + void set_to(const exprt &expr, bool value) override; + void add_instantiations(); + void add_negation_of_constraint_to_solver( + const string_constraintt &axiom, supert &solver); + void fill_model(); bool check_axioms(); + void set_char_array_equality(const exprt &lhs, const exprt &rhs); void update_index_set(const exprt &formula); void update_index_set(const std::vector &cur); void initial_index_set(const string_constraintt &axiom); void initial_index_set(const std::vector &string_axioms); + void add_to_index_set(const exprt &s, exprt i); exprt instantiate( const string_constraintt &axiom, const exprt &str, const exprt &val); @@ -101,17 +126,26 @@ class string_refinementt: public bv_refinementt const string_not_contains_constraintt &axiom, std::list &new_lemmas); + exprt substitute_array_lists(exprt) const; + exprt compute_inverse_function( const exprt &qvar, const exprt &val, const exprt &f); std::map map_representation_of_sum(const exprt &f) const; - exprt sum_over_map(std::map &m, bool negated=false) const; + exprt sum_over_map( + std::map &m, const typet &type, bool negated=false) const; exprt simplify_sum(const exprt &f) const; - exprt get_array(const exprt &arr, const exprt &size); + void concretize_results(); + void concretize_lengths(); + // Length of char arrays found during concretization + std::map found_length; + + exprt get_array(const exprt &arr, const exprt &size) const; + exprt get_array(const exprt &arr) const; - std::string string_of_array(const exprt &arr, const exprt &size) const; + std::string string_of_array(const array_exprt &arr); }; #endif From db3d5d61da1797d2658c8c00f90dfcdfad5567a8 Mon Sep 17 00:00:00 2001 From: Joel Allred Date: Fri, 24 Feb 2017 17:36:40 +0000 Subject: [PATCH 10/10] Restructuration of tests on strings Add test java_intern Adapt test.desc to new output format Make more robust java tests. Add test for parseint. Correction in the hacks to use refined strings in C programs Add smoke tests for java string support Quick set of tests. Created by modifying the existing development tests. Longer tests are run when using 'make testall'. Format of java files was adapted. No change to the validation tests (written by Lucas Cordeiro). Update smoke tests Add a series of performance tests that check that the negation of the assertions found in the smoke tests indeed fail. Update java_char_array_init/test_init.class Add first fixed_bugs test For bug #95 Update test description with new option name String refinement option name has changed to --refine-strings Formatting in cprover-string-hack.h Move smoke tests to regression folder. Move fixed bugs tests to strings folder Move string perfomance tests to strings directory These are not really performance tests, only tests that are longer than the smoke tests. Adapt Makefile for new location of smoke tests --- regression/strings-smoke-tests/Makefile | 9 ++ .../java_append_char/test.desc | 7 ++ .../java_append_char/test_append_char.class | Bin 0 -> 999 bytes .../java_append_char/test_append_char.java | 17 ++++ .../java_append_int/test.desc | 7 ++ .../java_append_int/test_append_int.class | Bin 0 -> 842 bytes .../java_append_int/test_append_int.java | 11 +++ .../java_append_object/test.desc | 7 ++ .../test_append_object.class | Bin 0 -> 992 bytes .../test_append_object.java | 17 ++++ .../java_append_string/test.desc | 7 ++ .../test_append_string.class | Bin 0 -> 1032 bytes .../test_append_string.java | 14 ++++ .../strings-smoke-tests/java_case/test.desc | 7 ++ .../java_case/test_case.class | Bin 0 -> 865 bytes .../java_case/test_case.java | 12 +++ .../java_char_array/test.desc | 7 ++ .../java_char_array/test_char_array.class | Bin 0 -> 714 bytes .../java_char_array/test_char_array.java | 13 +++ .../java_char_array_init/test.desc | 7 ++ .../java_char_array_init/test_init.class | Bin 0 -> 1046 bytes .../java_char_array_init/test_init.java | 21 +++++ .../java_char_at/test.desc | 7 ++ .../java_char_at/test_char_at.class | Bin 0 -> 628 bytes .../java_char_at/test_char_at.java | 7 ++ .../java_code_point/test.desc | 7 ++ .../java_code_point/test_code_point.class | Bin 0 -> 999 bytes .../java_code_point/test_code_point.java | 14 ++++ .../java_compare/test.desc | 7 ++ .../java_compare/test_compare.class | Bin 0 -> 623 bytes .../java_compare/test_compare.java | 9 ++ .../strings-smoke-tests/java_concat/test.desc | 8 ++ .../java_concat/test_concat.class | Bin 0 -> 798 bytes .../java_concat/test_concat.java | 13 +++ .../java_contains/test.desc | 8 ++ .../java_contains/test_contains.class | Bin 0 -> 716 bytes .../java_contains/test_contains.java | 11 +++ .../strings-smoke-tests/java_delete/test.desc | 7 ++ .../java_delete/test_delete.class | Bin 0 -> 943 bytes .../java_delete/test_delete.java | 10 +++ .../java_delete_char_at/test.desc | 7 ++ .../test_delete_char_at.class | Bin 0 -> 867 bytes .../test_delete_char_at.java | 11 +++ .../strings-smoke-tests/java_empty/test.desc | 7 ++ .../java_empty/test_empty.class | Bin 0 -> 571 bytes .../java_empty/test_empty.java | 8 ++ .../java_endswith/test.desc | 8 ++ .../java_endswith/test_endswith.class | Bin 0 -> 711 bytes .../java_endswith/test_endswith.java | 12 +++ .../strings-smoke-tests/java_equal/test.desc | 8 ++ .../java_equal/test_equal.class | Bin 0 -> 725 bytes .../java_equal/test_equal.java | 11 +++ .../strings-smoke-tests/java_float/test.desc | 7 ++ .../java_float/test_float.class | Bin 0 -> 965 bytes .../java_float/test_float.java | 15 ++++ .../java_hash_code/test.desc | 8 ++ .../java_hash_code/test_hash_code.class | Bin 0 -> 650 bytes .../java_hash_code/test_hash_code.java | 11 +++ .../java_index_of/test.desc | 7 ++ .../java_index_of/test_index_of.class | Bin 0 -> 631 bytes .../java_index_of/test_index_of.java | 10 +++ .../java_index_of_char/test.desc | 7 ++ .../test_index_of_char.class | Bin 0 -> 614 bytes .../test_index_of_char.java | 10 +++ .../java_insert_char/test.desc | 7 ++ .../java_insert_char/test_insert_char.class | Bin 0 -> 811 bytes .../java_insert_char/test_insert_char.java | 10 +++ .../java_insert_char_array/test.desc | 7 ++ .../test_insert_char_array.class | Bin 0 -> 979 bytes .../test_insert_char_array.java | 14 ++++ .../java_insert_int/test.desc | 7 ++ .../java_insert_int/test_insert_int.class | Bin 0 -> 810 bytes .../java_insert_int/test_insert_int.java | 10 +++ .../.test_insert.java.swp | Bin 0 -> 12288 bytes .../java_insert_multiple/test.desc | 7 ++ .../test_insert_multiple.class | Bin 0 -> 898 bytes .../test_insert_multiple.java | 11 +++ .../java_insert_string/test.desc | 7 ++ .../test_insert_string.class | Bin 0 -> 841 bytes .../test_insert_string.java | 10 +++ .../java_int_to_string/test.desc | 7 ++ .../java_int_to_string/test_int.class | Bin 0 -> 859 bytes .../java_int_to_string/test_int.java | 11 +++ .../strings-smoke-tests/java_intern/test.desc | 7 ++ .../java_intern/test_intern.class | Bin 0 -> 634 bytes .../java_intern/test_intern.java | 11 +++ .../java_last_index_of/test.desc | 7 ++ .../test_last_index_of.class | Bin 0 -> 647 bytes .../test_last_index_of.java | 10 +++ .../java_last_index_of_char/test.desc | 7 ++ .../test_last_index_of_char.class | Bin 0 -> 623 bytes .../test_last_index_of_char.java | 9 ++ .../strings-smoke-tests/java_length/test.desc | 7 ++ .../java_length/test_length.class | Bin 0 -> 630 bytes .../java_length/test_length.java | 9 ++ .../java_parseint/test.desc | 8 ++ .../java_parseint/test_parseint.class | Bin 0 -> 727 bytes .../java_parseint/test_parseint.java | 10 +++ .../java_replace/test.desc | 7 ++ .../java_replace/test_replace.class | Bin 0 -> 980 bytes .../java_replace/test_replace.java | 13 +++ .../java_replace_char/test.desc | 7 ++ .../java_replace_char/test_replace_char.class | Bin 0 -> 730 bytes .../java_replace_char/test_replace_char.java | 9 ++ .../java_set_char_at/test.desc | 7 ++ .../java_set_char_at/test_set_char_at.class | Bin 0 -> 874 bytes .../java_set_char_at/test_set_char_at.java | 13 +++ .../java_set_length/test.desc | 9 ++ .../java_set_length/test_set_length.class | Bin 0 -> 861 bytes .../java_set_length/test_set_length.java | 12 +++ .../java_starts_with/test.desc | 8 ++ .../java_starts_with/test_starts_with.class | Bin 0 -> 719 bytes .../java_starts_with/test_starts_with.java | 11 +++ .../java_string_builder_length/test.desc | 7 ++ .../test_sb_length.class | Bin 0 -> 722 bytes .../test_sb_length.java | 9 ++ .../java_subsequence/test.desc | 7 ++ .../java_subsequence/test_subsequence.class | Bin 0 -> 789 bytes .../java_subsequence/test_subsequence.java | 14 ++++ .../java_substring/test.desc | 7 ++ .../java_substring/test_substring.class | Bin 0 -> 740 bytes .../java_substring/test_substring.java | 14 ++++ .../strings-smoke-tests/java_trim/test.desc | 8 ++ .../java_trim/test_trim.class | Bin 0 -> 641 bytes .../java_trim/test_trim.java | 9 ++ regression/strings/RegexMatches01/test.desc | 2 +- regression/strings/RegexMatches02/test.desc | 2 +- .../strings/RegexSubstitution01/test.desc | 2 +- .../strings/RegexSubstitution02/test.desc | 2 +- .../strings/RegexSubstitution03/test.desc | 2 +- .../strings/StaticCharMethods01/test.desc | 2 +- .../strings/StaticCharMethods02/test.desc | 2 +- .../strings/StaticCharMethods03/test.desc | 2 +- .../strings/StaticCharMethods04/test.desc | 2 +- .../strings/StaticCharMethods05/test.desc | 2 +- .../strings/StaticCharMethods06/test.desc | 2 +- .../strings/StringBuilderAppend01/test.desc | 2 +- .../strings/StringBuilderAppend02/test.desc | 2 +- .../strings/StringBuilderCapLen01/test.desc | 2 +- .../strings/StringBuilderCapLen02/test.desc | 2 +- .../strings/StringBuilderCapLen03/test.desc | 2 +- .../strings/StringBuilderCapLen04/test.desc | 2 +- .../strings/StringBuilderChars01/test.desc | 2 +- .../strings/StringBuilderChars02/test.desc | 2 +- .../strings/StringBuilderChars03/test.desc | 2 +- .../strings/StringBuilderChars04/test.desc | 2 +- .../strings/StringBuilderChars05/test.desc | 2 +- .../strings/StringBuilderChars06/test.desc | 2 +- .../StringBuilderConstructors01/test.desc | 2 +- .../StringBuilderConstructors02/test.desc | 2 +- .../StringBuilderInsertDelete01/test.desc | 2 +- .../StringBuilderInsertDelete02/test.desc | 2 +- .../StringBuilderInsertDelete03/test.desc | 2 +- regression/strings/StringCompare01/test.desc | 2 +- regression/strings/StringCompare02/test.desc | 2 +- regression/strings/StringCompare03/test.desc | 2 +- regression/strings/StringCompare04/test.desc | 2 +- regression/strings/StringCompare05/test.desc | 2 +- .../strings/StringConcatenation01/test.desc | 2 +- .../strings/StringConcatenation02/test.desc | 2 +- .../strings/StringConcatenation03/test.desc | 2 +- .../strings/StringConcatenation04/test.desc | 2 +- .../strings/StringConstructors01/test.desc | 2 +- .../strings/StringConstructors02/test.desc | 2 +- .../strings/StringConstructors03/test.desc | 2 +- .../strings/StringConstructors04/test.desc | 2 +- .../strings/StringConstructors05/test.desc | 2 +- .../strings/StringIndexMethods01/test.desc | 2 +- .../strings/StringIndexMethods02/test.desc | 2 +- .../strings/StringIndexMethods03/test.desc | 2 +- .../strings/StringIndexMethods04/test.desc | 2 +- .../strings/StringIndexMethods05/test.desc | 2 +- .../strings/StringMiscellaneous01/test.desc | 2 +- .../strings/StringMiscellaneous02/test.desc | 2 +- .../strings/StringMiscellaneous03/test.desc | 2 +- .../strings/StringMiscellaneous04/test.desc | 2 +- regression/strings/StringStartEnd01/test.desc | 2 +- regression/strings/StringStartEnd02/test.desc | 2 +- regression/strings/StringStartEnd03/test.desc | 2 +- regression/strings/StringValueOf01/test.desc | 2 +- regression/strings/StringValueOf02/test.desc | 2 +- regression/strings/StringValueOf03/test.desc | 2 +- regression/strings/StringValueOf04/test.desc | 2 +- regression/strings/StringValueOf05/test.desc | 2 +- regression/strings/StringValueOf06/test.desc | 2 +- regression/strings/StringValueOf07/test.desc | 2 +- regression/strings/StringValueOf08/test.desc | 2 +- regression/strings/StringValueOf09/test.desc | 2 +- regression/strings/StringValueOf10/test.desc | 2 +- regression/strings/SubString01/test.desc | 2 +- regression/strings/SubString02/test.desc | 2 +- regression/strings/SubString03/test.desc | 2 +- regression/strings/TokenTest01/test.desc | 2 +- regression/strings/TokenTest02/test.desc | 2 +- regression/strings/Validate01/test.desc | 2 +- regression/strings/Validate02/test.desc | 2 +- .../strings/bug-test-gen-095/test.class | Bin 0 -> 822 bytes regression/strings/bug-test-gen-095/test.desc | 7 ++ regression/strings/bug-test-gen-095/test.java | 10 +++ regression/strings/cprover-string-hack.h | 77 ++++++++++++------ regression/strings/java_append_char/test.desc | 7 ++ .../java_append_char/test_append_char.class | Bin 0 -> 999 bytes .../java_append_char/test_append_char.java | 17 ++++ regression/strings/java_append_int/test.desc | 7 ++ .../java_append_int/test_append_int.class | Bin 0 -> 842 bytes .../java_append_int/test_append_int.java | 11 +++ .../strings/java_append_object/test.desc | 7 ++ .../test_append_object.class | Bin 0 -> 992 bytes .../test_append_object.java | 17 ++++ .../strings/java_append_string/test.desc | 7 ++ .../test_append_string.class | Bin 0 -> 1032 bytes .../test_append_string.java | 14 ++++ regression/strings/java_case/test.desc | 7 +- regression/strings/java_case/test_case.class | Bin 1073 -> 839 bytes regression/strings/java_case/test_case.java | 26 +++--- regression/strings/java_char_array/test.desc | 6 +- .../java_char_array/test_char_array.class | Bin 820 -> 676 bytes .../java_char_array/test_char_array.java | 26 +++--- .../strings/java_char_array_init/test.desc | 8 +- .../java_char_array_init/test_init.class | Bin 1209 -> 836 bytes .../java_char_array_init/test_init.java | 33 ++++---- regression/strings/java_char_at/test.desc | 6 +- .../strings/java_char_at/test_char_at.class | Bin 951 -> 628 bytes .../strings/java_char_at/test_char_at.java | 18 +--- regression/strings/java_code_point/test.desc | 10 +-- .../java_code_point/test_code_point.class | Bin 1025 -> 941 bytes .../java_code_point/test_code_point.java | 25 +++--- regression/strings/java_compare/test.desc | 7 +- .../strings/java_compare/test_compare.class | Bin 780 -> 623 bytes .../strings/java_compare/test_compare.java | 25 ++---- regression/strings/java_concat/test.desc | 6 +- .../strings/java_concat/test_concat.class | Bin 854 -> 798 bytes .../strings/java_concat/test_concat.java | 23 +++--- regression/strings/java_contains/test.desc | 5 +- .../strings/java_contains/test_contains.class | Bin 753 -> 671 bytes .../strings/java_contains/test_contains.java | 17 ++-- regression/strings/java_delete/test.desc | 5 +- .../strings/java_delete/test_delete.class | Bin 1126 -> 800 bytes .../strings/java_delete/test_delete.java | 23 ++---- .../strings/java_delete_char_at/test.desc | 7 ++ .../test_delete_char_at.class | Bin 0 -> 867 bytes .../test_delete_char_at.java | 11 +++ .../strings/java_easychair/easychair.class | Bin 1164 -> 1163 bytes .../strings/java_easychair/easychair.java | 62 +++++++------- regression/strings/java_easychair/test.desc | 6 +- regression/strings/java_empty/test.desc | 5 +- .../strings/java_empty/test_empty.class | Bin 669 -> 571 bytes regression/strings/java_empty/test_empty.java | 13 +-- regression/strings/java_endswith/test.desc | 7 ++ .../strings/java_endswith/test_endswith.class | Bin 0 -> 666 bytes .../strings/java_endswith/test_endswith.java | 9 ++ regression/strings/java_equal/test.desc | 5 +- .../strings/java_equal/test_equal.class | Bin 726 -> 725 bytes regression/strings/java_equal/test_equal.java | 17 ++-- regression/strings/java_float/test.desc | 7 +- .../strings/java_float/test_float.class | Bin 1095 -> 1015 bytes regression/strings/java_float/test_float.java | 35 ++++---- regression/strings/java_hash_code/test.desc | 7 ++ .../java_hash_code/test_hash_code.class | Bin 0 -> 602 bytes .../java_hash_code/test_hash_code.java | 9 ++ regression/strings/java_index_of/test.desc | 13 +-- .../strings/java_index_of/test_index_of.class | Bin 1108 -> 631 bytes .../strings/java_index_of/test_index_of.java | 40 ++------- .../strings/java_index_of_char/test.desc | 7 ++ .../test_index_of_char.class | Bin 0 -> 614 bytes .../test_index_of_char.java | 10 +++ .../strings/java_insert/test_insert.class | Bin 1318 -> 0 bytes .../strings/java_insert/test_insert.java | 19 ----- .../strings/java_insert/test_insert1.class | Bin 1035 -> 0 bytes .../strings/java_insert/test_insert1.java | 23 ------ regression/strings/java_insert_char/test.desc | 7 ++ .../java_insert_char/test_insert_char.class | Bin 0 -> 811 bytes .../java_insert_char/test_insert_char.java | 10 +++ .../strings/java_insert_char_array/test.desc | 7 ++ .../test_insert_char_array.class | Bin 0 -> 979 bytes .../test_insert_char_array.java | 14 ++++ regression/strings/java_insert_int/test.desc | 7 ++ .../java_insert_int/test_insert_int.class | Bin 0 -> 810 bytes .../java_insert_int/test_insert_int.java | 10 +++ .../strings/java_insert_multiple/test.desc | 7 ++ .../test_insert_multiple.class | Bin 0 -> 898 bytes .../test_insert_multiple.java | 11 +++ .../strings/java_insert_string/test.desc | 7 ++ .../test_insert_string.class | Bin 0 -> 841 bytes .../test_insert_string.java | 10 +++ regression/strings/java_int/test.desc | 13 --- regression/strings/java_int/test_int.class | Bin 1140 -> 0 bytes regression/strings/java_int/test_int.java | 25 ------ regression/strings/java_prefix/test.desc | 10 --- .../strings/java_prefix/test_prefix.class | Bin 933 -> 0 bytes .../strings/java_prefix/test_prefix.java | 23 ------ regression/strings/java_replace/test.desc | 8 -- .../strings/java_replace/test_replace.class | Bin 904 -> 0 bytes .../strings/java_replace/test_replace.java | 10 --- regression/strings/java_set_length/test.desc | 9 -- .../java_set_length/test_set_length.class | Bin 887 -> 0 bytes .../java_set_length/test_set_length.java | 12 --- .../strings/java_string_builder/test.desc | 9 -- .../test_string_builder.class | Bin 1003 -> 0 bytes .../test_string_builder.java | 16 ---- .../java_string_builder_insert/test.desc | 8 -- .../test_insert.class | Bin 1049 -> 0 bytes .../test_insert.java | 20 ----- .../java_string_builder_length/test.desc | 8 -- .../test_sb_length.class | Bin 791 -> 0 bytes .../test_sb_length.java | 11 --- regression/strings/java_strlen/test.desc | 8 -- .../strings/java_strlen/test_length.class | Bin 864 -> 0 bytes .../strings/java_strlen/test_length.java | 14 ---- regression/strings/java_substring/test.desc | 10 --- .../java_substring/test_substring.class | Bin 1051 -> 0 bytes .../java_substring/test_substring.java | 27 ------ regression/strings/java_suffix/test.desc | 8 -- .../strings/java_suffix/test_suffix.class | Bin 811 -> 0 bytes .../strings/java_suffix/test_suffix.java | 15 ---- regression/strings/java_trim/test.desc | 8 -- regression/strings/java_trim/test_trim.class | Bin 730 -> 0 bytes regression/strings/java_trim/test_trim.java | 8 -- regression/strings/test1/test.desc | 2 +- regression/strings/test2/test.desc | 2 +- regression/strings/test3.1/test.desc | 2 +- regression/strings/test3.2/test.desc | 2 +- regression/strings/test3.3/test.desc | 2 +- regression/strings/test3.4/test.desc | 8 +- regression/strings/test3/test.desc | 2 +- regression/strings/test4/test.desc | 2 +- regression/strings/test5/test.desc | 2 +- regression/strings/test_char_set/test.desc | 6 +- regression/strings/test_concat/test.desc | 2 +- regression/strings/test_contains/test.desc | 2 +- regression/strings/test_equal/test.desc | 6 +- regression/strings/test_index_of/test.desc | 2 +- regression/strings/test_int/test.desc | 2 +- regression/strings/test_pass1/test.desc | 2 +- regression/strings/test_pass_pc3/test.desc | 2 +- regression/strings/test_prefix/test.desc | 2 +- regression/strings/test_strlen/test.desc | 2 +- regression/strings/test_substring/test.desc | 10 +-- regression/strings/test_suffix/test.desc | 2 +- 339 files changed, 1389 insertions(+), 738 deletions(-) create mode 100644 regression/strings-smoke-tests/Makefile create mode 100644 regression/strings-smoke-tests/java_append_char/test.desc create mode 100644 regression/strings-smoke-tests/java_append_char/test_append_char.class create mode 100644 regression/strings-smoke-tests/java_append_char/test_append_char.java create mode 100644 regression/strings-smoke-tests/java_append_int/test.desc create mode 100644 regression/strings-smoke-tests/java_append_int/test_append_int.class create mode 100644 regression/strings-smoke-tests/java_append_int/test_append_int.java create mode 100644 regression/strings-smoke-tests/java_append_object/test.desc create mode 100644 regression/strings-smoke-tests/java_append_object/test_append_object.class create mode 100644 regression/strings-smoke-tests/java_append_object/test_append_object.java create mode 100644 regression/strings-smoke-tests/java_append_string/test.desc create mode 100644 regression/strings-smoke-tests/java_append_string/test_append_string.class create mode 100644 regression/strings-smoke-tests/java_append_string/test_append_string.java create mode 100644 regression/strings-smoke-tests/java_case/test.desc create mode 100644 regression/strings-smoke-tests/java_case/test_case.class create mode 100644 regression/strings-smoke-tests/java_case/test_case.java create mode 100644 regression/strings-smoke-tests/java_char_array/test.desc create mode 100644 regression/strings-smoke-tests/java_char_array/test_char_array.class create mode 100644 regression/strings-smoke-tests/java_char_array/test_char_array.java create mode 100644 regression/strings-smoke-tests/java_char_array_init/test.desc create mode 100644 regression/strings-smoke-tests/java_char_array_init/test_init.class create mode 100644 regression/strings-smoke-tests/java_char_array_init/test_init.java create mode 100644 regression/strings-smoke-tests/java_char_at/test.desc create mode 100644 regression/strings-smoke-tests/java_char_at/test_char_at.class create mode 100644 regression/strings-smoke-tests/java_char_at/test_char_at.java create mode 100644 regression/strings-smoke-tests/java_code_point/test.desc create mode 100644 regression/strings-smoke-tests/java_code_point/test_code_point.class create mode 100644 regression/strings-smoke-tests/java_code_point/test_code_point.java create mode 100644 regression/strings-smoke-tests/java_compare/test.desc create mode 100644 regression/strings-smoke-tests/java_compare/test_compare.class create mode 100644 regression/strings-smoke-tests/java_compare/test_compare.java create mode 100644 regression/strings-smoke-tests/java_concat/test.desc create mode 100644 regression/strings-smoke-tests/java_concat/test_concat.class create mode 100644 regression/strings-smoke-tests/java_concat/test_concat.java create mode 100644 regression/strings-smoke-tests/java_contains/test.desc create mode 100644 regression/strings-smoke-tests/java_contains/test_contains.class create mode 100644 regression/strings-smoke-tests/java_contains/test_contains.java create mode 100644 regression/strings-smoke-tests/java_delete/test.desc create mode 100644 regression/strings-smoke-tests/java_delete/test_delete.class create mode 100644 regression/strings-smoke-tests/java_delete/test_delete.java create mode 100644 regression/strings-smoke-tests/java_delete_char_at/test.desc create mode 100644 regression/strings-smoke-tests/java_delete_char_at/test_delete_char_at.class create mode 100644 regression/strings-smoke-tests/java_delete_char_at/test_delete_char_at.java create mode 100644 regression/strings-smoke-tests/java_empty/test.desc create mode 100644 regression/strings-smoke-tests/java_empty/test_empty.class create mode 100644 regression/strings-smoke-tests/java_empty/test_empty.java create mode 100644 regression/strings-smoke-tests/java_endswith/test.desc create mode 100644 regression/strings-smoke-tests/java_endswith/test_endswith.class create mode 100644 regression/strings-smoke-tests/java_endswith/test_endswith.java create mode 100644 regression/strings-smoke-tests/java_equal/test.desc create mode 100644 regression/strings-smoke-tests/java_equal/test_equal.class create mode 100644 regression/strings-smoke-tests/java_equal/test_equal.java create mode 100644 regression/strings-smoke-tests/java_float/test.desc create mode 100644 regression/strings-smoke-tests/java_float/test_float.class create mode 100644 regression/strings-smoke-tests/java_float/test_float.java create mode 100644 regression/strings-smoke-tests/java_hash_code/test.desc create mode 100644 regression/strings-smoke-tests/java_hash_code/test_hash_code.class create mode 100644 regression/strings-smoke-tests/java_hash_code/test_hash_code.java create mode 100644 regression/strings-smoke-tests/java_index_of/test.desc create mode 100644 regression/strings-smoke-tests/java_index_of/test_index_of.class create mode 100644 regression/strings-smoke-tests/java_index_of/test_index_of.java create mode 100644 regression/strings-smoke-tests/java_index_of_char/test.desc create mode 100644 regression/strings-smoke-tests/java_index_of_char/test_index_of_char.class create mode 100644 regression/strings-smoke-tests/java_index_of_char/test_index_of_char.java create mode 100644 regression/strings-smoke-tests/java_insert_char/test.desc create mode 100644 regression/strings-smoke-tests/java_insert_char/test_insert_char.class create mode 100644 regression/strings-smoke-tests/java_insert_char/test_insert_char.java create mode 100644 regression/strings-smoke-tests/java_insert_char_array/test.desc create mode 100644 regression/strings-smoke-tests/java_insert_char_array/test_insert_char_array.class create mode 100644 regression/strings-smoke-tests/java_insert_char_array/test_insert_char_array.java create mode 100644 regression/strings-smoke-tests/java_insert_int/test.desc create mode 100644 regression/strings-smoke-tests/java_insert_int/test_insert_int.class create mode 100644 regression/strings-smoke-tests/java_insert_int/test_insert_int.java create mode 100644 regression/strings-smoke-tests/java_insert_multiple/.test_insert.java.swp create mode 100644 regression/strings-smoke-tests/java_insert_multiple/test.desc create mode 100644 regression/strings-smoke-tests/java_insert_multiple/test_insert_multiple.class create mode 100644 regression/strings-smoke-tests/java_insert_multiple/test_insert_multiple.java create mode 100644 regression/strings-smoke-tests/java_insert_string/test.desc create mode 100644 regression/strings-smoke-tests/java_insert_string/test_insert_string.class create mode 100644 regression/strings-smoke-tests/java_insert_string/test_insert_string.java create mode 100644 regression/strings-smoke-tests/java_int_to_string/test.desc create mode 100644 regression/strings-smoke-tests/java_int_to_string/test_int.class create mode 100644 regression/strings-smoke-tests/java_int_to_string/test_int.java create mode 100644 regression/strings-smoke-tests/java_intern/test.desc create mode 100644 regression/strings-smoke-tests/java_intern/test_intern.class create mode 100644 regression/strings-smoke-tests/java_intern/test_intern.java create mode 100644 regression/strings-smoke-tests/java_last_index_of/test.desc create mode 100644 regression/strings-smoke-tests/java_last_index_of/test_last_index_of.class create mode 100644 regression/strings-smoke-tests/java_last_index_of/test_last_index_of.java create mode 100644 regression/strings-smoke-tests/java_last_index_of_char/test.desc create mode 100644 regression/strings-smoke-tests/java_last_index_of_char/test_last_index_of_char.class create mode 100644 regression/strings-smoke-tests/java_last_index_of_char/test_last_index_of_char.java create mode 100644 regression/strings-smoke-tests/java_length/test.desc create mode 100644 regression/strings-smoke-tests/java_length/test_length.class create mode 100644 regression/strings-smoke-tests/java_length/test_length.java create mode 100644 regression/strings-smoke-tests/java_parseint/test.desc create mode 100644 regression/strings-smoke-tests/java_parseint/test_parseint.class create mode 100644 regression/strings-smoke-tests/java_parseint/test_parseint.java create mode 100644 regression/strings-smoke-tests/java_replace/test.desc create mode 100644 regression/strings-smoke-tests/java_replace/test_replace.class create mode 100644 regression/strings-smoke-tests/java_replace/test_replace.java create mode 100644 regression/strings-smoke-tests/java_replace_char/test.desc create mode 100644 regression/strings-smoke-tests/java_replace_char/test_replace_char.class create mode 100644 regression/strings-smoke-tests/java_replace_char/test_replace_char.java create mode 100644 regression/strings-smoke-tests/java_set_char_at/test.desc create mode 100644 regression/strings-smoke-tests/java_set_char_at/test_set_char_at.class create mode 100644 regression/strings-smoke-tests/java_set_char_at/test_set_char_at.java create mode 100644 regression/strings-smoke-tests/java_set_length/test.desc create mode 100644 regression/strings-smoke-tests/java_set_length/test_set_length.class create mode 100644 regression/strings-smoke-tests/java_set_length/test_set_length.java create mode 100644 regression/strings-smoke-tests/java_starts_with/test.desc create mode 100644 regression/strings-smoke-tests/java_starts_with/test_starts_with.class create mode 100644 regression/strings-smoke-tests/java_starts_with/test_starts_with.java create mode 100644 regression/strings-smoke-tests/java_string_builder_length/test.desc create mode 100644 regression/strings-smoke-tests/java_string_builder_length/test_sb_length.class create mode 100644 regression/strings-smoke-tests/java_string_builder_length/test_sb_length.java create mode 100644 regression/strings-smoke-tests/java_subsequence/test.desc create mode 100644 regression/strings-smoke-tests/java_subsequence/test_subsequence.class create mode 100644 regression/strings-smoke-tests/java_subsequence/test_subsequence.java create mode 100644 regression/strings-smoke-tests/java_substring/test.desc create mode 100644 regression/strings-smoke-tests/java_substring/test_substring.class create mode 100644 regression/strings-smoke-tests/java_substring/test_substring.java create mode 100644 regression/strings-smoke-tests/java_trim/test.desc create mode 100644 regression/strings-smoke-tests/java_trim/test_trim.class create mode 100644 regression/strings-smoke-tests/java_trim/test_trim.java create mode 100644 regression/strings/bug-test-gen-095/test.class create mode 100644 regression/strings/bug-test-gen-095/test.desc create mode 100644 regression/strings/bug-test-gen-095/test.java create mode 100644 regression/strings/java_append_char/test.desc create mode 100644 regression/strings/java_append_char/test_append_char.class create mode 100644 regression/strings/java_append_char/test_append_char.java create mode 100644 regression/strings/java_append_int/test.desc create mode 100644 regression/strings/java_append_int/test_append_int.class create mode 100644 regression/strings/java_append_int/test_append_int.java create mode 100644 regression/strings/java_append_object/test.desc create mode 100644 regression/strings/java_append_object/test_append_object.class create mode 100644 regression/strings/java_append_object/test_append_object.java create mode 100644 regression/strings/java_append_string/test.desc create mode 100644 regression/strings/java_append_string/test_append_string.class create mode 100644 regression/strings/java_append_string/test_append_string.java create mode 100644 regression/strings/java_delete_char_at/test.desc create mode 100644 regression/strings/java_delete_char_at/test_delete_char_at.class create mode 100644 regression/strings/java_delete_char_at/test_delete_char_at.java create mode 100644 regression/strings/java_endswith/test.desc create mode 100644 regression/strings/java_endswith/test_endswith.class create mode 100644 regression/strings/java_endswith/test_endswith.java create mode 100644 regression/strings/java_hash_code/test.desc create mode 100644 regression/strings/java_hash_code/test_hash_code.class create mode 100644 regression/strings/java_hash_code/test_hash_code.java create mode 100644 regression/strings/java_index_of_char/test.desc create mode 100644 regression/strings/java_index_of_char/test_index_of_char.class create mode 100644 regression/strings/java_index_of_char/test_index_of_char.java delete mode 100644 regression/strings/java_insert/test_insert.class delete mode 100644 regression/strings/java_insert/test_insert.java delete mode 100644 regression/strings/java_insert/test_insert1.class delete mode 100644 regression/strings/java_insert/test_insert1.java create mode 100644 regression/strings/java_insert_char/test.desc create mode 100644 regression/strings/java_insert_char/test_insert_char.class create mode 100644 regression/strings/java_insert_char/test_insert_char.java create mode 100644 regression/strings/java_insert_char_array/test.desc create mode 100644 regression/strings/java_insert_char_array/test_insert_char_array.class create mode 100644 regression/strings/java_insert_char_array/test_insert_char_array.java create mode 100644 regression/strings/java_insert_int/test.desc create mode 100644 regression/strings/java_insert_int/test_insert_int.class create mode 100644 regression/strings/java_insert_int/test_insert_int.java create mode 100644 regression/strings/java_insert_multiple/test.desc create mode 100644 regression/strings/java_insert_multiple/test_insert_multiple.class create mode 100644 regression/strings/java_insert_multiple/test_insert_multiple.java create mode 100644 regression/strings/java_insert_string/test.desc create mode 100644 regression/strings/java_insert_string/test_insert_string.class create mode 100644 regression/strings/java_insert_string/test_insert_string.java delete mode 100644 regression/strings/java_int/test.desc delete mode 100644 regression/strings/java_int/test_int.class delete mode 100644 regression/strings/java_int/test_int.java delete mode 100644 regression/strings/java_prefix/test.desc delete mode 100644 regression/strings/java_prefix/test_prefix.class delete mode 100644 regression/strings/java_prefix/test_prefix.java delete mode 100644 regression/strings/java_replace/test.desc delete mode 100644 regression/strings/java_replace/test_replace.class delete mode 100644 regression/strings/java_replace/test_replace.java delete mode 100644 regression/strings/java_set_length/test.desc delete mode 100644 regression/strings/java_set_length/test_set_length.class delete mode 100644 regression/strings/java_set_length/test_set_length.java delete mode 100644 regression/strings/java_string_builder/test.desc delete mode 100644 regression/strings/java_string_builder/test_string_builder.class delete mode 100644 regression/strings/java_string_builder/test_string_builder.java delete mode 100644 regression/strings/java_string_builder_insert/test.desc delete mode 100644 regression/strings/java_string_builder_insert/test_insert.class delete mode 100644 regression/strings/java_string_builder_insert/test_insert.java delete mode 100644 regression/strings/java_string_builder_length/test.desc delete mode 100644 regression/strings/java_string_builder_length/test_sb_length.class delete mode 100644 regression/strings/java_string_builder_length/test_sb_length.java delete mode 100644 regression/strings/java_strlen/test.desc delete mode 100644 regression/strings/java_strlen/test_length.class delete mode 100644 regression/strings/java_strlen/test_length.java delete mode 100644 regression/strings/java_substring/test.desc delete mode 100644 regression/strings/java_substring/test_substring.class delete mode 100644 regression/strings/java_substring/test_substring.java delete mode 100644 regression/strings/java_suffix/test.desc delete mode 100644 regression/strings/java_suffix/test_suffix.class delete mode 100644 regression/strings/java_suffix/test_suffix.java delete mode 100644 regression/strings/java_trim/test.desc delete mode 100644 regression/strings/java_trim/test_trim.class delete mode 100644 regression/strings/java_trim/test_trim.java diff --git a/regression/strings-smoke-tests/Makefile b/regression/strings-smoke-tests/Makefile new file mode 100644 index 00000000000..c41ab1c5be8 --- /dev/null +++ b/regression/strings-smoke-tests/Makefile @@ -0,0 +1,9 @@ + +test: + @../test.pl -c ../../../src/cbmc/cbmc + +testfuture: + @../test.pl -c ../../../src/cbmc/cbmc -CF + +testall: + @../test.pl -c ../../../src/cbmc/cbmc -CFTK diff --git a/regression/strings-smoke-tests/java_append_char/test.desc b/regression/strings-smoke-tests/java_append_char/test.desc new file mode 100644 index 00000000000..0f1b3ae243f --- /dev/null +++ b/regression/strings-smoke-tests/java_append_char/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_append_char.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_append_char/test_append_char.class b/regression/strings-smoke-tests/java_append_char/test_append_char.class new file mode 100644 index 0000000000000000000000000000000000000000..00c40aef6f6514f718dc1137889e4124d8bd7230 GIT binary patch literal 999 zcmZWnYf}Wo2Pz(&a;H%@8%{2WMdqwzlljUYhBz_y_u& z&ES+xeeXwA?}3!mVR?7YbKcAIyzl$#_qQJa7O0Ha)#&34?)cGDMe5+w_+i!nyow z2BqW}f+4wP+F~PU)`a^?I@3i{H*JQ#vai?Qt?R80%uyg-9PEZyEIlzrEP5Y% z?TWh35ZWr8z`M+-Q(X}Z+1yqszt#&pLA^-ieCH@;ICs{OJpQX%{^3CdNX=QrVhY9OGl*1Mmr!w z93#iBU!l+sXz=fmYB*(7s!GbNR3oWIr5Yvkyo=W)Zb>|lxTvfhB2+y*hO46R8 z9~&f4khoFuN`w8OgTj&NJm)yh6CA^ZV;Kt_X~4i>UmN{<;L0Z`;V+2wDjunq86ya3 ME3!uy=@3HpFJ~^+h5!Hn literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_append_char/test_append_char.java b/regression/strings-smoke-tests/java_append_char/test_append_char.java new file mode 100644 index 00000000000..3eec4f30abe --- /dev/null +++ b/regression/strings-smoke-tests/java_append_char/test_append_char.java @@ -0,0 +1,17 @@ +public class test_append_char +{ + public static void main(/*String[] args*/) + { + char[] diff = {'d', 'i', 'f', 'f'}; + char[] blue = {'b', 'l', 'u', 'e'}; + + StringBuilder buffer = new StringBuilder(); + + buffer.append(diff) + .append(blue); + + String tmp=buffer.toString(); + System.out.println(tmp); + assert tmp.equals("diffblue"); + } +} diff --git a/regression/strings-smoke-tests/java_append_int/test.desc b/regression/strings-smoke-tests/java_append_int/test.desc new file mode 100644 index 00000000000..e1455859470 --- /dev/null +++ b/regression/strings-smoke-tests/java_append_int/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_append_int.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_append_int/test_append_int.class b/regression/strings-smoke-tests/java_append_int/test_append_int.class new file mode 100644 index 0000000000000000000000000000000000000000..16948397e03dc279cdae32b41c8692bcfbb44978 GIT binary patch literal 842 zcmaJfgc5Pjo(*l`@3rfC~W0~87*DQ!pza7cxK0upKphaf6?shoIKxwv+)9ezyy z0B1l-B`U$4{{&*zX&Rssmzmx9c<=4Z{`mFv8-OMr=rB=Maao6gvW6?tUzKKAnrj*4 za9zWSjvKhC;+BrAEU)OOqNZY%FuP)fp$H06*g4eQ`6GxWg5ptc#>b={s`f->gsklwhHhb= zJ{tlrC>n5r_qm5<{uw6!A%$q`b!HFbpaZfyj${TbR2#nnP)1bv9?39?*he3!UNjJwFlOa_g; z36*0S7MZ019SfYvf_|c*qNL(toSNut#)5#ELT-c$L#WA*NG85On_^EiOPmxGo@H<&=ME&u=k literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_append_int/test_append_int.java b/regression/strings-smoke-tests/java_append_int/test_append_int.java new file mode 100644 index 00000000000..963f3d7c063 --- /dev/null +++ b/regression/strings-smoke-tests/java_append_int/test_append_int.java @@ -0,0 +1,11 @@ +public class test_append_int +{ + public static void main(/*String[] args*/) + { + StringBuilder diffblue = new StringBuilder(); + diffblue.append("d"); + diffblue.append(4); + String s = diffblue.toString(); + assert s.equals("d4"); + } +} diff --git a/regression/strings-smoke-tests/java_append_object/test.desc b/regression/strings-smoke-tests/java_append_object/test.desc new file mode 100644 index 00000000000..5db2ac1db73 --- /dev/null +++ b/regression/strings-smoke-tests/java_append_object/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_append_object.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_append_object/test_append_object.class b/regression/strings-smoke-tests/java_append_object/test_append_object.class new file mode 100644 index 0000000000000000000000000000000000000000..ed6942a1fa6ddb20c36b528444d598e867e347f5 GIT binary patch literal 992 zcmZWn*>2N76g`t|9M@^mbPIb6p(Jh7u#`2SEAT>Ekb*$;rE=nF<>J`E3ld+!dwzgt zij+!Jf_FX&xZ{wfX=VG4=gygP&s~21`SBCLGB#C=VMf8Mg6kYNRKzeNOy5|YkHyzu1W_o(V5(Wd?VMtU>+w@l$ zqJ`pHhS;WK2!?dcw8eJNY6$m@1k*uFH*JPg-PfBRw)A%BCT`NjagRZ%Hm(0mYTXIk zrg&k>d(*z~{9V1>7PhhLG!8`5Upmk~=^7?5NwkK!w?|9E3M5#blr7!fFV}t7wD&gx z(=vpsQ8Dgocz}l-k2E~S6OM|8DxPY{Vw|E&8p%OgG^}8iAvfS!@8|y9bsd)>dtMXA znuc|3Fk}YzUWIapTs>J-wq8aIr9$oOg-Y?1YbcKjDfOK`$3)>gkPxQ?)IWQ^Xi;yR zz-O53(V9;AHPyx^8lku7!gwfP*v-J(5@b=&CQnQ31+U0nC&b4R*arn|^=z++z#i++bXh}h3bGR6_n)@0^aX%oS3C;sZb6 zvzWArB>L`05%-x=nuO#a7V$IhB!u~xT_+U z#5g82Rt39^(lGmdgsB>X^rZf@eAwv7}=eD^i=&(T@S*Y>9GN$12tsvh8v!tx;@v zp6f9fmsu)U*Rg@k4vw!6j(90x=+AApi#3VQ%h@HGjWSIAE8tSjc|Y?V7{$+iz$>&3 zwq1gq5#mx#O^o97HW(K7ygKXMT2g4@qkf9p5twCpU3$v|8snFx&xNnE=K{X(fx^1V1kWY>r`5PNxw_-+GtBn zT|1;t)}fyub&SlU(OpN+F}hBXrnKH)5-$?sjS&)&fJVp$6v9+-lWb#T$)gK1(6NOS zu2WPu*crAI3@NxlGK_4sGaK>-dJUtFzGEn{uZTszBh`j#wI)l&5z&|B0B+Gw1jBy- DqWB3A~sECS)t!#oa~!3s1iJ ztR|4yMBn{Ujc0ZRv^JTXnK|b>=ljl?`E~sL2Y@ObsYoF&vG34ZOeUXx<+Tfdkn125ZyK{(|gPy z6^d^d!gagH84?ZC;x9&r9qzmmUrp2(-^o;JiePigmNf?8&-5va?p*HQ2)8)@i zk+JM?*L&MFT)uf=d@wYmkzq)Rb7f#y{YukwOsmfj+Uba3MZ-9{$7mvU9+@9z&+kSdEEkp53rN za;HwR8PbK~|1cl)dN`bcqWt~H7`P{D21Hv$8gViJ?Dj3&;X&b3=?R)xh^i0h$r!Rd z?wSto&D*92@J1A%_iAH}K0%6p3QOk1$mk@2WFtd1OSe_p8SRnM6zq!t;tbiS@1$WN zH-~@)+r|u1pXcBYp(6HAVbq;NH-+)7&L}X@cdy z(1JhY^XDPcIYK`+N)5;)SV5W8)X3999A_z-gmjFujB~-tW(jkCuD0rT0HpN91j#Yv a@MnajZ;%%xvnEBc2twKuF^UVmhSlFL=B-Bn literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_case/test_case.java b/regression/strings-smoke-tests/java_case/test_case.java new file mode 100644 index 00000000000..b3437a6f83e --- /dev/null +++ b/regression/strings-smoke-tests/java_case/test_case.java @@ -0,0 +1,12 @@ +public class test_case +{ + public static void main(/*String[] argv*/) + { + String s = new String("Ab"); + String l = s.toLowerCase(); + String u = s.toUpperCase(); + assert(l.equals("ab")); + assert(u.equals("AB")); + assert(s.equalsIgnoreCase("aB")); + } +} diff --git a/regression/strings-smoke-tests/java_char_array/test.desc b/regression/strings-smoke-tests/java_char_array/test.desc new file mode 100644 index 00000000000..ecce56c1ab8 --- /dev/null +++ b/regression/strings-smoke-tests/java_char_array/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_char_array.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_char_array/test_char_array.class b/regression/strings-smoke-tests/java_char_array/test_char_array.class new file mode 100644 index 0000000000000000000000000000000000000000..0d2056042ca2ef3063d717972cfe8bf0f7b0d053 GIT binary patch literal 714 zcmZXR%Wl&^6o&t?9gpL zsgPK*2BcI1sqA?u;EbUOm(7`(|J=TF=G*trX8=05?ZQRP!6g@$aYdV@A{^8?uDY;M zAm|?D;iSXr9@hX=&Zg8wJI2+;UcNw>zj8!NfMLKCAlWBGkz7Xm_C?($9 zITEjhhdInsKQRa?-@{F;dANm!hY~!7nvPi?iTH56d(Qk&sYDUgKjk=@9$IKK__L&) z!I2EJzodSqqWF-(*zYlvvZO~qUCl#dHJVzqHDi~utj6Oez00$Dy%DXBVR0zaNXg-p zi58KK$w7PD!!m8&rEg(=O;15L6SOSMlP%M$PA8+Y&^iVCpabEPwR4f7h{`ndEeu%X z+o>8)S`(OC?Ly~X%bdX4{D{H{D(y4-9ZFwd@1BBx{iW4?@t?Njhkt0gsgXBbAyy(G zLYr=!XdP4uVT~rZOZ3~MR4F2W`GZ7@Bj8wIgdYSHdSOc1$?1Vg)tR7p0&cyBWqv|o U*6VygU9SMcyRX-9GGO8l5EOL`WQzE66TtyO1T~q{01u{YH(2aiY&)ZWg+BA* zqt9ZpC1Uj5KgdVoxt)xWm^SB}d(U^y{m$3h--q9S0+_)g4JnLpjB1GBf;1Ns7{etQ zUDj{~nFI`sb7VCnFd}y*;+T}_t8q+8pX0cu;X0-{ZZPzXnZ7T)z;Ydb!Sc;5TT~g? z21Bf1IaV;s5Y3FgU{H!~RWKx1Ek``5*S3WBT!JZ4GcAXqyA+s}H*4l@xXm#`BpKp` ziv6#RR&wiJMJ!pes3#D9@JeQ;cFcFCjsc_@3>oKa)7j3I0?%@`<^D}+ZgJe!aR+yG z+(VwDpyNJfb@ZX1Veq(Y{%Dv*&vQKqdcY77wvIW>GpNhLwp|?$QDjK8IdClKSj5r^ z22ZzkL?xi=O~R^~&7xF+lV4epQ76|AejsWjlv^kKz-maxa&ymUgn$MSW-U*8+QQim zUWa!(`wftN?slx6L0IL?bC6cfEMTcIDJ0N4@@ucUt03W z6QGu~At-sQT+ybBz>uyA-||GYEhK%`piT+81sfQp%ax*w$c#ZLJw;JaccjUlqSX+2 zMqbS}!M;i$2Fb?4O;Q}E+t5EysTlZVXg}1)*{HEx&MJl|XH~;4XJgWE!z~{mvQEvS zt6`w1O(<*oP$wFQHNf`~-$TD#7}{ra9U!sZg!Zci=pr}S067VoOz91D?{$L0+Eh;i z$&PKwIuf#;MUrBbo)|Q6TE%H(IfI5_bkVP+V;VguP^Lt}Y@in=$@8A1`AEn!RBa%7 zh!V$Hj&t;mrK!hITZ5TU7oay~G|;;Tu6%(K{f784i6iM`GZhhiP6|96ayK%)14Q&n}mKmr$g#`EUAH{(D5ZteiAqV6M)iiek3O!-J*I)@xy*=WYYtPjr? zU;CKDyoV}bd{M-))JAoq_=Ac?t0UV4IwEA&Riw-YAziC~Avle0TN1|hR3tz3E?QC_ zSTGkZgo+3wO(VkdkK$|c%mxVA^|156;WxWI9m;KGJBmie<~TeR`dFBEXX2X(Fp4ok z!Nw~c5uL0wjaJbKi;Grhs|x`Fj09N35}`80Z9cl+(z>e&!BcJzZvwnU?HTju)|m_q zpNZec+K=+eYVBr?2!&15rXZIJ}OO%)0Yh()H zcjRy39rls^ZHZC|(I__o4t%(%GVM5LSul S?9r7aaghq%TkjKz*5rTZxpr0n literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_char_at/test_char_at.java b/regression/strings-smoke-tests/java_char_at/test_char_at.java new file mode 100644 index 00000000000..3b8663d62ae --- /dev/null +++ b/regression/strings-smoke-tests/java_char_at/test_char_at.java @@ -0,0 +1,7 @@ +public class test_char_at { + + public static void main(/*String[] argv*/) { + String s = new String("abc"); + assert(s.charAt(2)=='c'); + } +} diff --git a/regression/strings-smoke-tests/java_code_point/test.desc b/regression/strings-smoke-tests/java_code_point/test.desc new file mode 100644 index 00000000000..012c7c3501b --- /dev/null +++ b/regression/strings-smoke-tests/java_code_point/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_code_point.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_code_point/test_code_point.class b/regression/strings-smoke-tests/java_code_point/test_code_point.class new file mode 100644 index 0000000000000000000000000000000000000000..1d5d2269325d6c4baed8f6c6f44326db9fc57985 GIT binary patch literal 999 zcmZuw+fEZv6kVsCOFJE)43|~`0Yz-7f+BbW2~ag@sF$QhBQIo_9&n({G&55ZUya5G zqaVPF#uuNxq$HB)yZ_)P@CU@W&q!NPU-rzbv-aA1?S1CQudm+#OkqxgfuR_N<4EG9 zhEo`cg2h!8r!^=T63D0sXGF-T$ZALkIDs*NPp=-qSeeMOe>-aZp z-(0QmG6P#?P-bn%4(1r5nd}1wDesm!Lr2ke_?_C;D);USG97H0w!_d?3QTMBwpk5f z73ZlsLu}Tn9LQ)Tx8_;=mMxOH1MUYa7D=vDUE2x9H_Rudjvn+f3=Z$Td$#xGWf-4_ z@ztUDLPr<6seq0Pm}E$c)QO7etWPX7tlacG*VAzklRAxUTE`_!Go)I~QsCLn`eMzl zlsOSE^x}tK2C!A%=buF18vvVrPbSXFWE(Mgw^g zXi@VOS~x>*nftcK%gvF|`hprA(6*N`O!v#6E60*)F>HFHdnUF+F-2bk^knpu$9BLz z3L?@Jl@Mfz<5-jWlTsse_Qr@TeL{2_J!4WGk|DoEVi(Gz9jMCVKkM3@B) zoAkSQ(D52=I8Lli$ouG1(U(f4_K{W5Pvn87)v3@v(Trpro!d~Q50Ijt5p7j#Oh~B7 Oi0JcTjwixq27d!;VcgOH literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_code_point/test_code_point.java b/regression/strings-smoke-tests/java_code_point/test_code_point.java new file mode 100644 index 00000000000..faf9a2051d5 --- /dev/null +++ b/regression/strings-smoke-tests/java_code_point/test_code_point.java @@ -0,0 +1,14 @@ +public class test_code_point +{ + public static void main(/*String[] argv*/) + { + String s = "!𐤇𐤄𐤋𐤋𐤅"; + assert(s.codePointAt(1) == 67847); + assert(s.codePointBefore(3) == 67847); + assert(s.codePointCount(1,5) >= 2); + assert(s.offsetByCodePoints(1,2) >= 3); + StringBuilder sb = new StringBuilder(); + sb.appendCodePoint(0x10907); + assert(s.charAt(1) == sb.charAt(0)); + } +} diff --git a/regression/strings-smoke-tests/java_compare/test.desc b/regression/strings-smoke-tests/java_compare/test.desc new file mode 100644 index 00000000000..38aa025f416 --- /dev/null +++ b/regression/strings-smoke-tests/java_compare/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_compare.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_compare/test_compare.class b/regression/strings-smoke-tests/java_compare/test_compare.class new file mode 100644 index 0000000000000000000000000000000000000000..3a807f4d203aecb2c12a4dab57637aeb3ded9359 GIT binary patch literal 623 zcmY*WO;6iE5Pjn~w&NH`%vTBxA1!SINaex}RJEcYA=37c2njCL##y1IiH+7ye+(Cn zoM|PHiqziuPgI?CA!)U%+1)oYZ{Ez_{r>S2z$O|#e9U^Nd3aKShdCefcB%mEjtS1TidFW8P-v_k66~F%D+v=#70Zu|@LS11M{-Y@jA|y+>~oa#&xDq*PsLXeU<~5~ zOLUCkXBh!g1bB`WLd}G1^hA8J@$OOVuGWbr1piXGcoE*OFyLUkD0g2fA12(5##(EJAb98+uS*C^T-DBr?4 zx`F%4a9BA<2%GOkF6i*$-)1QxBW2J%>MkaEGc+|Uu$dPHs-bs{(m7oF5_aJ`>=Eaq RF2hrV6}&a-r}L6Ce*kI)bz}el literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_compare/test_compare.java b/regression/strings-smoke-tests/java_compare/test_compare.java new file mode 100644 index 00000000000..c052ed429bd --- /dev/null +++ b/regression/strings-smoke-tests/java_compare/test_compare.java @@ -0,0 +1,9 @@ +public class test_compare +{ + public static void main(/*String[] argv*/) + { + String s1 = "ab"; + String s2 = "aa"; + assert(s1.compareTo(s2) == 1); + } +} diff --git a/regression/strings-smoke-tests/java_concat/test.desc b/regression/strings-smoke-tests/java_concat/test.desc new file mode 100644 index 00000000000..fb784efd723 --- /dev/null +++ b/regression/strings-smoke-tests/java_concat/test.desc @@ -0,0 +1,8 @@ +FUTURE +test_concat.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 10.* SUCCESS$ +^\[.*assertion.2\].* line 11.* FAILURE$ +-- diff --git a/regression/strings-smoke-tests/java_concat/test_concat.class b/regression/strings-smoke-tests/java_concat/test_concat.class new file mode 100644 index 0000000000000000000000000000000000000000..e4143c157737bffffa1af323a7918a12ba9a88e1 GIT binary patch literal 798 zcmZuvT~E_s6n;+Eu3cAP42MHR1aWQ?m>N(KXzlg$}NALZ(`KO;B4wR}iLl zTwm<TqMg{z+g&?M!_0 zwirRJZr56TzcEb9#GCkdu#Ip7!TCX z$eo~AQVZdGq3I-Q~5>`oJmtnB2@n4o@wmRn6Ut|&$j%*^27rf0ZSCpXq z;((^(GVv!Bcz}WOi0wwY0We*(2ADX3u6~4?`GVXS?R-f&QG;SVlBbwU$z1sjB)pi= literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_concat/test_concat.java b/regression/strings-smoke-tests/java_concat/test_concat.java new file mode 100644 index 00000000000..b9909c723d4 --- /dev/null +++ b/regression/strings-smoke-tests/java_concat/test_concat.java @@ -0,0 +1,13 @@ +public class test_concat +{ + public static void main(/*String[] argv*/) + { + String s = new String("pi"); + int i = s.length(); + String t = new String("ppo"); + String u = s.concat(t); + char c = u.charAt(i); + assert(c == 'p'); + assert(c == 'o'); + } +} diff --git a/regression/strings-smoke-tests/java_contains/test.desc b/regression/strings-smoke-tests/java_contains/test.desc new file mode 100644 index 00000000000..2b96346d718 --- /dev/null +++ b/regression/strings-smoke-tests/java_contains/test.desc @@ -0,0 +1,8 @@ +FUTURE +test_contains.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 8.* SUCCESS$ +^\[.*assertion.2\].* line 9.* FAILURE$ +-- diff --git a/regression/strings-smoke-tests/java_contains/test_contains.class b/regression/strings-smoke-tests/java_contains/test_contains.class new file mode 100644 index 0000000000000000000000000000000000000000..adf0ece000a23e9f4fd98803c8c74cbbf0aec72e GIT binary patch literal 716 zcmY*W!EVz)5Pf4OvEw)-aYzX*1qvli(n2r2H6W@07g9K+s?=W4+F2F1sSUQnkq^la za0aACq7vNssES#)Nr<$X-JLfx@6F8Lt6#qX?BJ<|B9;xTn7C&_!>WnrBm+|Wt&T##9O>Q z3;oKeI%Cf-p&dE;1ev!^w&&#bf4~@{+TOf?IY!|U`J)M}KR4d3MX#dJQi^3JVP05# z7h$j_6AdQpu&2gI3ECAJ29~Z*jo~{pEjy_`pyCuRV2@#Bz9FOkgfXu_Z9&z_LbG40 JM(Zj4-GA+{itGRY literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_contains/test_contains.java b/regression/strings-smoke-tests/java_contains/test_contains.java new file mode 100644 index 00000000000..5112c344c09 --- /dev/null +++ b/regression/strings-smoke-tests/java_contains/test_contains.java @@ -0,0 +1,11 @@ +public class test_contains +{ + public static void main(/*String[] argv*/) + { + String s = new String("Abc"); + String u = "bc"; + String t = "ab"; + assert(s.contains(u)); + assert(s.contains(t)); + } +} diff --git a/regression/strings-smoke-tests/java_delete/test.desc b/regression/strings-smoke-tests/java_delete/test.desc new file mode 100644 index 00000000000..27a1406cdb7 --- /dev/null +++ b/regression/strings-smoke-tests/java_delete/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_delete.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_delete/test_delete.class b/regression/strings-smoke-tests/java_delete/test_delete.class new file mode 100644 index 0000000000000000000000000000000000000000..f18891851b1e69aae1bc9416dd3316dab6c8e3b1 GIT binary patch literal 943 zcmZuv+iuf95IvjQ#*W+O+J-`aLV=_S4VRQ#0yHfkRZ0OV2-Na`9D7x{IB~HZBz`47 zz%xZkBr3r>{{&(-X_{Vm*|BHNoIP`Pe*gXP6F>!PD&n}raXE?w6#-n4$5nYOD!7L0 zDsCXJU>b!emQ)l`;<%|olRe8S%DBaGn<2HRd!BH8%jtN}EKhIQ!en6E43V1EvHT|t z!F=H@LulPG1;b3k>WG)!c1yT#B$x_q-RdyR=HEAV_0M|Q);l}prteyvovLh{YWlkI zaZ}$L;z=;a9foMlun+mwrqgu|@xqd9abI};2UFO>7t4}QLkekzxzpThUCTCwOY-V1 zLxS#VK*K{k;;3q<$w~rAhCtn*yEQxpO_iMx*2fM!cU^}VW5+abJk_v@ zIw_kpylU+V!#|N44a|_q|KEkkXe5SQeq*C>26H$~m5lM7F;_Z&7D$L=LYiMZU$n^s zr%Q4&BU;NTzb5y6q7izV8d5{$C({gkPl9ZEx`_DH)ot&T_|cHn0jU4ZyxhAZF=|43i8B z=8&at33aJ8NO9!=fvse4fKa0t3ilCySL`FQxes3IBf1Zzhjb~a_7UqLb^vW_fT>@S zIxwW3Cvv(ED#Zji<)WlQp^Z^-jw&&*Kd5lbbDXErg(Inzp(Y@aobF?$2Oj#0Q1CmH U3HMmGcd;12=iei~s-t literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_delete/test_delete.java b/regression/strings-smoke-tests/java_delete/test_delete.java new file mode 100644 index 00000000000..13bd09cd075 --- /dev/null +++ b/regression/strings-smoke-tests/java_delete/test_delete.java @@ -0,0 +1,10 @@ +public class test_delete +{ + public static void main(/*String[] argv*/) + { + StringBuilder s = new StringBuilder("Abc"); + s.delete(1,2); + String str = s.toString(); + assert(str.equals("Ac")); + } +} diff --git a/regression/strings-smoke-tests/java_delete_char_at/test.desc b/regression/strings-smoke-tests/java_delete_char_at/test.desc new file mode 100644 index 00000000000..94ba56a2c54 --- /dev/null +++ b/regression/strings-smoke-tests/java_delete_char_at/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_delete_char_at.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_delete_char_at/test_delete_char_at.class b/regression/strings-smoke-tests/java_delete_char_at/test_delete_char_at.class new file mode 100644 index 0000000000000000000000000000000000000000..cfd8561e5960688dd28ec9e722c7353b57d35ec8 GIT binary patch literal 867 zcmaJ*MY z8C=z{s^c22tGJ;fE#Va%Rn%0hF%(vL5C}iCJvVr42fXhHi-GMjB)4qW4j(YYD%Cd( z@omo%4B3wDikHKKzVKg5FeMJS?J{J#AvfQ@;Dabkl2qJe(6&tHm`3kjF9Of95wn;S&+(wfM%m~`k2A}x8M+}Ak)K+oFz+K#9$ju(U>hB9P{3kRKL&M>N zfpBS3>y^&z!6e(No(dhSZ!s8?p0}yxHc>BEo}Go(LT_5JSUC+OzNGjtZ4Bn4QVnc4*fO3zi6MUsxw|q0NOuO3UeZx0cBUdzYFNbJqp$pz%ZUDiQAzF;g*US&?OKL zd+gmsZGkyLYNJ~J)v(LWR#27u$}rMehWbi2?)1a@jd$-ka44(72yaLue( z_x$VP_MgYSAZP{zyRRUy=wQjx=4N)dMu(3^A^_Rn1ss?Mz~6WzTgUEIUDVXmLf@DBr7^d cwISkEV8K4z{bqS3qCAUGc(nlKcs)a zwVKcb65acwi1!W9rVEpocfapB_ujwfr@sMg;<1e~76oouxNXD0l7%}K?iNwPJ#8-w z+_zEGDGzL{;GsZ^P+#$qM8>HaM#&46c>X|!1UeuTx++rXGlJP(eMiXc3`0q%^i(9@ zjE;R7ztzbcIQCRTDECt@__XVN&fH9cV0DARWe>YQ9L0frrF4ax$|U_DqcHiZ(vMG$ zyf2=EDr$tP);9)Tbhyz^V-+28`)xl6b@&m%2$-AU2M(^G;-HOHLUUHKeKpC;I3C7K zX%0uA<6sTzb0~ZMkqlBoqurbJxq#l%Q(KzlduI8c6y8&1R=6|ZWfB%bnW$KXQ$DNhSmIrj7n z#=dJ#kbCXsdv0O(C&U=_&e{pAF-m7B?oVLx= z;+}l3G?kyqB>f~m4@B@UA9;WfY!zHDhgGcI;r`G)k-d~qsr`QtD{CydmoTo{tnGEuSY-?qZLNCyn? zP7krfPvh~!QL(BgU@r$|L6OfHzAdmNw)xc&=(|otiBBsF5(+5eA^SS@E0>yVcP?QZ zlyW1O?aa%ww_D2Z{eU$@d985)dx)t^I0qvX{*0rI=G~}PGBTxk)?#^X(_$qXbNu@> zS+~WJ3L`#@D>QA)j=u`SbGO}ZWNiX7CHDeTL)hjwn7N;@Cj2*(Xs$dA?~R_fn#n)9 E2H7QzvH$=8 literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_equal/test_equal.java b/regression/strings-smoke-tests/java_equal/test_equal.java new file mode 100644 index 00000000000..a3acb0ebda5 --- /dev/null +++ b/regression/strings-smoke-tests/java_equal/test_equal.java @@ -0,0 +1,11 @@ +public class test_equal +{ + public static void main(String[] argv) + { + String s = new String("pi"); + String t = new String("po"); + String u = "po"; + assert(s.equals(t)); + assert(t.equals(u)); + } +} diff --git a/regression/strings-smoke-tests/java_float/test.desc b/regression/strings-smoke-tests/java_float/test.desc new file mode 100644 index 00000000000..427d1fca836 --- /dev/null +++ b/regression/strings-smoke-tests/java_float/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_float.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_float/test_float.class b/regression/strings-smoke-tests/java_float/test_float.class new file mode 100644 index 0000000000000000000000000000000000000000..e4448d415584df7b1d4015eaf7189dcde13f9c81 GIT binary patch literal 965 zcmZuwZBNrs6n<{k?RKSOqpH2 z{(zsw1dJx?CqMY3#B)1gpr*~ax6ggfInO!g_UEt9UjfYEfsO%8s5|cf^-!9f?|_bT zIG@A?OzN0IK8Z9gYPh81G720;9etS4FsYetQ@SjOC9keamWk@wbtNHqgwH3h}*BG?< zrt>F;-tanpQ`Btfkq$)=zFc=aD=cqXZ!H5u$Z}jaa053vW(?fIZH_wz?xJeI#2|^N zTXhO*U>0)>BhsznSnfvU(UJTm-}ih<`q*8UNw*o2rQTle<>Z(*a1T^jrWfYv+NNlR zr=UjY+wKO*?XhZ7Gvx@qqr+^WR$T58x-cm`5xTJ*grZF)cpdW1cG0gjXRb(dJRyID&jV|oa z0Zn?9Zcv)87r-(jvh}o!fyoJx&C%C5t&G*}(0flhDHkAc4 zwrHwLlb;Z;Pm!5b^U}umkSOhg??Kx|b~J7#_o45i?+f}~9KiS%;X@@e^&dDps+#?$ zaVbZMpofzz4gF+?=tmhtDyp)I3|6StS5)UHv4;^mL=_1|Q8>oBFOVB1 q*E7d8%|vwq17><3nO$)8J=EAoXuaG=t&lO}P>hGNVP_+0C#+nD+1t&jn^YIG7T6 z;b9hY0`r8*qD&GMr@9viSJ zDQ4hI>WDDjOl5ewE6=mEK%L+=!tQ?#ui5Lzq57yzM0=y4 zf+gD~@O2D6llWM`BB5qVHoG!9+I;tD_d^`_VnT70Okl~!GFAxXVb9n0i3-z^R5Oir zbi^Kwjfc^A&QCnxux-1`yCGCND$%j(43v4&w9f!Hv@p;6^?2)4t{Kn#mjiDDMUExD z&G1Ql=GX5)-%KIO9GxslC}3hxdI^i0fkt3`4y>IZxBDIT6{_pE$Zzm>jj>;F4(=fS z41t%UfKjkAg=yAcS!Q(j5v=5*&ha(d4HzlGx<_50^6=Ieo*Y=&%IpCXfqRR>6@+~Q YJNEgj507B+?5dZ)H literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_hash_code/test_hash_code.java b/regression/strings-smoke-tests/java_hash_code/test_hash_code.java new file mode 100644 index 00000000000..d9f42b7ff9d --- /dev/null +++ b/regression/strings-smoke-tests/java_hash_code/test_hash_code.java @@ -0,0 +1,11 @@ +public class test_hash_code +{ + public static void main(/*String[] argv*/) + { + String s1 = "ab"; + String s2 = "ab"; + String s3 = "aa"; + assert(s1.hashCode() == s2.hashCode()); + assert(s1.hashCode() == s3.hashCode()); + } +} diff --git a/regression/strings-smoke-tests/java_index_of/test.desc b/regression/strings-smoke-tests/java_index_of/test.desc new file mode 100644 index 00000000000..f2fa825597d --- /dev/null +++ b/regression/strings-smoke-tests/java_index_of/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_index_of.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_index_of/test_index_of.class b/regression/strings-smoke-tests/java_index_of/test_index_of.class new file mode 100644 index 0000000000000000000000000000000000000000..1acb3335d57d4664c88fb229efaf15666076d900 GIT binary patch literal 631 zcmY*WOHbQC5dOxoy^b-Em=aRTD=oAEq;la_Kt<3>RZ} zXQ%`cNc7$xg&4af5%OwxJu}~9cK$xx-UC=g(}s-+3v~-GZA{`-85X7lrfry*5SXzs zi#dS?VQk(@Q<-Ecj?!(FdVW`i1nLmXH5I9BgHUQNekbT#aVQC+EfvX~-ia@hy}Xzc zC!UH3!|luqj=y<7i?G0Jg0&WO|8v;wxR(U-v&s=}Cev(RMWOt)A0NCw@=iSm!x&+y zO+O%Le!zGKZ!qs*2o9m1*Q|8C=x}B8$?m5li4)d+MkcV};4R(}Dg(%_eQ zDmo;H!o}_ZVZ7NIApWI4EPmmJ2hpuAzZIbt%2XvX>^tGkvmPh-p*m>rQ`Au zd@F%nVubfm{+s5L_%xPoK$m$TD!iLTkWfaoU)q7jU|`PGzPhE>((*O*^(z=>s7&eS z7`lV`;|AhS&Y~48H5hz17-jM&Sl;4Em*H~M0X<+=V2l^f1~2+LtA#dDb**cZ&mi;* Y=%wE<2E82|tP literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_index_of/test_index_of.java b/regression/strings-smoke-tests/java_index_of/test_index_of.java new file mode 100644 index 00000000000..270267196c5 --- /dev/null +++ b/regression/strings-smoke-tests/java_index_of/test_index_of.java @@ -0,0 +1,10 @@ +public class test_index_of +{ + public static void main(/*String[] argv*/) + { + String s = "Abc"; + String bc = "bc"; + int i = s.indexOf(bc); + assert(i == 1); + } +} diff --git a/regression/strings-smoke-tests/java_index_of_char/test.desc b/regression/strings-smoke-tests/java_index_of_char/test.desc new file mode 100644 index 00000000000..63382a455f3 --- /dev/null +++ b/regression/strings-smoke-tests/java_index_of_char/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_index_of_char.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_index_of_char/test_index_of_char.class b/regression/strings-smoke-tests/java_index_of_char/test_index_of_char.class new file mode 100644 index 0000000000000000000000000000000000000000..f87a10266837a4d7315b07e7dbb86aad5cd9ca03 GIT binary patch literal 614 zcmZWmO;6iE5Pg%_*kOZP&1R^$!B?%hXrN{9`a z#Cn_Uknuj|@Y;umK|;-@S35F3THSnZ_k%HsAyob+6L{le9&ZUjAGg~+R$=x}sF@iZ z9}z^}%I+b1S=?FLVUvB>R)^<9s75N)Mnye!cAIrM!NWP=Mg>nBprB^^krnVA(S2%sIkQ5A=k(K!x}>FxpdD%awtVinv4h62iHLQ~Uv^Py5`Q PrEyX4H>`!RTy^{pEv0g( literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_index_of_char/test_index_of_char.java b/regression/strings-smoke-tests/java_index_of_char/test_index_of_char.java new file mode 100644 index 00000000000..6a5d3d60bd6 --- /dev/null +++ b/regression/strings-smoke-tests/java_index_of_char/test_index_of_char.java @@ -0,0 +1,10 @@ +public class test_index_of_char +{ + public static void main(/*String[] argv*/) + { + String s = "Abc"; + char c = 'c'; + int i = s.indexOf(c); + assert(i == 2); + } +} diff --git a/regression/strings-smoke-tests/java_insert_char/test.desc b/regression/strings-smoke-tests/java_insert_char/test.desc new file mode 100644 index 00000000000..77d3ce2ebd9 --- /dev/null +++ b/regression/strings-smoke-tests/java_insert_char/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_insert_char.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_insert_char/test_insert_char.class b/regression/strings-smoke-tests/java_insert_char/test_insert_char.class new file mode 100644 index 0000000000000000000000000000000000000000..481304a9f6deb435deed6561f574cf664acb1da3 GIT binary patch literal 811 zcmZWnU2hUW6g{)R?y_tPrIg|aYPBj*1wX1UG)Bdm7*QWEn)am`b|>xB?XK>JKZZZx zvzkC+6MgqTX}kjkV*7G;_S`e)o_p{7{`=!6fK5EKu!xHWswOU3&~RCWD=MsIVdJWa zYZlgV-M|eCmSWztP($57gJF4{N0A6)8TipN8S%a+Tn4twpl?ZE#*Y|MwfZ}TbSH2H zL%u70@j5x`i}0-?Q{sqApJAaFbLYb={&5VG8v`2*=9c4~$XLA~2_5lVs!J=eh~hoz ztI~VU0S}vp{4=+)gd)SLI=4LT@3(q!DEX2=potT5UhB?z6R@r3qfeS) zsMcO|>Ss77EwpJQaWK^?)y@)$p^Hxm_o7p^CZ5`LT1|fLpySd07|O1QWGLKOyR?ls zp#&{&7i;tk7U`|9LPd>>PAM=oYl_SCSEVnbZ>BK<`>Kd2QPjsELl!GD>H%HVDAziM zwo^=vkbc=n7y3hF-ZzHOyWe08P}(S(Lu3cY9mCogA@@s(YGctdGIY++L)1ysz$#2M zsYIF39M~T;2{TY3_}r}O=GY0aRJ4a!7{Ew>K|1vv#$0!5R_SD**^gCA=f`C)`~&hw Br?3D3 literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_insert_char/test_insert_char.java b/regression/strings-smoke-tests/java_insert_char/test_insert_char.java new file mode 100644 index 00000000000..ac6beb4ffcf --- /dev/null +++ b/regression/strings-smoke-tests/java_insert_char/test_insert_char.java @@ -0,0 +1,10 @@ +public class test_insert_char +{ + public static void main(/*String[] argv*/) + { + StringBuilder sb = new StringBuilder("ac"); + sb.insert(1, 'b'); + String s = sb.toString(); + assert(s.equals("abc")); + } +} diff --git a/regression/strings-smoke-tests/java_insert_char_array/test.desc b/regression/strings-smoke-tests/java_insert_char_array/test.desc new file mode 100644 index 00000000000..d48c601b61b --- /dev/null +++ b/regression/strings-smoke-tests/java_insert_char_array/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_insert_char_array.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_insert_char_array/test_insert_char_array.class b/regression/strings-smoke-tests/java_insert_char_array/test_insert_char_array.class new file mode 100644 index 0000000000000000000000000000000000000000..3c0b53292301c003d9745154f7ecba9ccf1a4695 GIT binary patch literal 979 zcmZuwTTc^F5dKbYr(G5(ZMi4{qKLg9^@7(TmsU-Tpe7X!@IX#?PjGR&i@RGBeueM+ z0iVUBBx3a4A4QzgLM!6SoU`A2GxN=y+26ZGH!Rzf9z#f& ziZiFE%-lyd0*dN`JJ zEThbj?8d&T?MNda8Jm?ecv~gIV0NWTZi6K?#8|sshVkt4%}VYZ>7>6BO)YRwlV!5! ziNyFzPIb=@WSw5hZIGzJc3R6VzNVQ4ltzj=1*BV&&cY0QSCMRb!I=Em5Vrr1`gW_O z9Bo8@x2K9tYeO?LrEhuC?97suAZU<-c4h;Uw0%ihR+b!5k3qLENCq-w2kC2!PDW=m ze+c$f5ivwI)&dz4817I%Q)rlcl_P}KQ{h8IUPOOHR|?@|ZLJVV8f*DTp^50bd=s(N z1Mrz9;s;3VBQulIn&{a_&k^+XL-hVqg+i@D(^P`0L!**?;G`^$5yB=2nL-c!GdjxX zB@EH DG=!i}#;CO>ji?V8P5WYoWm2bZ7u{X_G5i6a z)dUio=)3<(;~gjv+m|~tXU?2^?!EK-?~k7V8hBu15f?3#lDK5Uz-1k-=&+W8gR4ng zv$2lr7H-(EHS?y8GAb6TgynS+hBAm$&kvufP;@-mCD1;>+)}=Z9ui{Z${Rv_yVsS3 zOiTIlW&fxngV&nO7e_+*goSn_+z&6r$1%)qENl>xTdsE^W4C+#z?ILGew2@77`;=z zPR&bHI~1RVgC*n$t9oDegnv+PM}hJWp7fR1l>xyJuIAiwa2quTb=+}~L6$v;#-_^& z9o)qxp*UA~Jgsgg2zo4$IhEMLJ%@XEpOBqDdeu3UZuB2CaY9%rx8}SF*wpPYC$$ht z<=x%N8O})wP3}n4n`-6DXNk-(<)^;z!c(~>o|+Y&OlIz2+vD*O3SAkhKz3)<@-U)4 zU-0bqvBtk(k-rLMi@IIBi-B~nIWF_5#4GWdsE$BiH4%A^<`^WTuri~*=cfkW)sJE9 zJW*y9L&}?SOerYa>*f51Eh~(?~RcDrA3XgXaNb{C-@(lENWpDNz^z+ zfzdSR4{D5AC^CF*mbEc<0xad6Ar=O(;$IMteTOyIoto7;2^h{JUDEk++6(^xKTD?D literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_insert_int/test_insert_int.java b/regression/strings-smoke-tests/java_insert_int/test_insert_int.java new file mode 100644 index 00000000000..b787141e51a --- /dev/null +++ b/regression/strings-smoke-tests/java_insert_int/test_insert_int.java @@ -0,0 +1,10 @@ +public class test_insert_int +{ + public static void main(/*String[] argv*/) + { + StringBuilder sb = new StringBuilder("ac"); + sb.insert(1, 42); + String s = sb.toString(); + assert(s.equals("a42c")); + } +} diff --git a/regression/strings-smoke-tests/java_insert_multiple/.test_insert.java.swp b/regression/strings-smoke-tests/java_insert_multiple/.test_insert.java.swp new file mode 100644 index 0000000000000000000000000000000000000000..5596a2c906d7e2a9c8e731f9ddba55e45b991bea GIT binary patch literal 12288 zcmeI&%Sr<=6b9hbx)QvgxNsN8MW@AfynzLATC${#p{Bqz5Ix+oKWuCczsmupLm${1sJH}`uN#jWDQAY;dg zjBNK$#pYEvQyD0&lDN8)oXNDhxU?|WH}TRYdV${xyi_(*scpKaO{(Ii_O@HeiQJLe zXzy5b#G#6{OwC~{i;QYV(la!ach+n|-{NRO00Q3&Wag+^A7+aS^WC52j5EzA#&^HZ z#|Q)<009U<00Izz00bcL?*vS{z^>?41NqH{^19Gh=S@@)fB*y_009U<00Izz00bZa z0SNp-0TD9xIKtS(C>@@@|G)qLf2Q^m#Vy4(MNHA4s8dW)Oj6i6uQd0C0tEsPfB*y_ z009U<00Izz00bcL+XOCbVVv6#+P*S(bxodTBGRrS{P&?R2ZK;LC<9snTkT0(t5OLEYI>i@@_gE?QS=3XMUst pu8lBMbrKcwmQbU}I;AbG)>^GPPz5iQsx(GLO&U=jFgEQ=Gt8VcQ-`6>#gE|! zd{z@kY@+Y}lg53ZKosN4-skMg+G}5a{QCM0z!qv6a=4&iO~pkG64r&dq~fyB8$w)3 zV-{CcT+?8psGy`l7a5xxuH%M+GQ<3a6^1;B+>ReUbwjJ=afg8&Fr;=|-;EwJB+TMl z2D#pGI77DK`utVgZt>ua2qs6{a(#xGW@Op#URoyuGqF-oVNiE$?+iw3cH+S1&s~wU z9PuzZbbV3!upN7md*bo(vGu{yF^@dMl6Y4<%Rj0#qrml#p2V)_@PI+G91(L<$1U6@ zsx9%jqtig{>X?H;jI5UJP%lP>)BwJ_~{lVdeitL%}^A_wj%sH_3e6I_7rt zhiS-*VZm%n;)ceWm{@Aq9>c1+TQ5$5_7Eb}UyAL#9^(bUnzET%g}7 zX+}C(>Vtg}fmkG&8W{$lq!*L`xMf?k?2EyQId0Z56QifY@~Wn_DVgdjn7DT zk>5159x`2IPNDDjG4ox3O9Su~f~ShmNE=YF0u^gis!Emuc`{%>QB|-!be$VB*cz|` h=8V}MvRx?hN63jUNKddw#05?glKx1vcYaWM^*86Xz$pL# literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_insert_multiple/test_insert_multiple.java b/regression/strings-smoke-tests/java_insert_multiple/test_insert_multiple.java new file mode 100644 index 00000000000..cce6881ca7d --- /dev/null +++ b/regression/strings-smoke-tests/java_insert_multiple/test_insert_multiple.java @@ -0,0 +1,11 @@ +public class test_insert_multiple +{ + public static void main(/*String[] argv*/) + { + StringBuilder sb = new StringBuilder("ad"); + sb.insert(1, 'c'); + sb.insert(1, "b"); + String s = sb.toString(); + assert(s.equals("abcd")); + } +} diff --git a/regression/strings-smoke-tests/java_insert_string/test.desc b/regression/strings-smoke-tests/java_insert_string/test.desc new file mode 100644 index 00000000000..b438d32d6d9 --- /dev/null +++ b/regression/strings-smoke-tests/java_insert_string/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_insert_string.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_insert_string/test_insert_string.class b/regression/strings-smoke-tests/java_insert_string/test_insert_string.class new file mode 100644 index 0000000000000000000000000000000000000000..39cc969a902e163ccfdfe821e6b8ae8b9f30aa07 GIT binary patch literal 841 zcmZuv+iuf95IyT$>^KfdoiquT0)+xe3JI5Rky0U`fP@I}5Cm#ps*SxWTU-ZhhmXk* z@C-Tej5 zn*&!cA1#VY&hPbjM*Cu14lfS>QN;U zVYDNCReC3k0_pEI_xLAn!A6nNDsFk)-);5cPLvgNQ;j{?uGvqpPKB{X>0j~rA?1k%TRVj zC;Mt7<)0sEqeSf(=_gA5sz z=hS!fRHIz$0NR$Fm>~JQk+f4|q~A8i(7Rt@j8Iy)Gh>(|WDk(tn!x(0M73D7j1O|Xx0PO J(&@PDnZGzkv2FkW literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_insert_string/test_insert_string.java b/regression/strings-smoke-tests/java_insert_string/test_insert_string.java new file mode 100644 index 00000000000..7c161205131 --- /dev/null +++ b/regression/strings-smoke-tests/java_insert_string/test_insert_string.java @@ -0,0 +1,10 @@ +public class test_insert_string +{ + public static void main(/*String[] argv*/) + { + StringBuilder sb = new StringBuilder("ad"); + sb.insert(1, "bc"); + String s = sb.toString(); + assert(s.equals("abcd")); + } +} diff --git a/regression/strings-smoke-tests/java_int_to_string/test.desc b/regression/strings-smoke-tests/java_int_to_string/test.desc new file mode 100644 index 00000000000..a615a10f538 --- /dev/null +++ b/regression/strings-smoke-tests/java_int_to_string/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_int.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_int_to_string/test_int.class b/regression/strings-smoke-tests/java_int_to_string/test_int.class new file mode 100644 index 0000000000000000000000000000000000000000..eff0e5a422e2df360086c15be326751bd69c8115 GIT binary patch literal 859 zcmY*X+iuf96r6P~n>bE$Yf1fGGfQwPYP>A4?ip#jd zv8*DDd=ytvRI!3<5nSiEp`wH`M};A?qPwneq+wg`W5dP+Vac@v{iCiSi4@084Xaqwuz&=EvR)?z4K>_i$a$=qsaw6;_9W{Q$FUubbq#fF za5OaB#vO{fTHhewi9W|&4fk-LAvx1{***{*IoE1Q$FO<~sTpg}lA4M%jRlcQsj0|Mw&_pwZuB~CYpC3D{3=`8?? zixkx~eHCbBw1z6jU|&5VGE~EUlOc-5DfKfHdVrmz_8rQzBLs$6tfYe@gocRyMELD7 z`0wOj0-HyOR7Z%8In}f}&+&W|-zQH_WKK0qQ8e#zKa$sk{z9hCAX6 zl|TZiz4u2I#sQL6w#J@$GjHC^pTBp%0IcFeh&;*x#zIu^IuC(yfr$`Vlm*^|n8aIw zcZA`pOjBj7ZYSxcPGzH|nglu^>5j8Asuk8W7tJt0_+ThAO}z1=af+Sab3XjN(tbz+rCJ|4?686m;|H5Ic-cHG@E!-fpyU1qm8vZ$oOUoB1+#~z_7P;S!$?GzW zGZ)iy+Z-Rk5(4JTV}|7nF)|8zV8<6I^)8144EGwZcEtcgC2@n`9KyeZpZN*D-{nQG QW6Z*fKD((#*zqv>2xe1s)c^nh literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_intern/test_intern.java b/regression/strings-smoke-tests/java_intern/test_intern.java new file mode 100644 index 00000000000..7f9d5283597 --- /dev/null +++ b/regression/strings-smoke-tests/java_intern/test_intern.java @@ -0,0 +1,11 @@ +public class test_intern +{ + public static void main(/*String[] argv*/) + { + String s1 = "abc"; + String s3 = "abc"; + String x = s1.intern(); + String y = s3.intern(); + assert(x == y); + } +} diff --git a/regression/strings-smoke-tests/java_last_index_of/test.desc b/regression/strings-smoke-tests/java_last_index_of/test.desc new file mode 100644 index 00000000000..77bc5b7f18f --- /dev/null +++ b/regression/strings-smoke-tests/java_last_index_of/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_last_index_of.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_last_index_of/test_last_index_of.class b/regression/strings-smoke-tests/java_last_index_of/test_last_index_of.class new file mode 100644 index 0000000000000000000000000000000000000000..4455da4d17990ad4ba7072f2330d39bebd49531c GIT binary patch literal 647 zcmZWmK~K~`6#ia!+v#=-EJb!#1px(JAb|@v(P&T;;wpzFChmny+kp%$t!cZ2-@?VC zXElLD6TSPRh;ORw#+XjtOuzZQ@4b2N*Y&p_0JhNa;GyNB?c%nFJGfhei#dUL4-Q%a z_dG0MQDBKMvn=ymWra?Y{DsbCI8ZTx`UGcNC%Sk_sB~7}5vn_BtO!$Gov63N(@FAfHhgHB>~evlq+9LqE5 zV*--|TZWMg36>1m#>WFJ`>4Ywv<+)>Ad{ob=QmZq%(65i1pj*qtoV3{M})>$w-+9( zsQ3r!6`4+s2z67@t|@5mkTBcnj#Ymsk5_lO0b_KB1v#M^t6XO)9+kwMD29B&jq78H zTkr8ysL?i$;8O+MElhHp;=g&`iFbSL3iR0!(ctKmAfblo5w#DC#lT` zpL~IRfySKk5%uqI-d{odG%i-@(uB=tn^g{fg44S^`5FR7eb6-)1ZH^gtZ-|TXRFK& hOb6~IY8MdIPpDSD!X6vnlxK`=SpGBfh}kl4^EYGRe8vC( literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_last_index_of/test_last_index_of.java b/regression/strings-smoke-tests/java_last_index_of/test_last_index_of.java new file mode 100644 index 00000000000..8b3a0904d5b --- /dev/null +++ b/regression/strings-smoke-tests/java_last_index_of/test_last_index_of.java @@ -0,0 +1,10 @@ +public class test_last_index_of +{ + public static void main(/*String[] argv*/) + { + String s = "abcab"; + String ab = "ab"; + int i = s.lastIndexOf(ab); + assert(i == 3); + } +} diff --git a/regression/strings-smoke-tests/java_last_index_of_char/test.desc b/regression/strings-smoke-tests/java_last_index_of_char/test.desc new file mode 100644 index 00000000000..3e9a3d4b547 --- /dev/null +++ b/regression/strings-smoke-tests/java_last_index_of_char/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_last_index_of_char.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_last_index_of_char/test_last_index_of_char.class b/regression/strings-smoke-tests/java_last_index_of_char/test_last_index_of_char.class new file mode 100644 index 0000000000000000000000000000000000000000..388717f4261b0458687f8c13e6e1a6735e6419c8 GIT binary patch literal 623 zcmZ`$&rcIU6#ibjyVGtLS&Eh_6#Rh(ILL)#V>GBqgFr}$30#`l-2n#5u9@8${}wJD zJ*x>Mn&{pCN#mOhwDDjjdGqG|_`dJG`Ss`94*(l@;-ijM4Rb!)xLb$7J%M>2E?NQ$ zJ~~(wSR%|W%RE=6&{>+l)VYj?Dk0Dz!RzW&7taXQmDRTdXERF_Vfu|u)z0WVQfA*4 zbK+d;lrYsVWPG+Q-<4s3`-ECI9$sVk{cL1n^;+AGg+k@UU?|z>G*KT0+0h_Ak>=^C zd@ln8m?F3`ie!szsv(6F+4R@Lqi&$iNA?eWl))=kdmgjS+*ZB#Or!P6HbPVll0S+U^l0~EHc zaQ3PoI~Utq{Oa&ce7kE`pwG4t(`>ymNZcBZOZQOW11vTxTWg`bM78?`&IQ7G?;{%D z;T~MU`)M&MB}Nkt`z{lDOf8tIh8d33LBG)vX!5sUb_~B!QUWtgaf#Xmg!2hb^(&kS T;*Bbc;-V5fx7u%)gm?Y|i7a^3 literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_last_index_of_char/test_last_index_of_char.java b/regression/strings-smoke-tests/java_last_index_of_char/test_last_index_of_char.java new file mode 100644 index 00000000000..029d59c9d68 --- /dev/null +++ b/regression/strings-smoke-tests/java_last_index_of_char/test_last_index_of_char.java @@ -0,0 +1,9 @@ +public class test_last_index_of_char +{ + public static void main(/*String[] argv*/) + { + String s = "abcab"; + int n = s.lastIndexOf('a'); + assert(n == 3); + } +} diff --git a/regression/strings-smoke-tests/java_length/test.desc b/regression/strings-smoke-tests/java_length/test.desc new file mode 100644 index 00000000000..913afbf13c7 --- /dev/null +++ b/regression/strings-smoke-tests/java_length/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_length.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_length/test_length.class b/regression/strings-smoke-tests/java_length/test_length.class new file mode 100644 index 0000000000000000000000000000000000000000..9273d09869b9f51a7d8c54ecac00703acfcf3186 GIT binary patch literal 630 zcmY*WOHUI~6#mY1I@3-E`#_*td6kE47qVezLnK8LW7S0s32ex8dQ)y0re@~WAH&9_ zYc-*XB(Uc{VK{dxEpE;|_dLGueCOQ${c{aq7j*|Ylx;lA;JE_>6>VN*k;Sr&6$iFX zt~yx5x{WGfe$$I%5h*zg;{zFc-9YpRbWE_CGL&kMkgC-W31(~96NG$QhT_xcyepzF zx|kE^o(u_d9p(9FAHA%8b3AA$;HJu7=D zkXFaGz`tdFiQjZ%4Em`HQDkc+LE`4pwDgc$4bE*`!8j_V#xOrLE|G5jf^~sH#rlri z73`xiGB+B?NPtQ(*-yh^$UGmriVWsCk_FwNYU3$i1q)M--Gmn?ma>;{E?}EKV5WY< Unjt=nrcu%`+&5alVnVod4-^}9hyVZp literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_length/test_length.java b/regression/strings-smoke-tests/java_length/test_length.java new file mode 100644 index 00000000000..4222414fa80 --- /dev/null +++ b/regression/strings-smoke-tests/java_length/test_length.java @@ -0,0 +1,9 @@ +public class test_length +{ + public static void main(/*String[] argv*/) + { + String s = new String("Abc"); + int l = s.length(); + assert(l == 3); + } +} diff --git a/regression/strings-smoke-tests/java_parseint/test.desc b/regression/strings-smoke-tests/java_parseint/test.desc new file mode 100644 index 00000000000..9cb70f5a957 --- /dev/null +++ b/regression/strings-smoke-tests/java_parseint/test.desc @@ -0,0 +1,8 @@ +FUTURE +test_parseint.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 7.* SUCCESS$ +^\[.*assertion.2\].* line 8.* FAILURE$ +-- diff --git a/regression/strings-smoke-tests/java_parseint/test_parseint.class b/regression/strings-smoke-tests/java_parseint/test_parseint.class new file mode 100644 index 0000000000000000000000000000000000000000..e1ffe0c72107860cfe03ac1f697018740f58a884 GIT binary patch literal 727 zcmZ`%U279T6g_u0o84@-=F7%dTeY@o+KNRfC|HY96$+_7M185W>NHhy`3Mpnyw0 zE{E`KaxugeEcsX_)Rsk(NNv1Ob6d=bL!n|qz4@|rAl``efr$I-ZKGA(zh@g~+D3F=?}|}c&&&wHW_R!hJZulg zx+|Y33sp5TF|S5KCsM`criF`e1|>rIZ)k#Z>$Xi^^>Ho2bu=SHm?1Q>%7-VLJ=S`t znaL@5A1e`7v33glS?54@4PmzV?`0|(`c7klRu!X4bnNNen%~jOcx1}R) zb=lrMhO<|7C&;zdzQDWx5&0uj=F8Dr6p!KWO%Qya#@=Nyi|(Z8b$IN12zgG4KhhEc z+~HYgIm%z{r~Og0RO4uUN^~P-1XQYp&j^p;=iVddenLKjJt1vjJUGz_XbmxW3hJyprYdsx4{^ zY?mRjZaJ2}!4OPmUNeM>jhbK>FI$dy-mF)J`$~$*QRkM!Fjn!o`F@)pbj(D^pst&C zH-=VeG+k3Xwd9F}FFgOPD-LXKilu%2k?S~*6hmC@b2fMOauwgToIRr8Rg+h1Qm{%~ zlI=*x13Xl)rX!Da1&?%WU{%K?rh0mkY+{QcH3(SfmHEVV8!khDS1HyZ@gJIpM-2Kf zl!Ahe$0&{NJZ+Qxcr1tw!!8b;+j#g4gpj%nsM6nYa$5$fg-Z2!q?+efgc5Pj=7vEw+zaoQ3-3KaU04`?pEwL+i(7XloDklIUG+pFT%cFNk}$K(%i z2Bbuy65RPuAZFb*5mZ{u&d$7f^JezfpYJ~a?4W0%ikk**nYe91!>TfO%BbM3iF@j? zX5hYsvI0G@u#OD_n+%P0o~A-(;V4O;g(>$U5iqa=hSFY`gxO<;LaY6bLGOiK5?)lsc6ky9n3vCIBW(ZE?~QjX{ET6_HCS++i`Z2=FfKIH2(5m^PniPf;9vMQMViu4_zTPEa{Rd4C4$ zry|sHLKiyuMOZ}LfI%xau}qN)*l%NV=I4?yi Po+32+i5jJux4iKe)@YJ< literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_replace_char/test_replace_char.java b/regression/strings-smoke-tests/java_replace_char/test_replace_char.java new file mode 100644 index 00000000000..82a023924e2 --- /dev/null +++ b/regression/strings-smoke-tests/java_replace_char/test_replace_char.java @@ -0,0 +1,9 @@ +public class test_replace_char +{ + public static void main(/*String[] argv*/) + { + String s = new String("abcabd"); + String t = s.replace('b','m'); + assert(t.equals("amcamd")); + } +} diff --git a/regression/strings-smoke-tests/java_set_char_at/test.desc b/regression/strings-smoke-tests/java_set_char_at/test.desc new file mode 100644 index 00000000000..650e7712278 --- /dev/null +++ b/regression/strings-smoke-tests/java_set_char_at/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_set_char_at.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_set_char_at/test_set_char_at.class b/regression/strings-smoke-tests/java_set_char_at/test_set_char_at.class new file mode 100644 index 0000000000000000000000000000000000000000..6e843afbe2a4b7cfb6c15ccbbbc95c7bc11bcbd0 GIT binary patch literal 874 zcmZWnOK%cU6#gy@Gs7^*K%wBH+SXP9vG}M@h!IhfrmZfhCUirF;igWV4mvZ~|3XY$ zx>gfNB+N86dCJ6 zT#F)s>nifXT~JWe5Erl;8cMjSV1r>{&Gdcl1$Nip? zErV3=b~r;~$9DOv-cg%-dm@+|N2cvE#2bNWz27xIjLk%i*f6M7%Q;JxsI@KOE$g_2+YH(HkY_#H z>2OcS9o*GvLico}upofP1iX(247nMmHtG3==XE`*I8R5xLmiLs_#ZN_+lSl=hgMQMOYbp*LdaAmh78OH;tr2(Sb-=X!9E~a7w z=zYXSh&P8g_j_#46eEN)tS>XWC>BR*-Ucw~;V3i2cDl~-GkS9{^t$4Stw)k z877r7a1GZP@(b>RSznJmZ{QiYff~s_QJ3SUfm^uEU@n+1ItQXF|AMAM7_x=NB5w-b zRnv)6D~+HN8c1PRK`}X)u`-3?zcdEjmzF2}*S6gM&&z5J(*Xr**rf&*I>O< z>U*MwDAqngsFl(t2tO^E`k1I=L>r&MN63^@+8D7B5=V%)CeXhh!(${&{lf`3T_!mC z2de6ag8CcaB5|jKaVyKXsIw372kfUf4+D}wCRyp!Hm2heeJ6cxo%3d##_RAYnsVv&a$4ZM*1vBAZ1C3{E|nO>$!n4LL7ztqY>y$=7O_w-8O-L&M~2MSAmR+A zu88^j;ZeZl2OUhnkuPF~Vo&+umu>$zb(0JRyB+qgYB;^YP=@@i&>1zw6SbcxU#evP zn^2#hANpT?7iCl!%KE+D_v3^0o{}OyAcjs5MjBpbFggL5AarpHB^OPsFw|!$o$F@a zNI8&H?O!SjEf=d;yFs)Q9P&_+ux58wYQny$dv_*UKate`1kt=ov(&9V4V7Uo;)#$v znu?+ksUZP0(LF5EVv4jmR<7$_=w*Ubp+eT9-vZr??rdue_EQIA znuNVLg|X|IV`ScW*{+w{{sn7{H@%v|NGaxtgm~f5U4%uN zY&3|lO`aMdB^Z}zSeTof8o_s_S~gOBK*cMZz#YNL{6NP14Qp2ax&>V;3&VY-8?C4G GcmD#%SB#4Q literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_starts_with/test_starts_with.java b/regression/strings-smoke-tests/java_starts_with/test_starts_with.java new file mode 100644 index 00000000000..aba79d846c0 --- /dev/null +++ b/regression/strings-smoke-tests/java_starts_with/test_starts_with.java @@ -0,0 +1,11 @@ +public class test_starts_with +{ + public static void main(/*String[] argv*/) + { + String s = new String("Abcd"); + String pref = "Ab"; + String bad_pref = "bc"; + assert(s.startsWith(pref)); + assert(s.startsWith(bad_pref)); + } +} diff --git a/regression/strings-smoke-tests/java_string_builder_length/test.desc b/regression/strings-smoke-tests/java_string_builder_length/test.desc new file mode 100644 index 00000000000..ba9187109ed --- /dev/null +++ b/regression/strings-smoke-tests/java_string_builder_length/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_sb_length.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_string_builder_length/test_sb_length.class b/regression/strings-smoke-tests/java_string_builder_length/test_sb_length.class new file mode 100644 index 0000000000000000000000000000000000000000..cfc35874d26f44f91fc0291fbf4cc2eb1c058bfd GIT binary patch literal 722 zcmZuuO>fgc5Pjn~vEw*x;?OpH6zB&e4YaxR)(QayBt$8PAW(Cu*7hp6xK3m{{Fq)i zat5SCq7vNsO$agTwy_Xgc4lYiy?OKY=kIUd0c@jdp^9q;uA8`FLBq0%n=0Naqk`Ki zTQRU|p{$zLEUe>>fxCppx=0ckr@=5vo&Ra8mxTHK zAd&~;6IaHsRWm=Fh#(?Vd#Ui=zZ9da%t8p}t`}Z#SiRvm_T;lbAsVSn(xb#Z3S~4% z-)$X>55h(bb;6R$yP=2%-Ci08(ctko2z?o|3gLRHsYTFyX`_t|8*`Yq(ZM}JGY3Ap zTW4;eZ4_c#OhZERwTP|Go|++*pbgoXBgUOZQ@qqZ-J(MU$@%;x_Z{=rPSo$;7>|;9S2e!SB75=>{e=yaWYFW+-VBx6q>F{ltBXKNt zrl8NN5e+^|S&{g+ugqHe85C%rK|6E`Q|K=`PH}?L+b=Lq(dbNInjcX)L-}wD>xW{~ zGByXg8Uc%W>oCxQi3P5hpkHViSmbPJHfKAV4b+{=1okNm{S)-UR~R|rr94Gagl0cf KOEj~2SN{Od36Tu| literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_string_builder_length/test_sb_length.java b/regression/strings-smoke-tests/java_string_builder_length/test_sb_length.java new file mode 100644 index 00000000000..b616749ffb4 --- /dev/null +++ b/regression/strings-smoke-tests/java_string_builder_length/test_sb_length.java @@ -0,0 +1,9 @@ +public class test_sb_length +{ + public static void main(/*String[] argv*/) + { + StringBuilder x = new StringBuilder("abc"); + x.append("de"); + assert(x.length() == 5); + } +} diff --git a/regression/strings-smoke-tests/java_subsequence/test.desc b/regression/strings-smoke-tests/java_subsequence/test.desc new file mode 100644 index 00000000000..34585a7900d --- /dev/null +++ b/regression/strings-smoke-tests/java_subsequence/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_subsequence.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_subsequence/test_subsequence.class b/regression/strings-smoke-tests/java_subsequence/test_subsequence.class new file mode 100644 index 0000000000000000000000000000000000000000..0f8410939e1af315893c149dafa8190916146c35 GIT binary patch literal 789 zcmZuuO>fgc5PchetmC+?<0K`Ngs+y851^L{4wQ;00V!$6B&5& z)}DALEX-k^CU;z~Ctp$z3#+(JjVv_Kv`~P>P)(U@V-f7Gbxx!|2*XLpV4v;E(X!CS z4NA?b9=m(ei~oU!ap(uT42v^X_mv2T$Kn_YBz5+xHTwPL;Q!paq~D|34oy%S{brYT zc8WQsb<>=YjQmiJrUqzvaY6~&^$z`wK|csEyP8_2n*v%e=ILCZSDhlGsI`v3KBh$2 zbm|$%kVkP!J)}~Na>B`NwKU^1ltEkh0yT$wZ8eLVZ7qwp)lbk4P^{VBdlbGwe|7}^ z<1bdXduK7HqT2Eln99gyGFC|dX`{h9x!`cf%@SeD^twZSw#d;7a^n!I4COb08b^tv u%ow>Um5E=O8d%Rv0Y!(z=MTWu4^WjuXtRMQzSD*pa@PHHJByi~bAJGKN17A> literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_subsequence/test_subsequence.java b/regression/strings-smoke-tests/java_subsequence/test_subsequence.java new file mode 100644 index 00000000000..4d8d79cb381 --- /dev/null +++ b/regression/strings-smoke-tests/java_subsequence/test_subsequence.java @@ -0,0 +1,14 @@ +public class test_subsequence +{ + public static void main(/*String[] argv*/) + { + String abcdef = "AbcDef"; + CharSequence cde = abcdef.subSequence(2,5); + char c = cde.charAt(0); + char d = cde.charAt(1); + char e = cde.charAt(2); + assert(c == 'c'); + assert(d == 'D'); + assert(e == 'e'); + } +} diff --git a/regression/strings-smoke-tests/java_substring/test.desc b/regression/strings-smoke-tests/java_substring/test.desc new file mode 100644 index 00000000000..8a29460f529 --- /dev/null +++ b/regression/strings-smoke-tests/java_substring/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_substring.class +--refine-strings +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/strings-smoke-tests/java_substring/test_substring.class b/regression/strings-smoke-tests/java_substring/test_substring.class new file mode 100644 index 0000000000000000000000000000000000000000..3ba0b60e7f2f7faf54110943d367cc5063d9aaf7 GIT binary patch literal 740 zcmZ8eO>fgs5S$m=vE#a_^U*Xw0~AWhheU-`aiLU1Ns%G~9D$3LLChO zdtUR*J(OO20UD&^1#&Yf0+o8N*XYm7&N%m}%zN#GZ8lKry+((Nm~%Q~?vSM;8Tp|c z&D3!t@stTJaELWNfyws~b~W+CKLy+x@{CKo)p!b?TJsd*Q$mEzm`y=yL}5n#$Wo2D z{bJ^EQ!`GW^jpda)CVn7z(i8Om>hnvN1bA?T-6CciwBzLnYm3PsA! d9Ya??Kvlj#n-4s9oHW#su^uLSSx)s-{s3YPjAQ@+ literal 0 HcmV?d00001 diff --git a/regression/strings-smoke-tests/java_substring/test_substring.java b/regression/strings-smoke-tests/java_substring/test_substring.java new file mode 100644 index 00000000000..03a33fdbebd --- /dev/null +++ b/regression/strings-smoke-tests/java_substring/test_substring.java @@ -0,0 +1,14 @@ +public class test_substring +{ + public static void main(/*String[] argv*/) + { + String abcdef = "AbcDef"; + String cde = abcdef.substring(2,5); + char c = cde.charAt(0); + char d = cde.charAt(1); + char e = cde.charAt(2); + assert(c == 'c'); + assert(d == 'D'); + assert(e == 'e'); + } +} diff --git a/regression/strings-smoke-tests/java_trim/test.desc b/regression/strings-smoke-tests/java_trim/test.desc new file mode 100644 index 00000000000..c7a307c37ed --- /dev/null +++ b/regression/strings-smoke-tests/java_trim/test.desc @@ -0,0 +1,8 @@ +FUTURE +test_trim.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 6.* SUCCESS$ +^\[.*assertion.2\].* line 7.* FAILURE$ +-- diff --git a/regression/strings-smoke-tests/java_trim/test_trim.class b/regression/strings-smoke-tests/java_trim/test_trim.class new file mode 100644 index 0000000000000000000000000000000000000000..33b34714ae2a5b39608f6624183a4d26028930b0 GIT binary patch literal 641 zcmY*W(M}UV6g_u$yVEX9Tb2UVinf5#@*tYOVgY&q5!wD6&nx zUiUErpWpge#hQ<&ct)ri&So!+k2c@lMcqx3K|&}@gap=oG!4BxrGM%i%dY+pYO`y6 z#G#Elq0(&aP5FN>UlD{#cl)RMTh=>|qBP~~^mtx`#Ym%%$h5f(PaaK^}uF!KxU zmrIE23=bH;4;oo3lMUb)FV5hi27woxE?}ep>jpJ}`3eJ-iQ`u02h0WeF$yCH=Q|wx V0`^q#E~rt-!Sdgjb`~+`K5Ph@2&a!L*Aq4OvYBVYz322O7NLgx(C!z-|t;Ev+BTn2bxF7x){(xt- z3aU(%-u+Kn_K*eK?%1$3@~({%${ZDj#Z?gm(hpVN3!bY$v|ZU{VEYW_mhx2im?2gwzhQ`P_q&oI z-Bg}@86CEz|5}47a43|=kT1P!9*EDP?h3D0Z-u_{dJUa8*9t}F#b6*k8r%9sfO9z~ z4K!#7VSmbA;tE5GAWuSc7J#CrhA4U|QJ?>+L ze#AU|8{VhL zW5k-(YmarE7fQuk?v3QW_ToOSkPt-bfJ-`{=!n8%8WBt|(dsR&_In#5!RgB|W z96gwb;kt?}avYN?5;9;)#WZF(W*G*?b=}Z?5-Lx5cO1@ruyRJ9eFh`zvam+Eq7HihOOlrvq+?se| z%DA*IJbznnHid0$*WT#v?5_S^*U*mvhGF@gw{&|aU-Dhk-dPPy%Mh-H8@Q?A7Unr_ zYq*2E919xm;l73x`ly;=*6UR(5L8=30gDWoZmx$%S|7Wv<1(a9bKrQOVF}B0)s1>y z-4!*TA+%LIfp?fur#d1SMzUMQ+*&vA1oZ-u^PQuZ!R%Q_^7yZ6>4WEs2DRS_sCK%O z)^zeOs2x6~5qg6H2HMq5!VJ7Aoh%wlI(vpsL5?#j-UYhlopR_XE#zqY$*zo|MLWVU zWC+i6g>l?Onz$d(1ue)X#%R@&w3aNDk&~dWFqj-B*+Dvu(3{aaGI;>@Svn$3HrfUm z;ut!1{R)MCK%IY&RKh8vTv1YHxe`g$%atgZXC1sMaZBQX#6@}S5TVKe!t2wMEhtm; ze?8qoWMd!EnHKmyVtW{z>5sRdenjFB33AqcN-m)`mkDA)1d$nIw%~O_H&NoJi#$sIF>QrmIn0o_q5Qv2d;dA68?f%x8jj{nK6Qp Nwjz6Ukq#k@`~_x<)`b87 literal 0 HcmV?d00001 diff --git a/regression/strings/java_append_char/test_append_char.java b/regression/strings/java_append_char/test_append_char.java new file mode 100644 index 00000000000..90e9ab089a2 --- /dev/null +++ b/regression/strings/java_append_char/test_append_char.java @@ -0,0 +1,17 @@ +public class test_append_char +{ + public static void main(/*String[] args*/) + { + char[] diff = {'d', 'i', 'f', 'f'}; + char[] blue = {'b', 'l', 'u', 'e'}; + + StringBuilder buffer = new StringBuilder(); + + buffer.append(diff) + .append(blue); + + String tmp=buffer.toString(); + System.out.println(tmp); + assert(!tmp.equals("diffblue")); + } +} diff --git a/regression/strings/java_append_int/test.desc b/regression/strings/java_append_int/test.desc new file mode 100644 index 00000000000..d65eecf13f5 --- /dev/null +++ b/regression/strings/java_append_int/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_append_int.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 9.* FAILURE$ +-- diff --git a/regression/strings/java_append_int/test_append_int.class b/regression/strings/java_append_int/test_append_int.class new file mode 100644 index 0000000000000000000000000000000000000000..d9ee5046e7d68f976c15ed958ecd8f1ee7d75712 GIT binary patch literal 842 zcmaJ#j z4c`_7v+a0ddvMql!7EwJi9^fr2)RyV_1pk}rM(_B8peLR=vZ)w} zFxs>Fec{=Aju)*SSnn+Z1xyp>WZ<~A2w0YFU1Fpo^rF8)BN;rBkzm3~r9EjF zWn0yAp;O&0!b0Ww|I%9Ik12|k^MwqM7Vid@8xm&zWFARvRe4+HM9+rHD<#a@B6I>_ zpACT*6b(4R``pDM{|uA=5amm9hI~qZ{GR4&?i}l8Mf&-NXTIJtkmb9 zrf_cU1j?IZBwo}C$stlZHFb#ePHhOa{TbR3ipzz}5c&sXPmtw8>vdID(q|h-Bgmv2N76g`uq8OL#!Cf(Rm2qkHohNY|tr3>&vTabc4^rdp*Y31VB!3z>!!882< zo+(l)Q3>ApDBzAmnx>WQJDxjd&OLYe{pZI|0E<{tF^YnMX$4m~uBnKjAWc!4>j})@ zhKdr(31l#NCw1mOHwix1d(>DDj zhG?n$h9S1*7=j_QZrWlqXg7uXT7v1It(!JOs^ROc_ZxaAbQ3q};<&@0)LYhnCbi)N zZc98j<-JK?c>cED=?L4{cA9&l~bRJLA543*OQ=?k^;3D-~_HB#z3eU7oxSs)=!2xxrre9@-f zIDyYF-lH|0>MN>^Pc%Yr(}jE}VA##TI}&73&&E$m>;?42+wqdaa>Uv2S1<#nw~98(;SY{zFW{8`@lAJg_3er$XR+8eSNK_g{5?(_V=Lkh&|I#MLaXx%6 ua9kv}Lco3=i=kj(G?(cjyAK}widghJ)Ir34PLgp15p7v!ewj8AT=@rV@YR?A literal 0 HcmV?d00001 diff --git a/regression/strings/java_append_object/test_append_object.java b/regression/strings/java_append_object/test_append_object.java new file mode 100644 index 00000000000..e139a01679a --- /dev/null +++ b/regression/strings/java_append_object/test_append_object.java @@ -0,0 +1,17 @@ +public class test_append_object +{ + public static void main(/*String[] args*/) + { + Object diff = "diff"; + Object blue = "blue"; + + StringBuilder buffer = new StringBuilder(); + + buffer.append(diff) + .append(blue); + + String tmp=buffer.toString(); + System.out.println(tmp); + assert(!tmp.equals("diffblue")); + } +} diff --git a/regression/strings/java_append_string/test.desc b/regression/strings/java_append_string/test.desc new file mode 100644 index 00000000000..7b6ea8ccae7 --- /dev/null +++ b/regression/strings/java_append_string/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_append_string.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 12.* FAILURE$ +-- diff --git a/regression/strings/java_append_string/test_append_string.class b/regression/strings/java_append_string/test_append_string.class new file mode 100644 index 0000000000000000000000000000000000000000..f2cb5cf8bea64858805fef9f4a7b85663a237736 GIT binary patch literal 1032 zcmZ`%YfsZq7=F%f?Meru444;G5OFYIiYO|G+zkq9GNXYnq^xJ;VAsyJGx3j@$RF^t zm~4q8`rRKzd{4(%Ci>O#pr zE299GN#|l;%vh8xqtx>Fd zp6f9f7g;J;)3J_?4vw$(4|yqI=+AAni#3VQ%h@HGjWSIAE8s%TSwHg~7{yP1z$>&3 zwrr8CA#mx#O^o97HW(K7ygKXMT2g4@qkf9p5twCpU;};lF3$v|8tnFx&xNnAM({YtBn zUE8Ej)}bFGb%e~M(OpN+7j&Hs}a7Bd1)Xd1>N=N(y z#z@+PgrUU1pCr~kf@J60-+F!DS~u2nc;)5o{t+lLZIh(aq|2h)#^9%hjE0^Fae6KK zbda^^xA>*$ZxbAK4Z;Rr^Yko0Bqav~Aop^

fY~HnML@r4WxVBGHxl=b!$VK{U8rN9v6#k~S-EOzEw58w$5kzgd)f);Hk+Oxvq##Mv1pHyP+ex$7cI)m|;}hsB zzzg_WOiCh&{`VDp7vh;+p@JlvnKNg;^UZfI`|J4o4*>VEt{{zZ2@^7ICUj4CzVTak%Z8R@*6?j$Ui> zIs@Bbh%A|H(_Ll==JKx?LYh_Q42g=_=9}GCjoU8-m@Znn*=ES*URQSY_j;kJw;P43 zYn$yxQ3S@Tu5P^D&^sQUv@^&{M)NPZQnk9a!PiYeHQ;i`ePiejpA%FnvKVGao~I>k zrJAAD*9739ibq(Gu&ClOiV~JoJQ2=iEU3s}h`@TyFzQ^zQ>-wI^w~-$nXlQlWee6- zO)IZ?hGCQ`qJ&k3=&33Rnu;)9q_4b~ zr)DR8z_Ui%vbnGH!h8st=oe6H((q90>)bJIUO%lTb=>XJ1x?Nl#%UbWG`%c2BKkpA z5EO%9T1V(KN;{)HJaq{6RRD2`)`;h%>f;pvik(o&;J;e4AJA%4>i1<(6J)0W1$UU7(^pHG{9`#A~knzLz`fNgN zz*9Q~h3qh`5hNf{dQnoXU;;5L(*L)GI2sthC%U~#$U%gTu_$5G|FYRJ$hdY|lX)+B jAeF{o52<}fp)UvpzaiRx@}xk5E{s5YMU-*OQ*`|gWS!(_ diff --git a/regression/strings/java_case/test_case.java b/regression/strings/java_case/test_case.java index ce3a51814c8..309abfc07b9 100644 --- a/regression/strings/java_case/test_case.java +++ b/regression/strings/java_case/test_case.java @@ -1,16 +1,12 @@ -public class test_case { - - public static void main(String[] argv) { - - String s = new String("AbcCdE"); - String l = s.toLowerCase(); - System.out.println(l); - - String u = s.toUpperCase(); - System.out.println(u); - assert(l.equals("abccde")); - assert(u.equals("ABCCDE")); - assert(s.equalsIgnoreCase("ABccDe")); - assert(!l.equals("abccde") || !u.equals("ABCCDE")); - } +public class test_case +{ + public static void main(/*String[] argv*/) + { + String s = new String("Ab"); + String l = s.toLowerCase(); + String u = s.toUpperCase(); + assert(!l.equals("ab") || + !u.equals("AB") || + !s.equalsIgnoreCase("aB")); + } } diff --git a/regression/strings/java_char_array/test.desc b/regression/strings/java_char_array/test.desc index 8282b808b84..62cc45997ba 100644 --- a/regression/strings/java_char_array/test.desc +++ b/regression/strings/java_char_array/test.desc @@ -1,9 +1,7 @@ FUTURE test_char_array.class ---string-refine +--refine-strings ^EXIT=10$ ^SIGNAL=0$ -^\[assertion.1\] assertion at file test_char_array.java line 11: SUCCESS$ -^\[assertion.2\] assertion at file test_char_array.java line 12: SUCCESS$ -^\[assertion.3\] assertion at file test_char_array.java line 13: FAILURE$ +^\[.*assertion.1\].* line 9.* FAILURE$ -- diff --git a/regression/strings/java_char_array/test_char_array.class b/regression/strings/java_char_array/test_char_array.class index 836942da1346e6bee0164979a451b7eec1a18c9b..38a7ecf41eddf662574382383851643fa631b055 100644 GIT binary patch delta 310 zcmXwzy-osA5QV?HuzO)yby-n<1QGEUOh|M~HTGyMv@x-{5MqMFSP&WupMlUAD+*sg zVldGJd*8@L915p6GiPQ_^1V4PcKH4KF#$sMTwF3SvMxDRW|EH+qo7%JamZ+jE^CxD z>;15vn!D(l=Ixoezch_bOHzg{I~;fv;k6l@~WV`x0lfH?ay1#(HEredO+MNLX6NXy3({}7?T%qkfSrdBC6 Pi`ZD+iIV-Y7>o2D@ft1Q delta 474 zcmZvY&rTXq6vlsdhM5ZkSR5ED#XpF)D$r8vlo;DY6IVv43yq0kH4ROw}s8!C_Ep1p7OswdTRc{hfEy8;bZ^GpK*624B{L zt;V+Ig=SJSrI~KE-$y57IO-kcw1~gBV+!Um8;vE!Sce1w 'z' ); - } +public class test_char_array +{ + public static void main(/*String[] argv*/) + { + String s = "abc"; + char [] str = s.toCharArray(); + char c = str[2]; + char a = s.charAt(0); + assert(str.length != 3 || + a != 'a' || + c != 'c'); + } } diff --git a/regression/strings/java_char_array_init/test.desc b/regression/strings/java_char_array_init/test.desc index fe5ffae7238..24437881467 100644 --- a/regression/strings/java_char_array_init/test.desc +++ b/regression/strings/java_char_array_init/test.desc @@ -1,11 +1,7 @@ FUTURE test_init.class ---string-refine +--refine-strings ^EXIT=10$ ^SIGNAL=0$ -^\[assertion.1\] assertion at file test_init.java line 16: SUCCESS$ -^\[assertion.2\] assertion at file test_init.java line 17: SUCCESS$ -^\[assertion.3\] assertion at file test_init.java line 18: SUCCESS$ -^\[assertion.4\] assertion at file test_init.java line 20: SUCCESS$ -^\[assertion.5\] assertion at file test_init.java line 21: FAILURE$ +^\[.*assertion.1\].* line 14.* FAILURE$ -- diff --git a/regression/strings/java_char_array_init/test_init.class b/regression/strings/java_char_array_init/test_init.class index be3baee56bd4f0a276d7b18454f832685f146dce..ff9c64510dad8e9bdd4cffcca053a0ed768259a6 100644 GIT binary patch delta 528 zcmYL_OK;Oa6otR>BNIDzaNPjq5nd&wbpnAB3KBvBiAAdtu?SgIMWO~-Az&p4EVlfH z;#Iq12U|c&fFjti;ur91DrPKEq|rHdM(3V;?tFEAmDYamfBOM+xZ!e$y5y9L!D$U= z9DL5|>Rg$5&F9NBG%rXlxKy-!(PfE9(%jx!ulc*=_%6-U*o% z1kd8vaXXDigLW@_IUEfYaT0H&)7nj!ZEn_~vWi;{+#_}6qZ3H5i)Ap(|5o+43!kW6( z6${07G(~*WLJlh|6^{akBL~ti*s2*G2JUxzJu-vUeq;qnKeB_gAC)x7VBFus*idHX zy`r#g+Ec9VC+uAoniEQa`;K}mloQH3)S96)!QG*pwVA HOg{M+MhHx` literal 1209 zcmZuxOH&g;5dJ2~W|C!rB_TXiPy{6qAPS=LP{9C#@~{e{1stp;jJUYT!tRDD|A9xZ zaPg>Du_{<%>D{CL9gDJO!&@q;?w;;%db+>v+F$$MegNphtcqH+ama{6Zx@}Mm@s9wDo?oHOBv~r*)-In zfk8i;S^5X17~&Y#a1Zx69%vZBsD_8gNNY?(0(A_^q_8Yo!#E}w8jcf<9`-%%IJUzO z5SE5VnA9+Z$8@x8hUif>98WY%W9C#XbIWTY=Mi=(L+>P)GO}MzdTL5qC#!zzdLmC; z+C{=A%1oJd`YF-m5m~~>5799E>Q1{U;kpD_#Bm~dKE+{66jr_0{-~yCB1!*w)%6U= zb6=P;a_&_*WwB8-EcXnc+}KbD0r;k26~){u;;!7-|0U2?9MhVyXrX8wR)lLhV&#Zs z+5)dg0otZTw9uZ`(qc2cK@N$mAebCA$woRgk!GZo&Rww25{L^V!@iTof{VCBHbL1W z6#4;wboIM3oeJuc*;Ggu*_5JN*;H5xuG`r?1Qt@e2+sIMNZCbbb_YsV3E{HhB}8@* z-9~L!Of8{e8x?!d7Isnj^T1sK*VPYa-QBUO5~@$2Q(@&R^udsSE72H=)trv|{&xQn zy4GC2zlB5O*6{1Zv2ZjfSCuqZ$$7FG>WcXhsEn2{iPg3Ii0$K*u8CH;ChR zh~qsWKM~8niRUKDQV(SxiyX}ym+4gyeBYKyW^6i?BbGe zS!QK;Ac|S9d*!t{$Lg}BJjtrd8tcPbu{+!_wr^rO5{Ohj@MvWsG-5*6l%5K@3*GIC zk9Z6gN$VO3AB9ez`CB~+Hb4?Vq>^_LHMcg*z^wq)HCA% literal 951 zcmZuvT~pIQ6g}IfO-NIkwtTc&v><5OTJQ_MTIHkS$V|nDIy%J%CbT;k3=JfyKZX~4 z^I4r~XJiJSeDOyy-YorZ;5kp=mAddfN0n?)sL~@t#?pxoPt@16yZ^R;`ZZ zKV=9Tg*OaR&1rLnMBVD}weHR)cV7!IC3Z}!!!TyNt8beh%{klbY|S-%*XnFl#Km~S zH(MWGn!5u$X(pKrO0{L5@~aJ}>$doFORyzo71D66DR$SL{1M+e}{s0dt z_NO=*k2E|+y?7*j!uVIH`&iED&H<{2h&B7reiV-)LB`1Gy9byGG6VETDHZQw zcptGKEM$cSvS#VEgG8u^Kqrw|$jC#%3`I(mTY!cY#L=X#cL{Nc(8CBHV?oAcCL@;} rBlN^s_w$1`fm9la9`t?4(q~BFZ&1%`2382J2tx5iVc3;{q^rLH7FffW diff --git a/regression/strings/java_char_at/test_char_at.java b/regression/strings/java_char_at/test_char_at.java index 337c6524099..9ae02733fb8 100644 --- a/regression/strings/java_char_at/test_char_at.java +++ b/regression/strings/java_char_at/test_char_at.java @@ -1,17 +1,7 @@ public class test_char_at { - public static void main(String[] argv) { - String s = new String("Hello World!"); - char c = s.charAt(4); - StringBuilder sb = new StringBuilder(s); - sb.setCharAt(5,'-'); - s = sb.toString(); - - if(argv.length==1) - assert(c == 'o'); - else if(argv.length==2) - assert(c == 'p'); - else - assert(s.equals("Hello-World!")); - } + public static void main(/*String[] argv*/) { + String s = new String("abc"); + assert(s.charAt(2)!='c'); + } } diff --git a/regression/strings/java_code_point/test.desc b/regression/strings/java_code_point/test.desc index 35ca0cd6f4b..2b94f1fa0c0 100644 --- a/regression/strings/java_code_point/test.desc +++ b/regression/strings/java_code_point/test.desc @@ -1,11 +1,7 @@ FUTURE test_code_point.class ---string-refine -^EXIT=0$ +--refine-strings +^EXIT=10$ ^SIGNAL=0$ -^\[assertion.1\] assertion at file test_code_point.java line 5: SUCCESS$ -^\[assertion.2\] assertion at file test_code_point.java line 6: SUCCESS$ -^\[assertion.3\] assertion at file test_code_point.java line 7: SUCCESS$ -^\[assertion.4\] assertion at file test_code_point.java line 8: SUCCESS$ -^\[assertion.5\] assertion at file test_code_point.java line 11: SUCCESS$ +^\[.*assertion.1\].* line 8.* FAILURE$ -- diff --git a/regression/strings/java_code_point/test_code_point.class b/regression/strings/java_code_point/test_code_point.class index c257f0633ec65db2643a2b314c4f01928dc14660..f2f5fbad63a60c992bb2f3c9ef2d15fb99700de0 100644 GIT binary patch delta 482 zcmYL_%}*0S7{-6IU$fnA`B;fIh*%L7w`c_`il9LgPnDAv1D9sS#-OAn?Z(8DG5!T) zZzLoT51u@z$(lfdCodfRe>A>BVw}To-aPZn^S(3h{m**s_|L%+Q0IO?M8)TVW+K3* zVxtP$R2K^jF&S`)%LZ2rrVOqc#Ksb9ssRI3G}8gsxUQ*fuQf(WPts)l^>VWHG{Z!4YVSRXa8pRoTA$Pui0*=6c(k#q6i`sDOM=O5B$0V@qj{v16fK#5K;(kyb_~VNyy%~ zkZ|#$2Q^uvBzpIM;6EY8nTA9Xok@N(^UOQ%*L;+({l#CuzyAQLJPHWu^Xbpf&b5F6 zuG@%=lne%V^cgZ_q-11Raw8yXaF!86%4S!Vj0W7KBDuA{I6c}`TAFzgy^1QEQFE;_ z7w@b$*QSQ&1-ZF6s&C9j+fSpF&4y%5``iCEpHp;lK_3<4RFfy7m{&|tRn(YN+-5S# zi=O^F+*RCTN|28mFXQF<)@oyUduzQJOYSQk@GyBRO38_MmV6Ln$+-1q_Y#7FF7yOj zPuL5sna|hS&c= 2); - assert(s.offsetByCodePoints(1,2) >= 3); - StringBuilder sb = new StringBuilder(); - sb.appendCodePoint(0x10907); - assert(s.charAt(1) == sb.charAt(0)); - } +public class test_code_point +{ + public static void main(/*String[] argv*/) + { + String s = "!𐤇𐤄𐤋𐤋𐤅"; + StringBuilder sb = new StringBuilder(); + sb.appendCodePoint(0x10907); + assert(s.codePointAt(1) != 67847 || + s.codePointBefore(3) != 67847 || + s.codePointCount(1,5) < 2 || + s.offsetByCodePoints(1,2) < 3 || + s.charAt(1) != sb.charAt(0)); + } } diff --git a/regression/strings/java_compare/test.desc b/regression/strings/java_compare/test.desc index 517b208c3e4..e7444831e77 100644 --- a/regression/strings/java_compare/test.desc +++ b/regression/strings/java_compare/test.desc @@ -1,10 +1,7 @@ FUTURE test_compare.class ---string-refine +--refine-strings ^EXIT=10$ ^SIGNAL=0$ -^\[assertion.1\] assertion at file test_compare.java line 6: SUCCESS$ -^\[assertion.2\] assertion at file test_compare.java line 8: FAILURE$ -^\[assertion.3\] assertion at file test_compare.java line 11: SUCCESS$ -^\[assertion.4\] assertion at file test_compare.java line 12: FAILURE$ +^\[.*assertion.1\].* line 7.* FAILURE$ -- diff --git a/regression/strings/java_compare/test_compare.class b/regression/strings/java_compare/test_compare.class index 5616013c523bf345c4c9743a55ef57608353b3f9..67f18914ea60035f71b5a2b6d3fbf28050aa44c4 100644 GIT binary patch delta 399 zcmYL_J5K^p5QV?HEW69HsH~{?!1pT{H8Cc(T3CSEcLV9qVGXY_r&U+{z~yQW&}zg7%2x$-rZYWktH8ul06S*Uq*N z8jW($Jg?UdgPNgcJl7rO(h6K#|M$V7qpD{b6vKw8Z<~{K@tdk!0N62CHIebj1 zD^XFjB;*is6kl3#)HfNMQF+oz4HS0!s*v=ZF0l@_`G6UD!TcxvGZykhF}(fI{#ajg F{1*XBGvU54k$*G_MUsscg}ae@7y21zkCC58!HwHm^N|6#7rJ}T(wZgH3PF2 zbWF>`bpvx2=5fQo0z+ki$FYbKFAUaxpL*M4I4!wv9W}k47KdaM`u2sL{S*o zXkeMazQ|~xX`_WULpf`E-rE;$@>gmso*{p#WIJS-YW&CDGqSSBEr#eMOG1oi+`ydN3L93o7 zNh2IoXfI1YQ>#YNca)B!ZhnMzgvnNWgq(Ja!dK|8PGEdb)75rUy+wfXE(088YmBXo zV7BQ0r%3`tcM*_^lvL3?OxkOtAxG+T5^mxyEZie|FUZ;fRZUVw1==sv4NTEj`-vGD qsI+?S_)cmKa4N`;U>(8G-a}JALCY>Xvo8sAP>K)bkS?cMYJUJ&teKbq diff --git a/regression/strings/java_compare/test_compare.java b/regression/strings/java_compare/test_compare.java index 8c1d4b71a0c..0a535fd0bf3 100644 --- a/regression/strings/java_compare/test_compare.java +++ b/regression/strings/java_compare/test_compare.java @@ -1,18 +1,9 @@ -public class test_compare { - - public static void main(String[] argv) { - String s1 = "abc"; - String s2 = "aac"; - assert(s1.compareTo(s2) == 1); - - assert(s2.compareTo(argv[0]) != -1); - - String s3 = "abc"; - assert(s3.hashCode() == s1.hashCode()); - assert(s3.hashCode() == s2.hashCode()); - - /*String x = s1.intern(); - String y = s3.intern(); - assert(x == y);*/ - } +public class test_compare +{ + public static void main(/*String[] argv*/) + { + String s1 = "ab"; + String s2 = "aa"; + assert(s1.compareTo(s2) != 1); + } } diff --git a/regression/strings/java_concat/test.desc b/regression/strings/java_concat/test.desc index 8ef2898e0d7..fb784efd723 100644 --- a/regression/strings/java_concat/test.desc +++ b/regression/strings/java_concat/test.desc @@ -1,8 +1,8 @@ FUTURE test_concat.class ---string-refine +--refine-strings ^EXIT=10$ ^SIGNAL=0$ -^\[assertion.1\] assertion at file test_concat.java line 9: SUCCESS$ -^\[assertion.2\] assertion at file test_concat.java line 10: FAILURE$ +^\[.*assertion.1\].* line 10.* SUCCESS$ +^\[.*assertion.2\].* line 11.* FAILURE$ -- diff --git a/regression/strings/java_concat/test_concat.class b/regression/strings/java_concat/test_concat.class index a6d4008aa268b84833bf1df2c7b8519a5ef4090a..a69c05921f673cc68295af7dbb43ccd41e10f1a8 100644 GIT binary patch delta 373 zcmYL^yG{aO6okKBSaw-f1q2jP5WFJ@DzVW*6FS68w4q!GF+rjf#LoB(gw8^F1uY;E zqrDGc>7%G;O$>kX&txX&OwN3I9z4a5@0T~Az_!UaF`Ze1ITMw*0||q9hm#JZyjU#g zESi|k|#4Vkt0o*0yVxWxI85SDST->AW6B)-2MjE4W&%Yl{q7iw$z!xRQ_N zEjHOw@HgxmJJ+rK@=wCtR5~j;nN{%CFmO9E~WcudwY(20sZNZ^%jCcF4J uk=79z38Vgqq3KL1@*P4F45s-%w;*RbFA(e|UCEHMrJ-8;iuh3xDl@-B(>Emm delta 390 zcmYLEy-vbV7(Ms)=ay2G6s&-#;4g|;6k*ViIIw||SQo-n2q7YY#t>&;fpl{a7hk{u z5=nIT0UX_Z3H8<({gUrHIp_Poli%dh>*v!mfE)@cX0XVxq+nSEMZyb71uGt|dST56 z4eJaWDpap>Q$-3}4BNv}Suj#{w@Qp~z#7=i%M;r~M0C|F7$G*1BuH9>!)kde)91w)+m4DG1TwV0qM{b$C*9`C^zxx3K zWRBJpw5AIah?VphQt^k%oSvpLW3WRpD#pi93eqEdx6tRLpfiGh3bi(Y|K(5YkK7v? zvqb)&gjqg03Wfv}{-_T{uAaeb$_QH0hLH=gk&LGbch{(A{=_b`X~K;PxF`<-ia2mG`pGp0sjOq3jhEB delta 457 zcmY*VOG^S#7(I91&Wt&Z`N*=ghnbIDM4L!*8I)}dLRw8FQVkj+EpyvegcfdEwyr=S zq4xco7Hy^PPEiDx?{&{T=Y02G{*X)Wlb2Tj8(7!j$E=Du4GA3r<~1y6NcvzP#rs7S zOFDcUvaDkTX%(xztvxZ4IqvVUNYG#HIH#8t=jzZoaqGm>yDOG01R1Og=h`W{PP0+0 zcG~C727|dZ5-o}dm8 z%H@a91~A6()ke_Yex}{R|1sAPJdHT1fEabiWKkhgD$>xfO{x*P2|$?eAB%pUFkQud neQ$aO0Xqa^2y*~cdVnN8L;Vx*mWUFNv&j(rWxnf-XCVFs=fgcY diff --git a/regression/strings/java_contains/test_contains.java b/regression/strings/java_contains/test_contains.java index fce2ee63047..6f4c60a1a2e 100644 --- a/regression/strings/java_contains/test_contains.java +++ b/regression/strings/java_contains/test_contains.java @@ -1,10 +1,9 @@ -public class test_contains { - - public static void main(String[] argv) { - String s = new String("Hello World!"); - String u = "o W"; - String t = "W o"; - assert(s.contains(u)); - assert(s.contains(t)); - } +public class test_contains +{ + public static void main(/*String[] argv*/) + { + String s = new String("Abc"); + String u = "bc"; + assert(!s.contains(u)); + } } diff --git a/regression/strings/java_delete/test.desc b/regression/strings/java_delete/test.desc index c6c608c0955..ff41e78b3df 100644 --- a/regression/strings/java_delete/test.desc +++ b/regression/strings/java_delete/test.desc @@ -1,8 +1,7 @@ FUTURE test_delete.class ---string-refine +--refine-strings ^EXIT=10$ ^SIGNAL=0$ -^\[assertion.1\] assertion at file test_delete.java line 11: SUCCESS$ -^\[assertion.2\] assertion at file test_delete.java line 12: FAILURE$ +^\[.*assertion.1\].* line 8.* FAILURE$ -- diff --git a/regression/strings/java_delete/test_delete.class b/regression/strings/java_delete/test_delete.class index 6d30024f108aeca8a2d4587aec50ce79b2f35ddf..7036ce13c9036943ef66368d595e31b8ed88ca47 100644 GIT binary patch delta 431 zcmYL_J1<006otQY?%aFs+&P%J#``_qGsc^mM29FyP>u--3Wb{Az%7JIr$#c9kdP=< zYCph#P!Ri0f@ZCA_E~%FwaudY3TCl4$$<(&>KTv5=+jfKVX1C z!%#pFD~AI{7&YY2wwAMX>&KjD0*;~=c5T2{fL1%HNY{@WYDKc)E zVA9e+TA>%qBDG909qp-tH)AEtTy&vEq8Hs3eG0GXT=cHjPpu>bm2QnY<>a8mG8Al- zTbHmBcJo!#Z7d`!=+%mfBu#(PeQDM5HvWj-4xK8A<$S`e;BMwCcq@09E3$>quaLYX z^+>Q?CG~s~o9dcrGp?Ln`3FxD7@F~AucR=fP+t@cErwPpxBX3>ttEj>Xe-oRVG=ha WoO{f_?{C=H$3@$Pc%}B**p46foiwBX literal 1126 zcmaJ=T~8BH5IwhF+iowkwop((DI#tuP!;j3s6YWB0X3f{&;I%M^A~_Atf)vKt6*3~0NE(6$#X=8>oSbW za3cl{ITd5b$B@K$6cZ{YQBZJGMYpWJrQ$ZG6x?A*kLaE!T;FtTZ^88R4NDjdY@H!8 zW7?+wm?5a;UNMA9jv*KltEMfUHEJ8eeJR28p{AQQLq>bMx}|^83zlwg7RtVB+M7jL z*j4uR>W4MG-og`g1=9@CnX0wlUoATgwLMwa6)?s4451CEC%a?Ie7g2xa10qtCL)OQZ3^=PNt(%>U|l|OsFsF4kv26gUjlQ5ma z3%X&S+6cWy1?iR$$I}c-U4ksKNAFpilRF~fV?(#R6M(js#T?l%(NVZ$kypuShVV>R z7>74R2J;*AfsDG2ELlE9{|Za?%X_A$AgDVs6#M9HkWNNtcx)H!y9A=2Vx*NMSKuNp z(X)hprP3gsulEpmvy0$rJ{4*rT*)iRNE4Atp5By7zKQ7C4r1d?s5^*nqh~zDo9Nm` zd=K4Jm-u}&{iTzZ(*v#Pqcj%?A&M{(#H9}k5shIODsqTp7917&cP|r)Bk)(6d4M1p rs0nRUDU3kZtW@J_i^$M_f=T@R diff --git a/regression/strings/java_delete/test_delete.java b/regression/strings/java_delete/test_delete.java index c91b16c5b89..ea846cd215a 100644 --- a/regression/strings/java_delete/test_delete.java +++ b/regression/strings/java_delete/test_delete.java @@ -1,15 +1,10 @@ -public class test_delete { - - public static void main(String[] argv) { - StringBuilder s = new StringBuilder(); - s.append("Hello World!"); - s.delete(4,6); - s.deleteCharAt(1); - - String str = s.toString(); - System.out.println(str); - assert(str.equals("HllWorld!")); - assert(!str.equals("HllWorld!")); - - } +public class test_delete +{ + public static void main(/*String[] argv*/) + { + StringBuilder s = new StringBuilder("Abc"); + s.delete(1,2); + String str = s.toString(); + assert(!str.equals("Ac")); + } } diff --git a/regression/strings/java_delete_char_at/test.desc b/regression/strings/java_delete_char_at/test.desc new file mode 100644 index 00000000000..0314c606e56 --- /dev/null +++ b/regression/strings/java_delete_char_at/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_delete_char_at.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 9.* FAILURE$ +-- diff --git a/regression/strings/java_delete_char_at/test_delete_char_at.class b/regression/strings/java_delete_char_at/test_delete_char_at.class new file mode 100644 index 0000000000000000000000000000000000000000..ed3148e2f7e60738b9863b1e47c0d50650b289cc GIT binary patch literal 867 zcmaJjF9Of95wn;S&+(eTK%m~`k1|RvpM+}93)K+oJz-`=N$ju(U80-l%{3|pOL&M?2 zp>SzZ>y_^8!6e(No(dhSZ!s8?o;%cXo2Zv7PyUD2LT_5JSUC+OzNC0J;!eOY|EG|N z@>Z4Bn4QV%IJ9eq1xp0BFRYWf(B{GsC1}w*SfMYIrO(B3B{^0)#lYlJ$QJ2VCeO$x zYKLH-BoOmtlTnZ%g@qHSM_*8(+~yIK*N2Ebt>xomB(`g0liRg1)b3|!2Pm%PQ)B2K zkUm11fW~*pt3TE`WfVq5Tj57yN a;~x=^eStRPo@$mn2`I*W+1a_M^zv`0>bRr; literal 0 HcmV?d00001 diff --git a/regression/strings/java_delete_char_at/test_delete_char_at.java b/regression/strings/java_delete_char_at/test_delete_char_at.java new file mode 100644 index 00000000000..5f2c995b56b --- /dev/null +++ b/regression/strings/java_delete_char_at/test_delete_char_at.java @@ -0,0 +1,11 @@ +public class test_delete_char_at +{ + public static void main(/*String[] argv*/) + { + StringBuilder s = new StringBuilder(); + s.append("Abc"); + s.deleteCharAt(1); + String str = s.toString(); + assert(!str.equals("Ac")); + } +} diff --git a/regression/strings/java_easychair/easychair.class b/regression/strings/java_easychair/easychair.class index e47900cc0b20ba70177dddd97c472c178867b054..e6c5f66c42df9f28db774c6eb3ab463dd03b134c 100644 GIT binary patch delta 108 zcmeC-?B?V+^>5cc1_lO`jU3mREm;}Z7}yyE88{fE7`Pb}8F(1f82A|U7z7wB7=##{ z7(^LD7{nOj7{nQ}7^E5M7-Sgg8RQsx85Ac=u$XX}Ffam5Vqg#ynjFre!OP>o2oz8P J3NSG!0|3Hx4oCn1 delta 109 zcmeC??BV1%^>5cc1_lP>jU3mREm;`Y7+4tufus}zCxapb7lRrD4}%^9AA<#h0D}{Q zFhdA~2tyo$C_@%dMID1QLp_5mLob8EWC<1%Zc_$Eph*l2Lc$D_!&o$Uc^w#mB1%9J HCI)2y$e#`} diff --git a/regression/strings/java_easychair/easychair.java b/regression/strings/java_easychair/easychair.java index 55ca2a31bb3..caed962fb46 100644 --- a/regression/strings/java_easychair/easychair.java +++ b/regression/strings/java_easychair/easychair.java @@ -1,34 +1,34 @@ -public class easychair { +public class easychair +{ + public static void main(String[] argv) + { + if(argv.length > 1) + { + String str = new String(argv[1]); + if(str.length() < 40) + { + // containing "/" and containing "EasyChair" + int lastSlash = str.lastIndexOf('/'); + if(lastSlash < 0) return ; - public static void main(String[] argv) { - if(argv.length > 1){ - String str = new String(argv[1]); - if(str.length() < 40){ - - // containing "/" and containing "EasyChair" - int lastSlash = str.lastIndexOf('/'); - if(lastSlash < 0) return ; - - String rest = str.substring(lastSlash + 1); - // warning: removed this because contains is not efficient at the moment - if(! rest.contains("EasyChair")) return ; - // (2) Check that str starts with "http://" - if(! str.startsWith("http://")) return ; - // (3) Take the string between "http://" and the last "/". - // if it starts with "www." strip the "www." off - String t = str.substring("http://".length(),lastSlash - "http://".length()); - if(t.startsWith("www.")) - t = t.substring("www.".length()); - - // - //(4) Check that after stripping we have either "live.com" - // or "google.com" - if(!t.equals("live.com") && !t.equals("google.com")) - return ; - // s survived all checks - assert(false); //return true; - } - } - } + String rest = str.substring(lastSlash + 1); + // warning: removed this because contains is not efficient at the moment + if(! rest.contains("EasyChair")) return ; + // (2) Check that str starts with "http://" + if(! str.startsWith("http://")) return ; + // (3) Take the string between "http://" and the last "/". + // if it starts with "www." strip the "www." off + String t = str.substring("http://".length(),lastSlash - "http://".length()); + if(t.startsWith("www.")) + t = t.substring("www.".length()); + //(4) Check that after stripping we have either "live.com" + // or "google.com" + if(!t.equals("live.com") && !t.equals("google.com")) + return ; + // s survived all checks + assert(false); //return true; + } + } + } } diff --git a/regression/strings/java_easychair/test.desc b/regression/strings/java_easychair/test.desc index 8680af72c5a..14418a7798e 100644 --- a/regression/strings/java_easychair/test.desc +++ b/regression/strings/java_easychair/test.desc @@ -1,7 +1,7 @@ -FUTURE +THOROUGH easychair.class ---string-refine +--refine-strings ^EXIT=10$ ^SIGNAL=0$ -^\[assertion.1\] assertion at file easychair.java line 29: FAILURE$ +^\[.*assertion.1\].* line 30.* FAILURE$ -- diff --git a/regression/strings/java_empty/test.desc b/regression/strings/java_empty/test.desc index cab514b80b5..44e8e1346a9 100644 --- a/regression/strings/java_empty/test.desc +++ b/regression/strings/java_empty/test.desc @@ -1,8 +1,7 @@ FUTURE test_empty.class ---string-refine +--refine-strings ^EXIT=10$ ^SIGNAL=0$ -^\[assertion.1\] assertion at file test_empty.java line 4: SUCCESS$ -^\[assertion.2\] assertion at file test_empty.java line 5: FAILURE$ +^\[.*assertion.1\].* line 6.* FAILURE$ -- diff --git a/regression/strings/java_empty/test_empty.class b/regression/strings/java_empty/test_empty.class index f0ced290ee36f38aa83f6b0d1a25161f3594a364..147a2b628fe75ae1487deed1d827639b1d4b3295 100644 GIT binary patch delta 337 zcmYL^Jxjw-6o#LhubZYxZBnhNTCG(Ea?p(M1ObcYj0ZWWiY+RcOJ2 z?*1BofQTm-tjl}Pd3it1eQ>AF?&r_jJCL&#P^0a$SVNNrbXd|X2e`B~D*;_rHEU%) zh@+$1;{58cxH&G)t}isb@@c0P5-A7?s0$OaPQU!hyp51e`oo^u9$u=wJ1rfcnrWqz z$wrAM5^TuUl~+P=vkB_C5;7;~8B&S0Ig=h>8Mc#HgBR=(NjAp0r#{6!nc#g?cFWis z(ju9H-YKbkE|%3teUoYunOd{d++;$W=rR5X?L6Yxuh{=-f5%iIE>^f-ojh;K7JdP7 CE+hE> delta 433 zcmZXQOG^TA6vcn@a&#Qc#z&S~(_1aDs8&I=&sIhdt)>T3nM6pdpbyYW+6k>&SD=tk zdp}Y{bY~!2#D#m$|8P0y{BK`>G}Z^-Z|}ewWebaJnDGcCD6Ur3OKSQ3{$BCmo> zMW#{ip*;JGB&3G|QX#@9j$nWF1XT)F9ku#`)*-#rMekyCi1rB`^e{gH-VuIC-U{pM zs)4S9E?AS&rw*REFfi+2t^gPF`tsby z3m1-#FSvM#MH@9jr52>ANR;fw={uPQovw%obU?5+Wh~VjLax5DPcXN8ksy?sG8P~E z#~qRE>0}NZ2Qns%wNwy(+YP>FZq`6>HpA{6hTH1(lTf^uy24i?RbNCLr9Y+mx^@)& z2t1TfCX}_k-VNfz^_EIxe8})yoiNhjR|G>_V;J|agk?f?l)ZJ|#7>g*5?1qo!baW0 z3K|axK6Q>ns0fqw<_PCM>ucSxqXm9ufsdr{h)Scv?Jm!eFcpbZCL$W@;i;%T2Y84F zSm3wt_@$^^)orkq1EZkK`vl+S_#{5_jRELfC&K65%AAA(D#O$^ml_lBs7>J{u06tCg52Ppj3NJfU_!(=fW-g+ literal 0 HcmV?d00001 diff --git a/regression/strings/java_endswith/test_endswith.java b/regression/strings/java_endswith/test_endswith.java new file mode 100644 index 00000000000..fabf6f8dde0 --- /dev/null +++ b/regression/strings/java_endswith/test_endswith.java @@ -0,0 +1,9 @@ +public class test_endswith +{ + public static void main(/*String[] argv*/) + { + String s = new String("Abcd"); + String suff = "cd"; + assert(!s.endsWith(suff)); + } +} diff --git a/regression/strings/java_equal/test.desc b/regression/strings/java_equal/test.desc index d66c30b26fe..bb61dcea8ed 100644 --- a/regression/strings/java_equal/test.desc +++ b/regression/strings/java_equal/test.desc @@ -1,8 +1,7 @@ FUTURE test_equal.class ---string-refine +--refine-strings ^EXIT=10$ ^SIGNAL=0$ -^\[assertion.1\] assertion at file test_equal.java line 7: FAILURE$ -^\[assertion.2\] assertion at file test_equal.java line 8: SUCCESS$ +^\[.*assertion.1\].* line 8.* FAILURE$ -- diff --git a/regression/strings/java_equal/test_equal.class b/regression/strings/java_equal/test_equal.class index 26ee19e6cb16d81855e5204569a842332489e8e1..e0fc6db8aaf91eb799f5e02cfdd3194a232479f1 100644 GIT binary patch delta 72 zcmcb{dX<&q)W2Q(7#J8#HgbeBiLx?qF|aX+Ft9U-GjK5IGH^0DGjL5VVN&8UVPFKR ZVqg#yn!J!ngO|sF5hx%56kuYI1ON?o3Zwu4 delta 73 zcmcc0dX1Ii)W2Q(7#J9gH*$nCiLx+oF|aa-Ft9O*Gq5x0GH@_BGjL8WVN&8YWncuV aVqg#wW|+KyNrRWyfe|Po0Tf|kkOTk~K?Sac*Pan#mw9$s)uJ zW{FC&3h{th+`AcgBeyf~?cWI0z{DU9B+YW4FZBflZ99`czGNcfdX2x1|YiVq;xf{-SajacLbY(lEL7l>^P zL{QLDu=N3a0&6>UBoUkJE;GZ-|9`vtX-{d#x;Is>~C8Zr-`4a>HrJve$F9;h_7 z$GwYguX}l=sI>p;$*H4v|(Q-S8 diff --git a/regression/strings/java_float/test_float.java b/regression/strings/java_float/test_float.java index e59c631d91e..312f1aeaf10 100644 --- a/regression/strings/java_float/test_float.java +++ b/regression/strings/java_float/test_float.java @@ -1,20 +1,17 @@ -public class test_float { - - public static void main(String[] arg) { - float inf = 100.0f / 0.0f; - float minus_inf = -100.0f / 0.0f; - float nan = 0.0f / 0.0f; - String inf_string = Float.toString(inf); - String mininf_string = Float.toString(minus_inf); - String nan_string = Float.toString(nan); - //String arg1 = arg[0]; - System.out.println(nan_string); - System.out.println(inf_string); - System.out.println(mininf_string); - assert(nan_string.equals("NaN")); - assert(inf_string.equals("Infinity")); - assert(mininf_string.equals("-Infinity")); - assert(!nan_string.equals("NaN") || !inf_string.equals("Infinity") - || !mininf_string.equals("-Infinity")); - } +public class test_float +{ + public static void main(/*String[] arg*/) + { + float inf = 100.0f / 0.0f; + float minus_inf = -100.0f / 0.0f; + float nan = 0.0f / 0.0f; + String inf_string = Float.toString(inf); + String mininf_string = Float.toString(minus_inf); + String nan_string = Float.toString(nan); + System.out.println(nan_string); + System.out.println(inf_string); + System.out.println(mininf_string); + assert(!nan_string.equals("NaN") || !inf_string.equals("Infinity") + || !mininf_string.equals("-Infinity")); + } } diff --git a/regression/strings/java_hash_code/test.desc b/regression/strings/java_hash_code/test.desc new file mode 100644 index 00000000000..4f786d42f80 --- /dev/null +++ b/regression/strings/java_hash_code/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_hash_code.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 7.* FAILURE$ +-- diff --git a/regression/strings/java_hash_code/test_hash_code.class b/regression/strings/java_hash_code/test_hash_code.class new file mode 100644 index 0000000000000000000000000000000000000000..d9b3e2b2f3de9b4d49d84348b75a7e50690e3cc1 GIT binary patch literal 602 zcmY*W%TC)s6g}6EOmGYY2SR8|c_SVYY*?ZS#6v=*Wf5AbY|z9R!9Z}3?eHoK)T@a{v7{V8UuO3{K1-^M0#&>}c zLTOSaiHcL*jFNSo$XY|y3A9JZE$c|9KM3~B>|cVj)~qW+@3xNA@7768#k;1M6DLwf zgzjo8!{cA_Gz$xi67tJoi zm&l`!BL&biMg#)>I8wz$6N!Z6BbOxO3I6bp;9q zwP+Ev?z^;;&IlRza?ZVf{*QCM?H^K7!gTHjg3J? zob-fxh9+XDcv{2L52~93jGZUUKB=N{PvVu>=@9EZa?!>v8BDIlTVydgmgL*Aa2!u4 uE^0*CVn(hKe0CC4ABRKQvj@ccSjGc}{*3wW{5M}@WTLsd(H3*#;LI=X>@Jr8 literal 1108 zcmZuwOHUI~6#i~IGj}>|X=y2s+6pLYAH1|sUr02lu?ffmqY)EvXa^h|I%Z}tCjJTC z7{kWyTtshJ`=DAK_0>&mAb0z%0(W_q*RY_nhzC`T6I|Hh>Z?Xo%ssihd0P z7!>A&Feil>QgKT7)54qyA&MMFUPBniISLwz80HvZNDk?)YdD^1*WK%;t1nwdje#vP zC{t$L^rjhtx%^!QX~wP@46#|WZrt8jUpAaOf=mbNx>;xF&OMl2)1T>MmR?^STkssS zzIs^%Mi)H2`eaUj>hn29ImQ^&sj9V?Ut6#@oT_ot6xkA<;d)DEy=FXLvR6h$#t0Hf zGDL0}mSqpzvmL88NI4=H$Jq$Z2{Vq8Sd|z8mMyjuVoN5DPKMrgUDsO8-f$e-q2dl) z$1xc}8Rr?|?U4E9HKXd0Qb+W6fVkT;1NW<+Um*p5 zf(SSXs3Jr14MD>&{bv(|UZUB|p#zU-GAlHj7c`fb#C%Oz-jnd((Tg4Q;TO{QjSLGQ z%ev7|D9CDmDLBN@$B|~cACO3QrMvo)$s}EOY=6j;{xs<{iD(lYo8ZzrNWst0+C{e} RE|SX#M6Zf>k@0)V{sT&*+!Fu* diff --git a/regression/strings/java_index_of/test_index_of.java b/regression/strings/java_index_of/test_index_of.java index bbe06d279ec..b607ba79570 100644 --- a/regression/strings/java_index_of/test_index_of.java +++ b/regression/strings/java_index_of/test_index_of.java @@ -1,32 +1,10 @@ -public class test_index_of { - - public static void main(String[] argv) { - String s = "Hello World!"; - char c = 'o'; - int i = s.indexOf(c); - int j = s.lastIndexOf('o'); - int k = s.indexOf(c,5); - int l = s.lastIndexOf(c,5); - int m = s.indexOf("lo"); - int n = s.lastIndexOf("lo"); - if(argv.length == 1){ - assert(i == 4); - assert(i != 4); - } - else if(argv.length == 2){ - assert(j == 7); - assert(j != 7); - } - else if(argv.length == 3){ - assert(k == 7); - assert(k != 7); - } - else if(argv.length == 4){ - assert(l == 4); - assert(l != 4); - } else { - assert(m != 2); - assert(n != 2); - } - } +public class test_index_of +{ + public static void main(/*String[] argv*/) + { + String s = "Abc"; + String bc = "bc"; + int i = s.indexOf(bc); + assert(i != 1); + } } diff --git a/regression/strings/java_index_of_char/test.desc b/regression/strings/java_index_of_char/test.desc new file mode 100644 index 00000000000..30d179cbaaa --- /dev/null +++ b/regression/strings/java_index_of_char/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_index_of_char.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 8.* FAILURE$ +-- diff --git a/regression/strings/java_index_of_char/test_index_of_char.class b/regression/strings/java_index_of_char/test_index_of_char.class new file mode 100644 index 0000000000000000000000000000000000000000..bf4fa6e946eca6e5f9872d09a06a2f839b17d288 GIT binary patch literal 614 zcmZWmO;6iE5Pg%_*kOZP&1R^$!B?%hXrN{9`a z#Cn_Uknuj|@Y;umK|;-@S35F3THSnZ_k%HsAyob+6L{le9&ZUjAGg~+R$=x}sF@iZ z9}z^}%I+b1S=?FLVUvB>R)^<9s75N)Mnye!cAIrM!NWP=Mg>nBprB^^krnVA(S2%sIkQ5A=k(K!x}>FxpdD%awtVinv4h62iHLQ~Uv^Py5`Q PrEyX4H>`!RTy^{pE-iAY literal 0 HcmV?d00001 diff --git a/regression/strings/java_index_of_char/test_index_of_char.java b/regression/strings/java_index_of_char/test_index_of_char.java new file mode 100644 index 00000000000..92d75b3b07d --- /dev/null +++ b/regression/strings/java_index_of_char/test_index_of_char.java @@ -0,0 +1,10 @@ +public class test_index_of_char +{ + public static void main(/*String[] argv*/) + { + String s = "Abc"; + char c = 'c'; + int i = s.indexOf(c); + assert(i != 2); + } +} diff --git a/regression/strings/java_insert/test_insert.class b/regression/strings/java_insert/test_insert.class deleted file mode 100644 index 5fa0f4250618e78cf024e8037a9213b4fe087127..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1318 zcmah|TTc^F5dKct?J3I^N=t!?C@4ycN(BU!R^+bbt|c1q!7S|wENolcZcPl2`X}TM z_$($%B8k5HZ~O!5oE9jzNR!UY&U|w@-Gvy^0&hg^&zG~L5~!7 zq_``^Jt=y9h)aE6ioRO(V?e_L4AvryAs-%Uc!b9s!x}>9=16Er;t9tHL#WFr7KQDY zg?w?+EE;Q;$TF~125-{Ln+`#0qOn&D%0wY67#ilxyjUpZ)`Yz*!4$|DW}cxr`ets^ zcyGilBflO`JGPl$Psl`n+A%U)^Tu`=&+(Lw!ZFI=OJ=OY7FxPcvNK}Zlm!EhC^~P= zyd0}nmeg?tZ451E%a4~#D=TaUbwgNILBhs#jAKHINhzkJn5H8bYZ+-i)A1ZBju{=Z znB$n&u^@9=5g{rz1i>7;B>MUX;`FDQG^mb6EHSiJyN?|)Hf7rdYF~F^V2&3$ULsA$ zs3t6~ZHkOT9WJ2g6tF@YLpXXdm);614DHcWDs~QYNJyd_pSUDGb4h&lfAQXE>Rk84 z{}Oyo;plKp(epqW`2=6-4@F1h=-LV;Vl7_@vR{qPFZ%U1-t>*16EhaN!^3d#I0a7Y%y|>>?cD!A2Ls zUDO>Qw6c$;pQrqvtA07Dr#$Hh8pu}YSSmQpT}QH>=8VwnozT!jo_^>^z>i6a%o0A0 z0JhMGj|ifJvRmN!OAgM_$rQ#oZgAX`ZXddinHnrp0t7<{yJ+48SH3{0`G!Dsm?PR` QQ57Els3i9meRy#D9{|H4+W-In diff --git a/regression/strings/java_insert/test_insert.java b/regression/strings/java_insert/test_insert.java deleted file mode 100644 index 6871a51716c..00000000000 --- a/regression/strings/java_insert/test_insert.java +++ /dev/null @@ -1,19 +0,0 @@ -public class test_insert { - - public static void main(String[] argv) { - int i = 123; - long j = 123; - char c = '/'; - boolean b = true; - StringBuilder sb = new StringBuilder("hello"); - sb.insert(2,i); - sb.insert(2,c); - sb.insert(2,j); - sb.insert(2,b); - sb.insert(2,"abc"); - String s = sb.toString(); - System.out.println(s); - assert(s.equals("heabctrue123/123llo")); - assert(!s.equals("heabctrue123/123llo")); - } -} diff --git a/regression/strings/java_insert/test_insert1.class b/regression/strings/java_insert/test_insert1.class deleted file mode 100644 index 80091936cea37ba88b8d3f67bddf5ea8683f7b2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1035 zcmZuw+fEZv6kVsx%xR}n=!F6mQ9;xem2wf(wsMC^f|sO513s9cJ%PdL49-kV41dC# zPdbd2DB1aUkF9GfkY zgTOuE>dsyU65@=!@)ti4HF`z2P9oDSTFcG9rUwd$Mwm6akZSrlzsr9lAgI#;_0t9hsWX$*!7SbAcJc(m(Z_tHB94be6Q4v(0n{Uttiv#5tQ|$dI+tc zWi++F0sbzdH4rZF14J^s0sR2ceWWuyX*3YqNAw7t>xbz2Ez^aX=|-T_T%iOiI3V diff --git a/regression/strings/java_insert/test_insert1.java b/regression/strings/java_insert/test_insert1.java deleted file mode 100644 index 54e754302c5..00000000000 --- a/regression/strings/java_insert/test_insert1.java +++ /dev/null @@ -1,23 +0,0 @@ -public class test_insert1 { - - public static void main(String[] argv) { - int i = 123; - long j = 123; - char c = '/'; - boolean b = true; - StringBuilder sb = new StringBuilder("hello"); - sb.insert(2,i); - - /* - sb.insert(2,c); - sb.insert(2,j); - sb.insert(2,b); - sb.insert(2,"abc"); - */ - String s = sb.toString(); - System.out.println(s); - assert(s.equals("he123llo")); - //assert(s.equals("heabctrue123/123llo")); - //assert(!s.equals("heabctrue123/123llo")); - } -} diff --git a/regression/strings/java_insert_char/test.desc b/regression/strings/java_insert_char/test.desc new file mode 100644 index 00000000000..f5727a3a4ab --- /dev/null +++ b/regression/strings/java_insert_char/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_insert_char.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 8.* FAILURE$ +-- diff --git a/regression/strings/java_insert_char/test_insert_char.class b/regression/strings/java_insert_char/test_insert_char.class new file mode 100644 index 0000000000000000000000000000000000000000..fbf4a82070b0507614103af7be1f1d5846d7a754 GIT binary patch literal 811 zcmZWnU2hUW6g{&nyRd8vrIg|aYPIS@75u2a&=?gpG1B^g(X=nkuuR&i+eP=o|6>1u z&uRjRP4wOWr11_EHnuN!XU{!z?z#8Q@4r8O0$9gG3-h>WqME@a3mPt~a7BfcENooO z;F^V1TsLvUf~A-@EjXx|s530C@-P%ZBnN)@OoqJYi9Q3{VK6qNFQZ2cDW~?9L2nQG zf+63LzSxQndm?zF$dowb(r1|KM%;bB$v=!?a${nRA+zCnCo)!d5C^V!A=Ra&NQBX@ z^i}Cycb^B11OAEISU{0sS)H36_xGCJD3Jc%(^z_a5in@nRh(NkZlhtNi90s(D3C|q zbE%+>yST?tNd%ruyL%o415zlQE^OkyO+$P@spQt{-hptV|DcHza_)2z-UMu^`52RC z7^=?8cI^!3q=goZBpOV$O3qm#F%0oB=3aQJ*2Gh*Mytsu4%!~=kD=Tbp$tTS)-G)$ ziYY}3sl6HIcLB5X6BnYv%e3&{{%3Hs)i&cIWERAr6Gh%%3M|^lfV^B zYq*MR0)5EEk=Ibb497JMx{8_AP{ehP8w`UP;rr4HEZ6ZLTfV5<(qv$346(B1Siw9) zIGcOJ5UIMRWawYA9QmTzs7vp)B9o&bEQg`D76{}0ve<6Jq>JMw$1R3<*|3i?X*IX$ z8S<&6;>H5$2OE~7s&5$Ygts9)PwdQYiH}0ZAkqvY>Rz;kvstVKp5<&-nwD)!k0B&X z#hKG_8+UZv#XXMuIv$|JQP%NLc?OUob)s&Vq(jF%9x;q|GcF$Y{lxQJN;&+0Jsb-< z7ExhHc4J@Gx1d%yrYs~D7(}pcfgVwVyx3H!$kJkdNp^3bktvorWUxz$*os7@{T`Gi=^_4;-X{_WUg%+Z3^DV@d z_rPabi0>h>i}XxNYoX^edJdqk?xXjYDimrLnx+y|9U7JF11Dv1j1o3UNCrLh&*-S2 zmoSi@9iqZ!i}#;8@3Mr|Y9%njwM=pi9iuDmA1H+x-4 z$h4F%xBG`38NAYDzBm-hC(N}Y;l6(?V_}Vu+;F`U8N1!<2d;ds^rL(v!|1K@ zb!uLs+JX2a94sJ5Sl0WxC;a_-I|`J)|D>Eu@k~lxi#aB!KQAHIj)6J zDsOF7&TvjjXmUrQ-b5>3K1*bVDL?jw7oN&B_SCHKWHK`cn;wskQ0U4~1+qJ>mWL7b z`GRM+hZX(>^ZZpPTh#61T@0jq&2f=WC0>cwM0E)Is)@*RG)EvIg{3L=9X~bru6_(- zHy0Zs{-PSsRtHGD;b6AD!8$^IEtec1^%?17*t&9g zixCf_eb*PI_dBr{xknza99r)!9ka+YEQoj2v;2cyf4wctY!v;fP47GLE>(e0U5?20SG!)#^aUTyDa^uWb?L%%y zf0%~680O68IBsaHi;1O%?J*S1?M7)L=Cq+YL&e;l@YesAphn%Z;(2p2kRVh1U2J*b zU*v{O)JwG8?3i-HqZ445cX;Rq+!@V?78=Fmp#AS*g)S*aXUB2{F=TorK-Ysj$vOHJ zNi)*Pav$uI2*fv^Rk??dr0n-Wh2#tvQzFsZGJ}j z82L3r>ml<2nG@){eN259;L-qmiQuUsG|~nXEJ4LGm8y}YK%NZPPt+7F4qfL)4Auv% ifEi=DhwL#F`6J}S7o^A7XT$|g5|aK%w0C|`y7(LCDZnTI literal 0 HcmV?d00001 diff --git a/regression/strings/java_insert_multiple/test_insert_multiple.java b/regression/strings/java_insert_multiple/test_insert_multiple.java new file mode 100644 index 00000000000..c976ddd807f --- /dev/null +++ b/regression/strings/java_insert_multiple/test_insert_multiple.java @@ -0,0 +1,11 @@ +public class test_insert_multiple +{ + public static void main(/*String[] argv*/) + { + StringBuilder sb = new StringBuilder("ad"); + sb.insert(1, 'c'); + sb.insert(1, "b"); + String s = sb.toString(); + assert(!s.equals("abcd")); + } +} diff --git a/regression/strings/java_insert_string/test.desc b/regression/strings/java_insert_string/test.desc new file mode 100644 index 00000000000..91e13cefab1 --- /dev/null +++ b/regression/strings/java_insert_string/test.desc @@ -0,0 +1,7 @@ +FUTURE +test_insert_string.class +--refine-strings +^EXIT=10$ +^SIGNAL=0$ +^\[.*assertion.1\].* line 8.* FAILURE$ +-- diff --git a/regression/strings/java_insert_string/test_insert_string.class b/regression/strings/java_insert_string/test_insert_string.class new file mode 100644 index 0000000000000000000000000000000000000000..be8f7ad0f79126964af9df57d0e5500d86d69cdd GIT binary patch literal 841 zcmZuv+iuf95IyT$>^KfdoiquT0)+xe3JI5Rky0U`fP@I}5Cm#ps*SxWTU-Zhhkv0z zz%w8v5|!Yce*!VIU*?2gZzJ#%KpKYxGw4xo)YCh}O(aoWHc6B^DMSXK8qb)3&2 zhcyEiOkBhz9W@hKMXsA@U|q*$hT<9zLlH!B;D--o$ormf8Q3;MdPDj$y33HL)n73r zHwUg@$akeLo)7o?B6z9Dl-TFeXUO#;?!0}*-^DN)(s6~s*l@ff8M8MS299_v)uT!z z!e~eOs`O461=8Pb?(q-Yf{h}jRowEpzuW4?$p=H}xgucDxT`o#iu#U)7Oq;jhU*pz zSRyaH@3>Uh!VR<;s&kq9(=Hzc!GLt^MFTo+TDXPV42Ai-7yUiqM1MgOM-0og?wmIP zJ8DwtNm~rf+LQk<7NDcvIy9|lFcmM=>I+0-q{aIo_riaQPfT{|w6*-)(xykNWhlEM zl!0((6QD&!LrTzIx3NlpNS^*AR;a2GQj`Eq2Sqwd^tD1aqdV0YgMC&+EYq2eL52*< zGwK_9s!^_W2yM$wjFEiWNZP3p(ytpM=-n?c4p3URGb5NEkv&9qYYgj$64heSGEx+$ zV3NEI9Tga8Qi%$oS+HMd>Zs~CPVk9Y)pqOzSh8~?96NxX{DfrUD~!4B)U47;L9_0u KmQKcHPyGQmzOiip literal 0 HcmV?d00001 diff --git a/regression/strings/java_insert_string/test_insert_string.java b/regression/strings/java_insert_string/test_insert_string.java new file mode 100644 index 00000000000..028a348122b --- /dev/null +++ b/regression/strings/java_insert_string/test_insert_string.java @@ -0,0 +1,10 @@ +public class test_insert_string +{ + public static void main(/*String[] argv*/) + { + StringBuilder sb = new StringBuilder("ad"); + sb.insert(1, "bc"); + String s = sb.toString(); + assert(!s.equals("abcd")); + } +} diff --git a/regression/strings/java_int/test.desc b/regression/strings/java_int/test.desc deleted file mode 100644 index ae60dd78af0..00000000000 --- a/regression/strings/java_int/test.desc +++ /dev/null @@ -1,13 +0,0 @@ -FUTURE -test_int.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -^\[assertion.1\] assertion at file test_int.java line 8: SUCCESS$ -^\[assertion.2\] assertion at file test_int.java line 9: SUCCESS$ -^\[assertion.3\] assertion at file test_int.java line 12: SUCCESS$ -^\[assertion.4\] assertion at file test_int.java line 15: SUCCESS$ -^\[assertion.5\] assertion at file test_int.java line 18: SUCCESS$ -^\[assertion.6\] assertion at file test_int.java line 21: SUCCESS$ -^\[assertion.7\] assertion at file test_int.java line 23: FAILURE$ --- diff --git a/regression/strings/java_int/test_int.class b/regression/strings/java_int/test_int.class deleted file mode 100644 index 643d7eca09cb890b7b49705679a2c8406c96efa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1140 zcmZuwOHUJF6g^)%ueMV7Zru1Y+~J0(cczq9bo0ILJ?Gwg&dirz?>_;^;F2E-y8Y-uuOFvz z#)lU4i8$*Ak8TO)oXB|z2`}*at8+<8=yx(xA};tbfI$&M4ADN-vNY4yD~5GNx72)D zD>ATU24Pw^bbFS;n@HYa;1()HjUlwC8`{n4T3$16JINGSQ+0!(EpcygRehuml~toO zv}BvQQJQjq!6jQQJh-8*yZIu9MT{^=(}nUOzkjJxH4EA`-C+ybnq{x(hCS$z$%vv= zL|UeSvxJi|iZK~sL>Sr|)#mCWTs6&#NiB_}Gg%qqxX8c{WYZY}P9RGGHD4&on8Xxy zP_HCnTE+}$Ql&w8E5E80Y|`gHQ~i}#o0K8kz~&5FD{0h+WLN6pSR$AFS07Tja9=g& zs1Qd93j|qLO-myNhFIcXKr+V=uq)TK$8};sdstP=*0Jmp-g6zRYlFx zO|5t&8#!cGDL_syqnAD;g+4K+v^zr6$qUi}t+dAI7N?!j&iC(vy>SxJMyudHGWc); z?R2J8wgC^_fuCVtau1%x6t@HKOp2#E{fRR8cyegoHto zXC49MAY+AeFCl~{r213R{W&TAl4Sfyg6@-~9mJM^_?tjHp+%fxjC_b5ppzY-hwimg u7o8@EyYtAgQP&zE5=F}nLYok|SKz$wz%@Fo+vil_;R#-LOpdz)bo~Lq)9aJ~ diff --git a/regression/strings/java_int/test_int.java b/regression/strings/java_int/test_int.java deleted file mode 100644 index 620ae638dce..00000000000 --- a/regression/strings/java_int/test_int.java +++ /dev/null @@ -1,25 +0,0 @@ -public class test_int { - - public static void main(String[] argv) { - String s = Integer.toString(2345); - char c = s.charAt(1); - char d = s.charAt(2); - char e = s.charAt(3); - assert(c == '3'); - assert(d == '4'); - - int i = Integer.parseInt("1234"); - assert(i == 1234); - - String t = Integer.toString(-2345); - assert(t.charAt(0) == '-'); - - int j = Integer.parseInt("-4231"); - assert(j == -4231); - - String u = Integer.toHexString(43981); - assert(u.equals("abcd")); - - assert(e == '2' || i < 1234 || t.charAt(0) != '-' || j != -4231 || !u.equals("abcd")); - } -} diff --git a/regression/strings/java_prefix/test.desc b/regression/strings/java_prefix/test.desc deleted file mode 100644 index 175f934ca1d..00000000000 --- a/regression/strings/java_prefix/test.desc +++ /dev/null @@ -1,10 +0,0 @@ -FUTURE -test_prefix.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -^\[assertion.1\] assertion at file test_prefix.java line 14: SUCCESS$ -^\[assertion.2\] assertion at file test_prefix.java line 16: FAILURE$ -^\[assertion.3\] assertion at file test_prefix.java line 18: SUCCESS$ -^\[assertion.4\] assertion at file test_prefix.java line 20: FAILURE$ --- diff --git a/regression/strings/java_prefix/test_prefix.class b/regression/strings/java_prefix/test_prefix.class deleted file mode 100644 index 6f5f4025932b51a8fdcec8d94d4d5032d883ee5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 933 zcmZ`%%Wl&^6g`vJvEw*RaBwh`LIVNvC=IW60il8x5J)L30*#t3kdv6=;@Xw%ApQV; zfvmb?4M>edrLgC7_yFLJMH)asvgY2IbMBpc&iLDpFCzfgv7{h_GZN0qm{$-(LB=^5 z=XqL`ae>E+Nu+T}LP8>W+~A%am>tLJF|am6qHeo(xWW)G zl{XlKHLqteWE!?>J?`&zEdMDd6R>OAEELDw`wTRlY0^7HGN8^*lVV?kc zsx}Jr*ctjYSk~ZzDT{+~7im3CyE%%CqF5P%edI*wv?iiMh9vShK{=;>r_uz)cZY~= zYVje2h9<68wZs9WmFfbm%R*I?X`5UYD?0ov-S` z0JkSVVhogZae(3kkj6k(7vCc_2KcnGXxf{YpyCRAPFBJ#6Lrs UOfvS3cNGy!-{J0_js~6k1sUzW1ONa4 diff --git a/regression/strings/java_prefix/test_prefix.java b/regression/strings/java_prefix/test_prefix.java deleted file mode 100644 index c9b5fa72fcf..00000000000 --- a/regression/strings/java_prefix/test_prefix.java +++ /dev/null @@ -1,23 +0,0 @@ -public class test_prefix { - - public static void main(String[] argv) { - String s = new String("Hello World!"); - //String t = new String("Hello"); - //String u = new String("Wello"); - String u = "Wello"; - boolean b = s.startsWith("Hello"); - //boolean c = s.startsWith("Wello"); - //boolean b = s.startsWith(t); - boolean c = s.startsWith(u); - boolean d = s.startsWith("lo",3); - if(argv.length == 1){ - assert(b); - } else if(argv.length == 2){ - assert(c); - } else if(argv.length == 3){ - assert(d); - } else if(argv.length == 4){ - assert(!d); - } - } -} diff --git a/regression/strings/java_replace/test.desc b/regression/strings/java_replace/test.desc deleted file mode 100644 index 1e89ebe37b4..00000000000 --- a/regression/strings/java_replace/test.desc +++ /dev/null @@ -1,8 +0,0 @@ -FUTURE -test_replace.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -^\[assertion.1\] assertion at file test_replace.java line 6: SUCCESS$ -^\[assertion.2\] assertion at file test_replace.java line 8: FAILURE$ --- diff --git a/regression/strings/java_replace/test_replace.class b/regression/strings/java_replace/test_replace.class deleted file mode 100644 index c795826dc15e95c6e64931bc9afb74e3617f8687..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 904 zcmZuvYi|-k6g|UhV7mx~wqg|ptqK&uTI-9(*r28+R8258tsl$+lV~aL$K@!l z$iouHRRu9*W4MOv3JNH4loTwZ%yEMuy`(vguwC6UoyWSPwG7c=V7m;Fb=}n6hYZ0& z@ijxJZgm7hqM@7Oxz}w8`;|HadBk zR#8#KO%+MZj-y^~+Z#n!aEl=`0ogd}`H5{?Hpi-p+gRhcqv9?q^n98K$2}GI@!$lF z7p;BKb{Xai|L>ZQyO6@v>&1VQNMP~a(+uYn#t67pBnPIu{^+=(OI}!>EINYIt?EmX z*(I@s)~%75eupQo8F)`78RSu7qCnjs--%pDIJzx5$AXYqu15hfeHVH9ND2CAESZtA z(k=)l9ie%SPFY$Rt>MxT?5j+~Jk1gRlF_eQz**YM)KBy@Nb9ph1a?xvAwrGiq?Pmr z2yY!A(#Kpm#RrJ?F>{F6&JfDa1I&~MP^Y7xCsA20;FnvZfHR zP((%GH%c7mXk_Vr@tFUbPZUU{5g*`8A3XF0q2M<}Cg?}aNTe_V@kg@d^M3IQe*s01 Bzfk}H diff --git a/regression/strings/java_replace/test_replace.java b/regression/strings/java_replace/test_replace.java deleted file mode 100644 index 342bf9afddc..00000000000 --- a/regression/strings/java_replace/test_replace.java +++ /dev/null @@ -1,10 +0,0 @@ -public class test_replace { - - public static void main(String[] argv) { - String s = new String("Hello World!"); - String t = s.replace('o','u'); - assert(t.equals("Hellu Wurld!")); - System.out.println(t); - assert(!t.equals("Hellu Wurld!")); - } -} diff --git a/regression/strings/java_set_length/test.desc b/regression/strings/java_set_length/test.desc deleted file mode 100644 index 43f82a648fd..00000000000 --- a/regression/strings/java_set_length/test.desc +++ /dev/null @@ -1,9 +0,0 @@ -FUTURE -test_set_length.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -^\[assertion.1\] assertion at file test_set_length.java line 8: SUCCESS$ -^\[assertion.2\] assertion at file test_set_length.java line 9: SUCCESS$ -^\[assertion.3\] assertion at file test_set_length.java line 10: FAILURE$ --- diff --git a/regression/strings/java_set_length/test_set_length.class b/regression/strings/java_set_length/test_set_length.class deleted file mode 100644 index 8836640967a8736f8ecdfc31c509c8f67e5cdc31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 887 zcmZ`%TW=CU6#j+<29~8=xfL%|t5uhRMXmJ`8>6BoO{hL#G~h$Cz=UqyE@pS|$22iM z`m839*hJs`Pa4l`OHtI9GiSazm+w1gzW@C46~G$q=$J!^V=;lVIwCly%#t$alQ3{W z$1*N*T+)$5NnI{;SUSpB;ixcVm+c@BzH|m&@W=`5jw^Z$tj!SLa6CueW6-Sf3x;TY z&=U;v4aXBthkG62KUcx@uxC3SL&190*tOrd)}2NS`MeShE^xPf)jHPe^lrh!|y&0tP5pLKRcSN;JV z3T4P!|5l$QDUDDGP0HF-14+oiBr9i?|4w7j18Ms*c9pG^`lrCE1r zr?iot2pnJZj`h+a;$8!v2fk; z7RD>SReQH)H3K~9Rx!t*E!65K{CcI)a%=pVkZd`hd;X>uly6pBqHc3{O7a>QLY5)> ze~-t<7zVZJ@-6W`Z{QB@QiJ@iuqNr$Qiwx@_P{l(7i&$bvcBx)ecX-V|lR9>VthJg=B4(H@^ziIl>SRRH zp!tmsN2X9b2PA~<`IhT@>%xD_FxZQpu2!SwCy+!}@JgMY0$rrdJ>hcu)C#&kzeOMD z9c*BP9#@*)Axq|@m$XwrHOSJMqth@&MloU@fPIlbT%a`?BpG73h)cAW&|g%lQ2b~f zMLuEg5TVxxP|D+}a2t{JaWgy}#8i}m8IgyS8f4ng*1jUPkIY0$Z=-J?eTOipIR2xP z?r$T}Bb_{pmij`0J`+0a719|-KO!_(ltxieqWmoSuuA_>6>)q(0+$Jyfbs{cDuz{D v8Tw80Yq)yq!CWvbkV<2qjnqEW@MnaTZ-{jpb_|hZ5rpE)(zZMuLKyi6M=96L diff --git a/regression/strings/java_string_builder/test_string_builder.java b/regression/strings/java_string_builder/test_string_builder.java deleted file mode 100644 index 1d76b34e9f8..00000000000 --- a/regression/strings/java_string_builder/test_string_builder.java +++ /dev/null @@ -1,16 +0,0 @@ -public class test_string_builder { - public static void main(String[] argv) { - if(argv.length > 2) { - StringBuilder tmp = new StringBuilder(); - tmp.append("prefix "); - tmp.append(argv[1]); - tmp.append(" middle ").append(argv[2]).append(" end"); - //StringBuilder tmp1 = tmp.append(argv[2]); - //tmp1.append(" end"); - String r = tmp.toString(); - assert(r.startsWith("pref")); - assert(r.endsWith("end")); - assert(r.startsWith("pr3f")); - } - } -} diff --git a/regression/strings/java_string_builder_insert/test.desc b/regression/strings/java_string_builder_insert/test.desc deleted file mode 100644 index 2655f846da1..00000000000 --- a/regression/strings/java_string_builder_insert/test.desc +++ /dev/null @@ -1,8 +0,0 @@ -FUTURE -test_insert.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -^\[assertion.1\] assertion at file test_insert.java line 17: SUCCESS$ -^\[assertion.2\] assertion at file test_insert.java line 18: FAILURE$ --- diff --git a/regression/strings/java_string_builder_insert/test_insert.class b/regression/strings/java_string_builder_insert/test_insert.class deleted file mode 100644 index 69a32d7f93fa8cbebd4e1f6c84f79c41463bb3b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1049 zcmZuwT~8B16g|_Aop!sWYg<1206|e&3RFcJe$32GBpy7GK^-ah27EI6Bv_zGGturXorfvE& z48ctHHAATAR0Ts~$+X2vy|yXbR}xGIHN&(Sx-uI}+r~#DZyEMhzT~^6y;YEf@se*; z-Y*+FO+3dqY38`k5Sgx6M^~sNr|wq7GgA`kzVQ6FrY&WSNlFbVq#3%;)6dsUt14WQ z+W*OMt*XRLXqdzU4G-~%V@g8-(;SaA%*c~VNHWA0g=IOd3eutB31%63+T?S`4SDLi z4zb5h>EW2uFpnasY!|%P+!hs|A+T{a-)aIwXXgK%QCc1u`ZCWqirEXGBYy>ImG2yr zr85_Sgg7Oq^x5-8jo!_vlc>%Xt?A@n(v$c^Ba9jqq?-EArWyE-1X=W+iuh1BEbpB9 zmeoR*<|EN=K+&Qhq7kSH&vZrgq=EGEew_|zg4QuWv#8VPGQCGW1nq(#8Awy?q_19D z8Li>reXws5h%SmsGszG|H+pCFMctXt)rA_Lc*@&N*C z$>2Uh%Ok;D1K~F#4Ja#n;G+#h_7L4gdNipv5ZguU0NUC<;=fO)zqHd*PM|4g5^>sx z>3W4Eaq<))4^fh)l7l#gC^Lox{h&Ig$mc3KeMgAPRFy#B5UU(lIIePB>!Q-$6Z;cQ kpFlE&js_CD;GwSw1-~QOzWlfsk}Qlsd{%a>uc__&KWVw%^#A|> diff --git a/regression/strings/java_string_builder_insert/test_insert.java b/regression/strings/java_string_builder_insert/test_insert.java deleted file mode 100644 index 1fac897c5ed..00000000000 --- a/regression/strings/java_string_builder_insert/test_insert.java +++ /dev/null @@ -1,20 +0,0 @@ -public class test_insert { - - public static void main(String[] argv) - { - char [] str = new char[5]; - str[0] = 'H'; - str[1] = 'e'; - str[2] = 'l'; - str[3] = 'l'; - str[4] = 'o'; - - - StringBuilder sb = new StringBuilder(" world"); - sb.insert(0,str); - String s = sb.toString(); - System.out.println(s); - assert(s.equals("Hello world")); - assert(!s.equals("Hello world")); - } -} diff --git a/regression/strings/java_string_builder_length/test.desc b/regression/strings/java_string_builder_length/test.desc deleted file mode 100644 index c4720992571..00000000000 --- a/regression/strings/java_string_builder_length/test.desc +++ /dev/null @@ -1,8 +0,0 @@ -FUTURE -test_sb_length.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -\[assertion.1\] assertion at file test_sb_length.java line 6: SUCCESS$ -\[assertion.2\] assertion at file test_sb_length.java line 8: FAILURE$ --- diff --git a/regression/strings/java_string_builder_length/test_sb_length.class b/regression/strings/java_string_builder_length/test_sb_length.class deleted file mode 100644 index 586e8f71935b9b16a50d4a4a6ad14c4069667c5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 791 zcmZuv&rcIk5dPkFyT7`H((4HUL5zx!m=rzKNWcSm?LOV z9Ojj`VB)$1TY(lG+`vr}w-`!`JdQ<_$Zi-vmN9Py!e?N+491!aWpbY(<1M{l(AT@Z zU>I-6P(1A)v_$k=fhlpoWymn?y=?6Bx4a(kuv2d)kqkSlsxaS7c>B#3@1=NB$Y8Ct zgOlb?v)hl_VpFPCr9{NZUfkLXMA%7Quc&@53YcJ+`M39@z6^X3kXegw9BMV3A)KH=IOL~x;`tE)v)Ac zK*BLWZ;`&{$TG6o>JaR+0-{8(kp>z43X_;3UqRnfsYZ752-;3DGlbr#6|(~v+h1TF zVzM@XRj@xGcLaN92s!bMJ{(&0yQp#NU4b&{7CjbBd diff --git a/regression/strings/java_string_builder_length/test_sb_length.java b/regression/strings/java_string_builder_length/test_sb_length.java deleted file mode 100644 index 652b72cdc90..00000000000 --- a/regression/strings/java_string_builder_length/test_sb_length.java +++ /dev/null @@ -1,11 +0,0 @@ -public class test_sb_length { - public static void main(String[] argv) { - StringBuilder tmp = new StringBuilder("prefix"); - //tmp.append("prefix"); - tmp.append("end"); - assert(tmp.length() == 9); - if(argv.length > 1) { - assert(tmp.length() == 12); - } - } -} diff --git a/regression/strings/java_strlen/test.desc b/regression/strings/java_strlen/test.desc deleted file mode 100644 index b98e6f76f0a..00000000000 --- a/regression/strings/java_strlen/test.desc +++ /dev/null @@ -1,8 +0,0 @@ -FUTURE -test_length.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -^\[assertion.1\] assertion at file test_length.java line 10: SUCCESS$ -^\[assertion.2\] assertion at file test_length.java line 11: FAILURE$ --- diff --git a/regression/strings/java_strlen/test_length.class b/regression/strings/java_strlen/test_length.class deleted file mode 100644 index 7f1c10c02ca3c0b61fb85561752aa7e23c0b36f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 864 zcmZuvU2hUW6g{)-7t3NPNTn*;D&j)1XsbSGZEUb6O{gYfOj;kzvP@v>cGv7K{+Pb_ zV&bzJA+bq)_eWXpP$^YOcJIubIrrWcl!+6@C`+|*z(Km<~A3FT0E2?E;9>s4w?swzfvZ!YwgIU7=t<9kHxaS38ziMI$H50e6Y@&|a zCeC4op)kqW7>nEt!ysfxooS=tj)@hl{?+7pdyhLY`7=coL*AOMRXsWQ$g?f7&@<(h| z<(2K)0Lpr8X#n+sJTDgq(C#Z=pdTQcS2Dd1NF5@%GlcQu6b#OQqOmk;T&9+Q3 1) { - String t = argv[1]; - int i = t.length(); - String u = t.concat(s); - char c = u.charAt(i); - assert(c == 'h'); - assert(c == 'o'); - } - } -} diff --git a/regression/strings/java_substring/test.desc b/regression/strings/java_substring/test.desc deleted file mode 100644 index bd54a8204fe..00000000000 --- a/regression/strings/java_substring/test.desc +++ /dev/null @@ -1,10 +0,0 @@ -FUTURE -test_substring.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -^\[assertion.1\] assertion at file test_substring.java line 12: SUCCESS$ -^\[assertion.2\] assertion at file test_substring.java line 13: FAILURE$ -^\[assertion.3\] assertion at file test_substring.java line 20: SUCCESS$ -^\[assertion.4\] assertion at file test_substring.java line 21: FAILURE$ --- diff --git a/regression/strings/java_substring/test_substring.class b/regression/strings/java_substring/test_substring.class deleted file mode 100644 index e6532aca43e8ec0108d5f9108ccd271907039b70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1051 zcmbVK-%ry}7(I9EkI@wv%poEuD9U~yQxG(P5D+xZfSSyZfDfkI8Yqqq+fLv7BYfmV z5{*2o$%vZZyML5;ZjlYtCzIxDd+#~tyXSoO$Iq_^048wDfQfzs1Gpf|MOg;hU|>kc zB?H>g-sL!kF{tB;fvXtNkrqe}TfT35fm3t+MaQ>FRl6b})&#T}$8~~PfoM9jBA_hP zDz-r9lH=MB>suw;dm_Qy*s>f~peOxwY14XX<*Syvo-YQT@XW85{7_^}s+#CTftPrCe+m_d~T9)xMxDg8$T$W+I`P2Vqrsc$I1Bv=l=h ztqt;T1aV$66L*--3iDZIHWt&_pyh4yUJ?D85xhYPAIM5kbq?ww37U=`9cTFn!3YnD zj2tbo@gZ)v0KH9sAb<)noNG>CGK?DNPQqv)z5`v^gA)A=wdLS=9J0HLNc)@|T3=}J F{4e6h&lUgx diff --git a/regression/strings/java_substring/test_substring.java b/regression/strings/java_substring/test_substring.java deleted file mode 100644 index 8a2ac883cca..00000000000 --- a/regression/strings/java_substring/test_substring.java +++ /dev/null @@ -1,27 +0,0 @@ -public class test_substring { - - public static void main(String[] argv) { - if(argv.length > 1) { - String t = argv[1]; - - if(t.length() == 6) { - String u = t.substring(2,4); - char c = u.charAt(1); - char d = t.charAt(3); - char e = t.charAt(4); - assert(c == d); - assert(c == e); - } - else if(t.length() == 5){ - CharSequence u = t.subSequence(2,4); - char c = u.charAt(1); - char d = t.charAt(3); - char e = t.charAt(4); - assert(c == d); - assert(c == e); - } - - - } - } -} diff --git a/regression/strings/java_suffix/test.desc b/regression/strings/java_suffix/test.desc deleted file mode 100644 index 2740e87d6e4..00000000000 --- a/regression/strings/java_suffix/test.desc +++ /dev/null @@ -1,8 +0,0 @@ -FUTURE -test_suffix.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -^\[assertion.1\] assertion at file test_suffix.java line 12: SUCCESS$ -^\[assertion.2\] assertion at file test_suffix.java line 13: FAILURE$ --- diff --git a/regression/strings/java_suffix/test_suffix.class b/regression/strings/java_suffix/test_suffix.class deleted file mode 100644 index 557acd02653a0558f2ddb5117649f5cdd387e77e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 811 zcmZ`%(M}UV6g|^!JKOD+*4APbixf}`1*#H#kq`)Kd?@-*V*@^zZFj)IW!LOZjUV9` z^ap%alQxk=-~A}{&ZbZ_m~8IcJ#*&XbMDN~U*En1SjW1BDO5RTP28}Mz?_MiiFuta z=&+c9jhh^|ELfU%+d>^n9Lo%)MJI|xsAS+rk7VR@J>fF2eTMXg^rhNlNY5FImIq#jO=lF-swhE z$zX2uym5W29rVMVcp`PRf)bH>9rX_mGH=qZ}n1x^{t^^5(R z!gr&NRB!%6p;23razZsGIk%LKC7Bi%HmHxI!_Z8YL zBk`Mn6i0>QDt(Of7KwcA%*6dzEukgYL*xeF#wQrbugFYVojTGbQ%K~twC|Z%$@M>U CNTL-0 diff --git a/regression/strings/java_suffix/test_suffix.java b/regression/strings/java_suffix/test_suffix.java deleted file mode 100644 index f61b0b8ba36..00000000000 --- a/regression/strings/java_suffix/test_suffix.java +++ /dev/null @@ -1,15 +0,0 @@ -public class test_suffix { - - public static void main(String[] argv) { - String s = new String("Hello World!"); - //String t = new String("Hello"); - //String u = new String("Wello"); - String u = "Wello!"; - boolean b = s.endsWith("World!"); - //boolean c = s.startsWith("Wello"); - //boolean b = s.startsWith(t); - boolean c = s.startsWith(u); - assert(b); - assert(c); - } -} diff --git a/regression/strings/java_trim/test.desc b/regression/strings/java_trim/test.desc deleted file mode 100644 index 7c0f1a87978..00000000000 --- a/regression/strings/java_trim/test.desc +++ /dev/null @@ -1,8 +0,0 @@ -FUTURE -test_trim.class ---string-refine -^EXIT=10$ -^SIGNAL=0$ -^\[assertion.1\] assertion at file test_trim.java line 5: SUCCESS$ -^\[assertion.2\] assertion at file test_trim.java line 6: FAILURE$ --- diff --git a/regression/strings/java_trim/test_trim.class b/regression/strings/java_trim/test_trim.class deleted file mode 100644 index 8e6a923dcbc867d6e06db7e6b4ad880270c3084d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 730 zcmZWn%Wl&^6g}fd#&Mk{Bxwkb5*JGA^pyny7OfDdz$z_^ASB8Hjh#{D)^Vuq@G<#; zt^p~PK!QF01mccM5-MbC=FWYbd(WBq`TOg401wcy;ozo)TQ+WExdGLoZekA)0?1-VT7sg@sghBV(Zy1dIVP7(oyJ0L3 zM+09buT?Sy1|p0Z8s59^iTEfwk%*5wy(|gi<6Tu)>SZE0JrE!Ae2#SnYcGiYg4?~} zC<)}tP(dwbGR@vo>0n1eIVhvTP;_14`flJ7iFF4a+73!sWH58LgAHslH0RBqO&PsN zl3_v<3O{fOXNJzP