Skip to content

Commit 7635af5

Browse files
Owen Jonestautschnig
Owen Jones
authored andcommitted
Make Long.parseLong work
Note the tests are marked THOROUGH as they take a little too long. This should be solved by #702.
1 parent 963213b commit 7635af5

18 files changed

+115
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
THOROUGH
2+
test_parselong.class
3+
--refine-strings
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[.*assertion.1\].* line 8.* SUCCESS$
7+
^\[.*assertion.2\].* line 9.* FAILURE$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
public class test_parselong
2+
{
3+
public static void main(String[] args)
4+
{
5+
// 2^40
6+
String str = new String("1099511627776");
7+
long parsed = Long.parseLong(str);
8+
assert(parsed == 1099511627776L);
9+
assert(parsed != 1099511627776L);
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
THOROUGH
2+
test_parselong.class
3+
--refine-strings
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[.*assertion.1\].* line 7.* SUCCESS$
7+
^\[.*assertion.2\].* line 8.* FAILURE$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
public class test_parselong
2+
{
3+
public static void main(String[] args)
4+
{
5+
String str = new String("+00AbCdEf0123");
6+
long parsed = Long.parseLong(str, 16);
7+
assert(parsed == 737894400291L);
8+
assert(parsed != 737894400291L);
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
THOROUGH
2+
test_parselong.class
3+
--refine-strings
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[.*assertion.1\].* line 8.* SUCCESS$
7+
^\[.*assertion.2\].* line 9.* FAILURE$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
public class test_parselong
2+
{
3+
public static void main(String[] args)
4+
{
5+
// -2^41
6+
String str = new String("-2199023255552");
7+
long parsed = Long.parseLong(str, 10);
8+
assert(parsed == -2199023255552L);
9+
assert(parsed != -2199023255552L);
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
THOROUGH
2+
test_parselong.class
3+
--refine-strings
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[.*assertion.1\].* line 7.* SUCCESS$
7+
^\[.*assertion.2\].* line 8.* FAILURE$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
public class test_parselong
2+
{
3+
public static void main(String[] args)
4+
{
5+
String str = new String("7654321076543210");
6+
long parsed = Long.parseLong(str, 8);
7+
assert(parsed == 275730608604808L);
8+
assert(parsed != 275730608604808L);
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
THOROUGH
2+
test_parselong.class
3+
--refine-strings
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^\[.*assertion.1\].* line 8.* SUCCESS$
7+
^\[.*assertion.2\].* line 9.* FAILURE$
8+
--
9+
--
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
public class test_parselong
2+
{
3+
public static void main(String[] args)
4+
{
5+
// -2^35
6+
String str = new String("-100000000000000000000000000000000000");
7+
long parsed = Long.parseLong(str, 2);
8+
assert(parsed == -34359738368L);
9+
assert(parsed != -34359738368L);
10+
}
11+
}

src/java_bytecode/java_string_library_preprocess.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,12 @@ void java_string_library_preprocesst::initialize_conversion_table()
19411941
cprover_equivalent_to_java_function
19421942
["java::java.lang.Integer.parseInt:(Ljava/lang/String;I)I"]=
19431943
ID_cprover_string_parse_int_func;
1944+
cprover_equivalent_to_java_function
1945+
["java::java.lang.Long.parseLong:(Ljava/lang/String;)J"]=
1946+
ID_cprover_string_parse_int_func;
1947+
cprover_equivalent_to_java_function
1948+
["java::java.lang.Long.parseLong:(Ljava/lang/String;I)J"]=
1949+
ID_cprover_string_parse_int_func;
19441950
cprover_equivalent_to_java_string_returning_function
19451951
["java::java.lang.Integer.toHexString:(I)Ljava/lang/String;"]=
19461952
ID_cprover_string_of_int_hex_func;

src/solvers/refinement/string_constraint_generator.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ class string_constraint_generatort
297297

298298
exprt add_axioms_for_parse_int(const function_application_exprt &f);
299299
exprt add_axioms_for_correct_number_format(
300-
const string_exprt &str, const exprt &radix, std::size_t max_size=10);
300+
const string_exprt &str, const exprt &radix, std::size_t max_size);
301301
exprt add_axioms_for_to_char_array(const function_application_exprt &f);
302302
exprt add_axioms_for_compare_to(const function_application_exprt &f);
303303

src/solvers/refinement/string_constraint_generator_valueof.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,9 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
419419
PRECONDITION(f.arguments().size()==1 || f.arguments().size()==2);
420420
string_exprt str=get_string_expr(f.arguments()[0]);
421421
const exprt radix=
422-
f.arguments().size()==1?from_integer(10, f.type()):f.arguments()[1];
422+
f.arguments().size()==1?
423+
static_cast<exprt>(from_integer(10, f.type())):
424+
static_cast<exprt>(typecast_exprt(f.arguments()[1], f.type()));
423425

424426
const typet &type=f.type();
425427
symbol_exprt i=fresh_symbol("parsed_int", type);
@@ -436,21 +438,23 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
436438
not_exprt(or_exprt(starts_with_minus, starts_with_plus));
437439

438440
/// TODO: we should throw an exception when this does not hold:
439-
exprt correct=add_axioms_for_correct_number_format(str, radix);
441+
const std::size_t max_string_length=40;
442+
const exprt &correct=add_axioms_for_correct_number_format(
443+
str, radix, max_string_length);
440444
axioms.push_back(correct);
441445

442446
/// TODO(OJones): size should depend on the radix
443447
/// TODO(OJones): we should deal with overflow properly
444-
for(unsigned size=1; size<=10; size++)
448+
for(std::size_t size=1; size<=max_string_length; size++)
445449
{
446450
exprt sum=from_integer(0, type);
447451
exprt first_value=get_numeric_value_from_character(chr, char_type, type);
448452
equal_exprt premise=str.axiom_for_has_length(size);
449453

450-
for(unsigned j=1; j<size; j++)
454+
for(std::size_t j=1; j<size; j++)
451455
{
452456
mult_exprt radix_sum(sum, radix);
453-
if(j>=9)
457+
if(j>=max_string_length-1)
454458
{
455459
// We have to be careful about overflows
456460
div_exprt div(sum, radix);
@@ -463,7 +467,7 @@ exprt string_constraint_generatort::add_axioms_for_parse_int(
463467
get_numeric_value_from_character(str[j], char_type, type));
464468

465469
mult_exprt first(first_value, radix);
466-
if(j>=9)
470+
if(j>=max_string_length-1)
467471
{
468472
// We have to be careful about overflows
469473
div_exprt div_first(first, radix);

0 commit comments

Comments
 (0)