Skip to content

Commit 4588753

Browse files
Add JDIFF tool
1 parent a20f2c1 commit 4588753

13 files changed

+919
-6
lines changed

CMakeLists.txt

+2-4
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,11 @@ set_target_properties(
6464
goto-instrument-lib
6565
goto-programs
6666
goto-symex
67-
java_bytecode
68-
jbmc
69-
jbmc-lib
7067
jsil
7168
json
7269
langapi
7370
linking
7471
miniBDD
75-
miniz
7672
mmcc
7773
pointer-analysis
7874
solvers
@@ -85,6 +81,8 @@ set_target_properties(
8581
java_bytecode
8682
jbmc
8783
jbmc-lib
84+
jdiff
85+
jdiff-lib
8886
java-testing-utils
8987
java-unit
9088
miniz

jbmc/src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ endmacro(generic_includes)
1616
add_subdirectory(miniz)
1717
add_subdirectory(java_bytecode)
1818
add_subdirectory(jbmc)
19+
add_subdirectory(jdiff)

jbmc/src/Makefile

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
DIRS = jbmc java_bytecode miniz
1+
DIRS = jbmc jdiff java_bytecode miniz
22

33
include config.inc
44

55
.PHONY: all
6-
all: jbmc.dir
6+
all: jbmc.dir jdiff.dir
77

88
# building cbmc proper
99
.PHONY: cprover.dir
@@ -16,6 +16,9 @@ java_bytecode.dir: miniz.dir
1616
.PHONY: jbmc.dir
1717
jbmc.dir: java_bytecode.dir cprover.dir
1818

19+
.PHONY: jdiff.dir
20+
jdiff.dir: java_bytecode.dir cprover.dir
21+
1922
.PHONY: miniz.dir
2023
miniz.dir:
2124

jbmc/src/jdiff/CMakeLists.txt

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Library
2+
file(GLOB_RECURSE sources "*.cpp" "*.h")
3+
list(REMOVE_ITEM sources
4+
${CMAKE_CURRENT_SOURCE_DIR}/jdiff_main.cpp
5+
)
6+
add_library(jdiff-lib ${sources})
7+
8+
generic_includes(jdiff-lib)
9+
10+
target_link_libraries(jdiff-lib
11+
ansi-c
12+
linking
13+
big-int
14+
pointer-analysis
15+
goto-diff-lib
16+
goto-instrument-lib
17+
goto-programs
18+
goto-symex
19+
analyses
20+
java_bytecode
21+
langapi
22+
xml
23+
util
24+
)
25+
26+
# Executable
27+
add_executable(jdiff jdiff_main.cpp)
28+
target_link_libraries(jdiff jdiff-lib)

jbmc/src/jdiff/Makefile

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
SRC = jdiff_languages.cpp \
2+
jdiff_main.cpp \
3+
jdiff_parse_options.cpp \
4+
java_syntactic_diff.cpp \
5+
# Empty last line
6+
7+
OBJ += ../$(CPROVER_DIR)/src/ansi-c/ansi-c$(LIBEXT) \
8+
..//java_bytecode/java_bytecode$(LIBEXT) \
9+
../$(CPROVER_DIR)/src/linking/linking$(LIBEXT) \
10+
../$(CPROVER_DIR)/src/big-int/big-int$(LIBEXT) \
11+
../$(CPROVER_DIR)/src/goto-programs/goto-programs$(LIBEXT) \
12+
../$(CPROVER_DIR)/src/pointer-analysis/pointer-analysis$(LIBEXT) \
13+
../$(CPROVER_DIR)/src/goto-diff/syntactic_diff$(OBJEXT) \
14+
../$(CPROVER_DIR)/src/goto-diff/unified_diff$(OBJEXT) \
15+
../$(CPROVER_DIR)/src/goto-diff/change_impact$(OBJEXT) \
16+
../$(CPROVER_DIR)/src/goto-diff/goto_diff_base$(OBJEXT) \
17+
../$(CPROVER_DIR)/src/goto-instrument/cover$(OBJEXT) \
18+
../$(CPROVER_DIR)/src/goto-instrument/cover_basic_blocks$(OBJEXT) \
19+
../$(CPROVER_DIR)/src/goto-instrument/cover_filter$(OBJEXT) \
20+
../$(CPROVER_DIR)/src/goto-instrument/cover_instrument_branch$(OBJEXT) \
21+
../$(CPROVER_DIR)/src/goto-instrument/cover_instrument_condition$(OBJEXT) \
22+
../$(CPROVER_DIR)/src/goto-instrument/cover_instrument_decision$(OBJEXT) \
23+
../$(CPROVER_DIR)/src/goto-instrument/cover_instrument_location$(OBJEXT) \
24+
../$(CPROVER_DIR)/src/goto-instrument/cover_instrument_mcdc$(OBJEXT) \
25+
../$(CPROVER_DIR)/src/goto-instrument/cover_instrument_other$(OBJEXT) \
26+
../$(CPROVER_DIR)/src/goto-instrument/cover_util$(OBJEXT) \
27+
../$(CPROVER_DIR)/src/goto-symex/rewrite_union$(OBJEXT) \
28+
../$(CPROVER_DIR)/src/analyses/analyses$(LIBEXT) \
29+
../$(CPROVER_DIR)/src/langapi/langapi$(LIBEXT) \
30+
../$(CPROVER_DIR)/src/xmllang/xmllang$(LIBEXT) \
31+
../$(CPROVER_DIR)/src/util/util$(LIBEXT) \
32+
../miniz/miniz$(OBJEXT) \
33+
../$(CPROVER_DIR)/src/json/json$(LIBEXT) \
34+
# Empty last line
35+
36+
INCLUDES= -I .. -I ../$(CPROVER_DIR)/src
37+
38+
LIBS =
39+
40+
include ../config.inc
41+
include ../$(CPROVER_DIR)/src/config.inc
42+
include ../$(CPROVER_DIR)/src/common
43+
44+
CLEANFILES = jdiff$(EXEEXT)
45+
46+
all: jdiff$(EXEEXT)
47+
48+
###############################################################################
49+
50+
jdiff$(EXEEXT): $(OBJ)
51+
$(LINKBIN)
52+
53+
.PHONY: jdiff-mac-signed
54+
55+
jdiff-mac-signed: jdiff$(EXEEXT)
56+
strip jdiff$(EXEEXT) ; codesign -v -s $(OSX_IDENTITY) jdiff$(EXEEXT)

jbmc/src/jdiff/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
\ingroup module_hidden
2+
\defgroup jdiff jdiff
3+
4+
# Folder jdiff
5+
6+
`jdiff/` is a tool that offers functionality similar to the `diff`
7+
tool, but for Java programs.
+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*******************************************************************\
2+
3+
Module: Syntactic GOTO-DIFF for Java
4+
5+
Author: Peter Schrammel
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Syntactic GOTO-DIFF for Java
11+
12+
#include "java_syntactic_diff.h"
13+
14+
#include <goto-programs/goto_model.h>
15+
16+
bool java_syntactic_difft::operator()()
17+
{
18+
forall_goto_functions(it, goto_model1.goto_functions)
19+
{
20+
if(!it->second.body_available())
21+
continue;
22+
23+
goto_functionst::function_mapt::const_iterator f_it =
24+
goto_model2.goto_functions.function_map.find(it->first);
25+
if(
26+
f_it == goto_model2.goto_functions.function_map.end() ||
27+
!f_it->second.body_available())
28+
{
29+
deleted_functions.insert(it->first);
30+
continue;
31+
}
32+
33+
// check access qualifiers
34+
const symbolt *fun1 = goto_model1.symbol_table.lookup(it->first);
35+
CHECK_RETURN(fun1 != nullptr);
36+
const symbolt *fun2 = goto_model2.symbol_table.lookup(it->first);
37+
CHECK_RETURN(fun2 != nullptr);
38+
const irep_idt &class_name = fun1->type.get(ID_C_class);
39+
bool function_access_changed =
40+
fun1->type.get(ID_access) != fun2->type.get(ID_access);
41+
bool class_access_changed = false;
42+
bool field_access_changed = false;
43+
if(!class_name.empty())
44+
{
45+
const symbolt *class1 = goto_model1.symbol_table.lookup(class_name);
46+
CHECK_RETURN(class1 != nullptr);
47+
const symbolt *class2 = goto_model2.symbol_table.lookup(class_name);
48+
CHECK_RETURN(class2 != nullptr);
49+
class_access_changed =
50+
class1->type.get(ID_access) != class2->type.get(ID_access);
51+
const class_typet &class_type1 = to_class_type(class1->type);
52+
const class_typet &class_type2 = to_class_type(class2->type);
53+
for(const auto &field1 : class_type1.components())
54+
{
55+
for(const auto &field2 : class_type2.components())
56+
{
57+
if(field1.get_name() == field2.get_name())
58+
{
59+
field_access_changed = field1.get_access() != field2.get_access();
60+
break;
61+
}
62+
}
63+
if(field_access_changed)
64+
break;
65+
}
66+
}
67+
if(function_access_changed || class_access_changed || field_access_changed)
68+
{
69+
modified_functions.insert(it->first);
70+
continue;
71+
}
72+
73+
if(
74+
it->second.body.instructions.size() !=
75+
f_it->second.body.instructions.size())
76+
{
77+
modified_functions.insert(it->first);
78+
continue;
79+
}
80+
81+
goto_programt::instructionst::const_iterator i_it1 =
82+
it->second.body.instructions.begin();
83+
for(goto_programt::instructionst::const_iterator
84+
i_it2 = f_it->second.body.instructions.begin();
85+
i_it1 != it->second.body.instructions.end() &&
86+
i_it2 != f_it->second.body.instructions.end();
87+
++i_it1, ++i_it2)
88+
{
89+
long jump_difference1 = 0;
90+
if(!i_it1->targets.empty())
91+
{
92+
jump_difference1 =
93+
i_it1->get_target()->location_number - i_it1->location_number;
94+
}
95+
long jump_difference2 = 0;
96+
if(!i_it2->targets.empty())
97+
{
98+
jump_difference2 =
99+
i_it2->get_target()->location_number - i_it2->location_number;
100+
}
101+
if(
102+
i_it1->code != i_it2->code || i_it1->function != i_it2->function ||
103+
i_it1->type != i_it2->type || i_it1->guard != i_it2->guard ||
104+
jump_difference1 != jump_difference2)
105+
{
106+
modified_functions.insert(it->first);
107+
break;
108+
}
109+
}
110+
}
111+
forall_goto_functions(it, goto_model2.goto_functions)
112+
{
113+
if(!it->second.body_available())
114+
continue;
115+
116+
total_functions_count++;
117+
118+
goto_functionst::function_mapt::const_iterator f_it =
119+
goto_model1.goto_functions.function_map.find(it->first);
120+
if(
121+
f_it == goto_model1.goto_functions.function_map.end() ||
122+
!f_it->second.body_available())
123+
new_functions.insert(it->first);
124+
}
125+
126+
return !(
127+
new_functions.empty() && modified_functions.empty() &&
128+
deleted_functions.empty());
129+
}

jbmc/src/jdiff/java_syntactic_diff.h

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*******************************************************************\
2+
3+
Module: Syntactic GOTO-DIFF for Java
4+
5+
Author: Peter Schrammel
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Syntactic GOTO-DIFF for Java
11+
12+
#ifndef CPROVER_JDIFF_JAVA_SYNTACTIC_DIFF_H
13+
#define CPROVER_JDIFF_JAVA_SYNTACTIC_DIFF_H
14+
15+
#include <goto-diff/goto_diff.h>
16+
17+
class java_syntactic_difft : public goto_difft
18+
{
19+
public:
20+
java_syntactic_difft(
21+
const goto_modelt &_goto_model1,
22+
const goto_modelt &_goto_model2,
23+
const optionst &_options,
24+
message_handlert &_message_handler)
25+
: goto_difft(_goto_model1, _goto_model2, _options, _message_handler)
26+
{
27+
}
28+
29+
virtual bool operator()();
30+
};
31+
32+
#endif // CPROVER_JDIFF_JAVA_SYNTACTIC_DIFF_H

jbmc/src/jdiff/jdiff_languages.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*******************************************************************\
2+
3+
Module: Language Registration
4+
5+
Author: Peter Schrammel
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Language Registration
11+
12+
#include "jdiff_languages.h"
13+
14+
#include <langapi/mode.h>
15+
16+
#include <java_bytecode/java_bytecode_language.h>
17+
18+
void jdiff_languagest::register_languages()
19+
{
20+
register_language(new_java_bytecode_language);
21+
}

jbmc/src/jdiff/jdiff_languages.h

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*******************************************************************\
2+
3+
Module: JDIFF Languages
4+
5+
Author: Peter Schrammel
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// JDIFF Languages
11+
12+
#ifndef CPROVER_JDIFF_JDIFF_LANGUAGES_H
13+
#define CPROVER_JDIFF_JDIFF_LANGUAGES_H
14+
15+
#include <goto-programs/goto_model.h>
16+
#include <langapi/language_ui.h>
17+
18+
class jdiff_languagest : public language_uit
19+
{
20+
public:
21+
explicit jdiff_languagest(
22+
const cmdlinet &cmdline,
23+
ui_message_handlert &ui_message_handler)
24+
: language_uit(cmdline, ui_message_handler)
25+
{
26+
register_languages();
27+
}
28+
29+
protected:
30+
virtual void register_languages();
31+
};
32+
33+
#endif // CPROVER_JDIFF_JDIFF_LANGUAGES_H

0 commit comments

Comments
 (0)