Skip to content

Commit 26f0976

Browse files
author
Matthias Güdemann
committed
ignore non-Java files in enum static init unwind
To correctly unwind static inits of Java enums, one first has to check whether the function is actually a Java function. This patch also adds a first regression test for static loop unwinding. Fixes: b49a7fc
1 parent ea3a21f commit 26f0976

File tree

5 files changed

+40
-16
lines changed

5 files changed

+40
-16
lines changed
1.37 KB
Binary file not shown.

regression/cbmc-java/enum1/enum1.java

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
public enum enum1
2+
{
3+
VAL1, VAL2, VAL3, VAL4, VAL5;
4+
static
5+
{
6+
for(enum1 e : enum1.values())
7+
{
8+
System.out.println(e);
9+
}
10+
}
11+
public static void main(String[] args)
12+
{
13+
enum1 e=VAL5;
14+
assert(e==VAL5);
15+
}
16+
}

regression/cbmc-java/enum1/test.desc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
enum1.class
3+
--java-unwind-enum-static --unwind 3
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^Unwinding loop java::enum1.<clinit>:()V.0 iteration 5 (6 max) file enum1.java line 6 function java::enum1.<clinit>:()V bytecode_index 78 thread 0$
7+
--
8+
^warning: ignoring

src/cbmc/cbmc_parse_options.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,8 @@ int cbmc_parse_optionst::doit()
550550
if(set_properties(goto_functions))
551551
return 7; // should contemplate EX_USAGE from sysexits.h
552552

553+
// unwinds <clinit> loops to number of enum elements
554+
// side effect: add this as explicit unwind to unwind set
553555
if(options.get_bool_option("java-unwind-enum-static"))
554556
remove_static_init_loops(symbol_table, goto_functions, options);
555557

src/goto-programs/remove_static_init_loops.cpp

+14-16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Author: Daniel Kroening, [email protected]
77
\*******************************************************************/
88

99
#include <util/message.h>
10+
#include <util/suffix.h>
1011
#include <util/string2int.h>
1112

1213
#include "remove_static_init_loops.h"
@@ -56,6 +57,10 @@ void remove_static_init_loopst::unwind_enum_static(
5657
const std::string java_clinit="<clinit>:()V";
5758
const std::string &fname=id2string(ins.function);
5859
size_t class_prefix_length=fname.find_last_of('.');
60+
// is Java function and static init?
61+
const symbolt &function_name=symbol_table.lookup(ins.function);
62+
if(!(function_name.mode==ID_java && has_suffix(fname, java_clinit)))
63+
continue;
5964
assert(
6065
class_prefix_length!=std::string::npos &&
6166
"could not identify class name");
@@ -65,23 +70,16 @@ void remove_static_init_loopst::unwind_enum_static(
6570
size_t unwinds=class_type.get_size_t(ID_java_enum_static_unwind);
6671

6772
unwind_max=std::max(unwind_max, unwinds);
68-
if(fname.length()>java_clinit.length())
73+
if(unwinds>0)
6974
{
70-
// extend unwindset with unwinds for <clinit> of enum
71-
if(fname.compare(
72-
fname.length()-java_clinit.length(),
73-
java_clinit.length(),
74-
java_clinit)==0 && unwinds>0)
75-
{
76-
const std::string &set=options.get_option("unwindset");
77-
std::string newset;
78-
if(set!="")
79-
newset=",";
80-
newset+=
81-
id2string(ins.function)+"."+std::to_string(loop_id)+":"+
82-
std::to_string(unwinds);
83-
options.set_option("unwindset", set+newset);
84-
}
75+
const std::string &set=options.get_option("unwindset");
76+
std::string newset;
77+
if(set!="")
78+
newset=",";
79+
newset+=
80+
id2string(ins.function)+"."+std::to_string(loop_id)+":"+
81+
std::to_string(unwinds);
82+
options.set_option("unwindset", set+newset);
8583
}
8684
}
8785
}

0 commit comments

Comments
 (0)