From c0fda236c96a8d3f00ed5e51f552ba6b85da3896 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Sun, 22 Jan 2017 16:22:27 +0000 Subject: [PATCH 001/166] gcc style error messages for goto-cc --- src/goto-cc/armcc_mode.cpp | 4 +-- src/goto-cc/armcc_mode.h | 9 +++-- src/goto-cc/cw_mode.cpp | 4 +-- src/goto-cc/cw_mode.h | 5 ++- src/goto-cc/gcc_mode.cpp | 4 +-- src/goto-cc/gcc_mode.h | 9 +++-- src/goto-cc/goto_cc_mode.cpp | 7 ++-- src/goto-cc/goto_cc_mode.h | 5 ++- src/goto-cc/ld_mode.cpp | 4 +-- src/goto-cc/ld_mode.h | 9 +++-- src/goto-cc/ms_cl_mode.cpp | 4 +-- src/goto-cc/ms_cl_mode.h | 5 ++- src/util/cout_message.cpp | 65 ++++++++++++++++++++++++++++++++++++ src/util/cout_message.h | 27 +++++++++++++-- 14 files changed, 131 insertions(+), 30 deletions(-) diff --git a/src/goto-cc/armcc_mode.cpp b/src/goto-cc/armcc_mode.cpp index fbe8db16d94..f4a57655582 100644 --- a/src/goto-cc/armcc_mode.cpp +++ b/src/goto-cc/armcc_mode.cpp @@ -59,8 +59,8 @@ int armcc_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2int(cmdline.get_value("verbosity")); - compiler.ui_message_handler.set_verbosity(verbosity); - ui_message_handler.set_verbosity(verbosity); + compiler.set_message_handler(get_message_handler()); + message_handler.set_verbosity(verbosity); debug() << "ARM mode" << eom; diff --git a/src/goto-cc/armcc_mode.h b/src/goto-cc/armcc_mode.h index 11cc4be2ad2..efbc1acfc9c 100644 --- a/src/goto-cc/armcc_mode.h +++ b/src/goto-cc/armcc_mode.h @@ -11,23 +11,26 @@ Date: June 2006 #ifndef CPROVER_GOTO_CC_ARMCC_MODE_H #define CPROVER_GOTO_CC_ARMCC_MODE_H +#include + #include "goto_cc_mode.h" #include "armcc_cmdline.h" class armcc_modet:public goto_cc_modet { public: - virtual int doit(); - virtual void help_mode(); + int doit() final; + void help_mode() final; explicit armcc_modet(armcc_cmdlinet &_armcc_cmdline): - goto_cc_modet(_armcc_cmdline), + goto_cc_modet(_armcc_cmdline, message_handler), cmdline(_armcc_cmdline) { } protected: armcc_cmdlinet &cmdline; + gcc_message_handlert message_handler; }; #endif // CPROVER_GOTO_CC_ARMCC_MODE_H diff --git a/src/goto-cc/cw_mode.cpp b/src/goto-cc/cw_mode.cpp index a3a085d843c..510f7c9c0aa 100644 --- a/src/goto-cc/cw_mode.cpp +++ b/src/goto-cc/cw_mode.cpp @@ -59,8 +59,8 @@ int cw_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2unsigned(cmdline.get_value("verbosity")); - compiler.ui_message_handler.set_verbosity(verbosity); - ui_message_handler.set_verbosity(verbosity); + compiler.set_message_handler(get_message_handler()); + message_handler.set_verbosity(verbosity); debug() << "CodeWarrior mode" << eom; diff --git a/src/goto-cc/cw_mode.h b/src/goto-cc/cw_mode.h index e82615dc828..d69ff940e98 100644 --- a/src/goto-cc/cw_mode.h +++ b/src/goto-cc/cw_mode.h @@ -11,6 +11,8 @@ Date: June 2006 #ifndef CPROVER_GOTO_CC_CW_MODE_H #define CPROVER_GOTO_CC_CW_MODE_H +#include + #include "goto_cc_mode.h" #include "gcc_cmdline.h" @@ -21,13 +23,14 @@ class cw_modet:public goto_cc_modet virtual void help_mode(); explicit cw_modet(gcc_cmdlinet &_gcc_cmdline): - goto_cc_modet(_gcc_cmdline), + goto_cc_modet(_gcc_cmdline, message_handler), cmdline(_gcc_cmdline) { } protected: gcc_cmdlinet &cmdline; + console_message_handlert message_handler; }; #endif // CPROVER_GOTO_CC_CW_MODE_H diff --git a/src/goto-cc/gcc_mode.cpp b/src/goto-cc/gcc_mode.cpp index 6038bddb93f..66417e12180 100644 --- a/src/goto-cc/gcc_mode.cpp +++ b/src/goto-cc/gcc_mode.cpp @@ -122,7 +122,7 @@ int gcc_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2unsigned(cmdline.get_value("verbosity")); - ui_message_handler.set_verbosity(verbosity); + gcc_message_handler.set_verbosity(verbosity); if(act_as_ld) { @@ -197,7 +197,7 @@ int gcc_modet::doit() // determine actions to be undertaken compilet compiler(cmdline); - compiler.ui_message_handler.set_verbosity(verbosity); + compiler.set_message_handler(get_message_handler()); if(act_as_ld) compiler.mode=compilet::LINK_LIBRARY; diff --git a/src/goto-cc/gcc_mode.h b/src/goto-cc/gcc_mode.h index a0a41be9ed8..b7ec7e21d6b 100644 --- a/src/goto-cc/gcc_mode.h +++ b/src/goto-cc/gcc_mode.h @@ -11,17 +11,19 @@ Date: June 2006 #ifndef CPROVER_GOTO_CC_GCC_MODE_H #define CPROVER_GOTO_CC_GCC_MODE_H +#include + #include "goto_cc_mode.h" #include "gcc_cmdline.h" class gcc_modet:public goto_cc_modet { public: - virtual int doit(); - virtual void help_mode(); + int doit() final; + void help_mode() final; explicit gcc_modet(goto_cc_cmdlinet &_cmdline): - goto_cc_modet(_cmdline), + goto_cc_modet(_cmdline, gcc_message_handler), produce_hybrid_binary(false), act_as_ld(false) { @@ -30,6 +32,7 @@ class gcc_modet:public goto_cc_modet bool produce_hybrid_binary; protected: + gcc_message_handlert gcc_message_handler; bool act_as_ld; std::string native_compiler_name; diff --git a/src/goto-cc/goto_cc_mode.cpp b/src/goto-cc/goto_cc_mode.cpp index 3d02f19111f..fc2d40325a4 100644 --- a/src/goto-cc/goto_cc_mode.cpp +++ b/src/goto-cc/goto_cc_mode.cpp @@ -33,9 +33,10 @@ Function: goto_cc_modet::goto_cc_modet \*******************************************************************/ -goto_cc_modet::goto_cc_modet(goto_cc_cmdlinet &_cmdline): - language_uit(_cmdline, ui_message_handler), - ui_message_handler(_cmdline, "goto-cc " CBMC_VERSION), +goto_cc_modet::goto_cc_modet( + goto_cc_cmdlinet &_cmdline, + message_handlert &_message_handler): + messaget(_message_handler), cmdline(_cmdline) { register_languages(); diff --git a/src/goto-cc/goto_cc_mode.h b/src/goto-cc/goto_cc_mode.h index 28459da42de..2e1a78a67c7 100644 --- a/src/goto-cc/goto_cc_mode.h +++ b/src/goto-cc/goto_cc_mode.h @@ -15,7 +15,7 @@ Date: June 2006 #include "goto_cc_cmdline.h" -class goto_cc_modet:public language_uit +class goto_cc_modet:public messaget { public: std::string base_name; @@ -26,11 +26,10 @@ class goto_cc_modet:public language_uit virtual void help(); virtual void usage_error(); - explicit goto_cc_modet(goto_cc_cmdlinet &_cmdline); + goto_cc_modet(goto_cc_cmdlinet &, message_handlert &); ~goto_cc_modet(); protected: - ui_message_handlert ui_message_handler; void register_languages(); goto_cc_cmdlinet &cmdline; }; diff --git a/src/goto-cc/ld_mode.cpp b/src/goto-cc/ld_mode.cpp index f7e6ee09c57..134c7aa4f26 100644 --- a/src/goto-cc/ld_mode.cpp +++ b/src/goto-cc/ld_mode.cpp @@ -68,8 +68,8 @@ int ld_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2int(cmdline.get_value("verbosity")); - compiler.ui_message_handler.set_verbosity(verbosity); - ui_message_handler.set_verbosity(verbosity); + compiler.set_message_handler(get_message_handler()); + message_handler.set_verbosity(verbosity); if(produce_hybrid_binary) debug() << "LD mode (hybrid)" << eom; diff --git a/src/goto-cc/ld_mode.h b/src/goto-cc/ld_mode.h index 7ef8ee3d683..1fb112432aa 100644 --- a/src/goto-cc/ld_mode.h +++ b/src/goto-cc/ld_mode.h @@ -11,17 +11,19 @@ Date: June 2006 #ifndef CPROVER_GOTO_CC_LD_MODE_H #define CPROVER_GOTO_CC_LD_MODE_H +#include + #include "goto_cc_mode.h" #include "ld_cmdline.h" class ld_modet:public goto_cc_modet { public: - virtual int doit(); - virtual void help_mode(); + int doit() final; + void help_mode() final; explicit ld_modet(ld_cmdlinet &_ld_cmdline): - goto_cc_modet(_ld_cmdline), + goto_cc_modet(_ld_cmdline, message_handler), produce_hybrid_binary(false), cmdline(_ld_cmdline) { @@ -31,6 +33,7 @@ class ld_modet:public goto_cc_modet protected: ld_cmdlinet &cmdline; + gcc_message_handlert message_handler; //int gcc_hybrid_binary(const cmdlinet::argst &input_files); //static bool is_supported_source_file(const std::string &); diff --git a/src/goto-cc/ms_cl_mode.cpp b/src/goto-cc/ms_cl_mode.cpp index 73a06455467..86aaf3f0a3d 100644 --- a/src/goto-cc/ms_cl_mode.cpp +++ b/src/goto-cc/ms_cl_mode.cpp @@ -69,8 +69,8 @@ int ms_cl_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2unsigned(cmdline.get_value("verbosity")); - compiler.ui_message_handler.set_verbosity(verbosity); - ui_message_handler.set_verbosity(verbosity); + compiler.set_message_handler(get_message_handler()); + message_handler.set_verbosity(verbosity); debug() << "Visual Studio mode" << eom; diff --git a/src/goto-cc/ms_cl_mode.h b/src/goto-cc/ms_cl_mode.h index 8a446c332c1..1b6abf31e2d 100644 --- a/src/goto-cc/ms_cl_mode.h +++ b/src/goto-cc/ms_cl_mode.h @@ -11,6 +11,8 @@ Date: June 2006 #ifndef CPROVER_GOTO_CC_MS_CL_MODE_H #define CPROVER_GOTO_CC_MS_CL_MODE_H +#include + #include "goto_cc_mode.h" #include "ms_cl_cmdline.h" @@ -21,13 +23,14 @@ class ms_cl_modet:public goto_cc_modet virtual void help_mode(); explicit ms_cl_modet(ms_cl_cmdlinet &_ms_cl_cmdline): - goto_cc_modet(_ms_cl_cmdline), + goto_cc_modet(_ms_cl_cmdline, message_handler), cmdline(_ms_cl_cmdline) { } protected: ms_cl_cmdlinet &cmdline; + console_message_handlert message_handler; }; #endif // CPROVER_GOTO_CC_MS_CL_MODE_H diff --git a/src/util/cout_message.cpp b/src/util/cout_message.cpp index 6b63f8625ad..d4936d5ad53 100644 --- a/src/util/cout_message.cpp +++ b/src/util/cout_message.cpp @@ -135,3 +135,68 @@ void console_message_handlert::print( std::cerr << message << '\n' << std::flush; #endif } + +/*******************************************************************\ + +Function: gcc_message_handlert::print + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void gcc_message_handlert::print( + unsigned level, + const std::string &message, + int sequence_number, + const source_locationt &location) +{ + std::string dest; + + const irep_idt &file=location.get_file(); + const irep_idt &line=location.get_line(); + const irep_idt &function=location.get_function(); + + if(!function.empty()) + { + if(!file.empty()) + dest+=id2string(file)+":"; + if(dest!="") dest+=' '; + dest+="In function '"+id2string(function)+"':\n"; + } + + if(!line.empty()) + { + if(!file.empty()) + dest+=id2string(file)+":"; + + dest+=id2string(line)+":"+id2string(line)+":"; + } + + dest+=message; + + print(level, dest); +} + +/*******************************************************************\ + +Function: gcc_message_handlert::print + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void gcc_message_handlert::print( + unsigned level, + const std::string &message) +{ + // gcc appears to send everything to cerr + std::cerr << message << '\n' << std::flush; +} diff --git a/src/util/cout_message.h b/src/util/cout_message.h index 0cedb2b790c..ab78148c6d6 100644 --- a/src/util/cout_message.h +++ b/src/util/cout_message.h @@ -15,21 +15,42 @@ class cout_message_handlert:public message_handlert { public: // all messages go to cout - virtual void print(unsigned level, const std::string &message); + virtual void print( + unsigned level, + const std::string &message) override; }; class cerr_message_handlert:public message_handlert { public: // all messages go to cerr - virtual void print(unsigned level, const std::string &message); + virtual void print( + unsigned level, + const std::string &message) override; }; class console_message_handlert:public message_handlert { public: // level 4 and upwards go to cout, level 1-3 to cerr - virtual void print(unsigned level, const std::string &message); + virtual void print( + unsigned level, + const std::string &message) override; +}; + +class gcc_message_handlert:public message_handlert +{ +public: + // aims to imitate the messages gcc prints + virtual void print( + unsigned level, + const std::string &message) override; + + virtual void print( + unsigned level, + const std::string &message, + int sequence_number, + const source_locationt &location) override; }; #endif // CPROVER_UTIL_COUT_MESSAGE_H From 9a61c2c0ab570ffbfc388a5ff3fdd259e8cfb26c Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Sun, 22 Jan 2017 18:41:05 +0000 Subject: [PATCH 002/166] fix for multi-ary fixed-bv multiplication --- regression/cbmc/Fixedbv8/main.c | 13 +++++++++++++ regression/cbmc/Fixedbv8/test.desc | 8 ++++++++ src/solvers/flattening/boolbv_mult.cpp | 12 ++++++------ 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 regression/cbmc/Fixedbv8/main.c create mode 100644 regression/cbmc/Fixedbv8/test.desc diff --git a/regression/cbmc/Fixedbv8/main.c b/regression/cbmc/Fixedbv8/main.c new file mode 100644 index 00000000000..f0736e7ea70 --- /dev/null +++ b/regression/cbmc/Fixedbv8/main.c @@ -0,0 +1,13 @@ +typedef __CPROVER_fixedbv[64][32] __plant_typet; +extern __plant_typet A0, A1; + +int main(void) { + __CPROVER_assume(A0 == (__plant_typet)0.125); + __CPROVER_assume(A1 == (__plant_typet)0.015625); + + const __plant_typet XXX1a=A0 * A1; + const __plant_typet XXX2a=(__plant_typet)-1 * XXX1a; + const __plant_typet XXX2b=-0.001953125; + __CPROVER_assert(XXX2a==XXX2b, ""); + return 0; +} diff --git a/regression/cbmc/Fixedbv8/test.desc b/regression/cbmc/Fixedbv8/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/Fixedbv8/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/src/solvers/flattening/boolbv_mult.cpp b/src/solvers/flattening/boolbv_mult.cpp index 37d910b71cf..52ead55629d 100644 --- a/src/solvers/flattening/boolbv_mult.cpp +++ b/src/solvers/flattening/boolbv_mult.cpp @@ -53,15 +53,15 @@ bvt boolbvt::convert_mult(const exprt &expr) std::size_t fraction_bits= to_fixedbv_type(expr.type()).get_fraction_bits(); - // do a sign extension by fraction_bits bits - bv=bv_utils.sign_extension(bv, bv.size()+fraction_bits); - for(exprt::operandst::const_iterator it=operands.begin()+1; it!=operands.end(); it++) { if(it->type()!=expr.type()) throw "multiplication with mixed types"; + // do a sign extension by fraction_bits bits + bv=bv_utils.sign_extension(bv, bv.size()+fraction_bits); + bvt op=convert_bv(*it); if(op.size()!=width) @@ -70,10 +70,10 @@ bvt boolbvt::convert_mult(const exprt &expr) op=bv_utils.sign_extension(op, bv.size()); bv=bv_utils.signed_multiplier(bv, op); - } - // cut it down again - bv.erase(bv.begin(), bv.begin()+fraction_bits); + // cut it down again + bv.erase(bv.begin(), bv.begin()+fraction_bits); + } return bv; } From f1df0bec45a7b5d72d4122b27ba77a6ad02464c2 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Sun, 22 Jan 2017 18:41:05 +0000 Subject: [PATCH 003/166] fix for multi-ary fixed-bv multiplication --- regression/cbmc/Fixedbv8/main.c | 13 +++++++++++++ regression/cbmc/Fixedbv8/test.desc | 8 ++++++++ src/solvers/flattening/boolbv_mult.cpp | 12 ++++++------ 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 regression/cbmc/Fixedbv8/main.c create mode 100644 regression/cbmc/Fixedbv8/test.desc diff --git a/regression/cbmc/Fixedbv8/main.c b/regression/cbmc/Fixedbv8/main.c new file mode 100644 index 00000000000..f0736e7ea70 --- /dev/null +++ b/regression/cbmc/Fixedbv8/main.c @@ -0,0 +1,13 @@ +typedef __CPROVER_fixedbv[64][32] __plant_typet; +extern __plant_typet A0, A1; + +int main(void) { + __CPROVER_assume(A0 == (__plant_typet)0.125); + __CPROVER_assume(A1 == (__plant_typet)0.015625); + + const __plant_typet XXX1a=A0 * A1; + const __plant_typet XXX2a=(__plant_typet)-1 * XXX1a; + const __plant_typet XXX2b=-0.001953125; + __CPROVER_assert(XXX2a==XXX2b, ""); + return 0; +} diff --git a/regression/cbmc/Fixedbv8/test.desc b/regression/cbmc/Fixedbv8/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/Fixedbv8/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/src/solvers/flattening/boolbv_mult.cpp b/src/solvers/flattening/boolbv_mult.cpp index 37d910b71cf..52ead55629d 100644 --- a/src/solvers/flattening/boolbv_mult.cpp +++ b/src/solvers/flattening/boolbv_mult.cpp @@ -53,15 +53,15 @@ bvt boolbvt::convert_mult(const exprt &expr) std::size_t fraction_bits= to_fixedbv_type(expr.type()).get_fraction_bits(); - // do a sign extension by fraction_bits bits - bv=bv_utils.sign_extension(bv, bv.size()+fraction_bits); - for(exprt::operandst::const_iterator it=operands.begin()+1; it!=operands.end(); it++) { if(it->type()!=expr.type()) throw "multiplication with mixed types"; + // do a sign extension by fraction_bits bits + bv=bv_utils.sign_extension(bv, bv.size()+fraction_bits); + bvt op=convert_bv(*it); if(op.size()!=width) @@ -70,10 +70,10 @@ bvt boolbvt::convert_mult(const exprt &expr) op=bv_utils.sign_extension(op, bv.size()); bv=bv_utils.signed_multiplier(bv, op); - } - // cut it down again - bv.erase(bv.begin(), bv.begin()+fraction_bits); + // cut it down again + bv.erase(bv.begin(), bv.begin()+fraction_bits); + } return bv; } From 7f33f0463552242d8273cccc1e51e117a62edb24 Mon Sep 17 00:00:00 2001 From: Pascal Kesseli Date: Sun, 22 Jan 2017 19:06:58 +0000 Subject: [PATCH 004/166] Added CEGIS control benchmark 4 CEGIS control benchmark 4 tests the __CPROVER_fixedbv semantics fixed in 1f1a11e. --- .../cegis_control_benchmark_04/benchmark.h | 11 + .../control_types.h | 48 ++ .../cegis_control_benchmark_04/operators.h | 57 ++ .../safety_stability.c | 505 ++++++++++++++++++ .../cegis_control_benchmark_04/test.desc | 7 + 5 files changed, 628 insertions(+) create mode 100644 regression/cegis/cegis_control_benchmark_04/benchmark.h create mode 100644 regression/cegis/cegis_control_benchmark_04/control_types.h create mode 100644 regression/cegis/cegis_control_benchmark_04/operators.h create mode 100644 regression/cegis/cegis_control_benchmark_04/safety_stability.c create mode 100644 regression/cegis/cegis_control_benchmark_04/test.desc diff --git a/regression/cegis/cegis_control_benchmark_04/benchmark.h b/regression/cegis/cegis_control_benchmark_04/benchmark.h new file mode 100644 index 00000000000..c5b3724cbb9 --- /dev/null +++ b/regression/cegis/cegis_control_benchmark_04/benchmark.h @@ -0,0 +1,11 @@ +#define INT_BITS 12 +#define FRAC_BITS 12 +#include "control_types.h" + +#define NSTATES 3 +#define NINPUTS 1 +#define NOUTPUTS 1 +#define INPUT_LOWERBOUND (__plant_typet)-1 +#define INPUT_UPPERBOUND (__plant_typet)1 +const __plant_typet _controller_A[NSTATES][NSTATES] = { { interval(0.9905),interval(0.075687),interval(0.021033) }, { interval(0.125),interval(0),interval(0) }, { interval(0),interval(0.015625),interval(0) } }; +const __plant_typet _controller_B[NSTATES] = { interval(16), interval(0), interval(0) }; diff --git a/regression/cegis/cegis_control_benchmark_04/control_types.h b/regression/cegis/cegis_control_benchmark_04/control_types.h new file mode 100644 index 00000000000..62bbffafb8a --- /dev/null +++ b/regression/cegis/cegis_control_benchmark_04/control_types.h @@ -0,0 +1,48 @@ +/* + * control_types.h + * + * Created on: 18 Jan 2017 + * Author: elipol + */ + +#ifndef CONTROL_TYPES_H_ +#define CONTROL_TYPES_H_ + +#ifdef CPROVER + #ifdef INTERVAL + typedef __CPROVER_fixedbv[_CONTROL_FLOAT_WIDTH][_CONTORL_RADIX_WIDTH] __plant_precisiont; + #include "intervals.h" + typedef struct intervalt __plant_typet; + typedef __CPROVER_fixedbv[_CONTROL_FLOAT_WIDTH][_CONTORL_RADIX_WIDTH] __controller_precisiont; + typedef struct intervalt __controller_typet; + #define interval(x) interval_cast(x); + #else + typedef __CPROVER_fixedbv[_CONTROL_FLOAT_WIDTH][_CONTORL_RADIX_WIDTH] __plant_precisiont; + typedef __plant_precisiont __plant_typet; + typedef __CPROVER_fixedbv[INT_BITS+FRAC_BITS][FRAC_BITS] __controller_precisiont; + typedef __controller_precisiont __controller_typet; + #define plant_cast(x) ((__plant_typet)x) + #define controller_cast(x) ((__controller_typet)x) + #define interval(x) x + #endif +#else + #ifdef INTERVAL + typedef double __plant_precisiont; + #include "intervals.h" + typedef struct intervalt __plant_typet; + typedef double __controller_precisiont; //fixed point arithmetic is implemented using doubles + typedef struct intervalt __controller_typet; + #define interval(x) interval_cast(x) + #endif + #ifndef INTERVAL + typedef double __plant_precisiont; + typedef __plant_precisiont __plant_typet; + typedef double __controller_precisiont; //fixed point arithmetic is implemented using doubles + typedef __controller_precisiont __controller_typet; + #define interval(x) (x) + #define plant_cast(x) x + #define controller_cast(x) x + #endif +#endif + +#endif /* CONTROL_TYPES_H_ */ diff --git a/regression/cegis/cegis_control_benchmark_04/operators.h b/regression/cegis/cegis_control_benchmark_04/operators.h new file mode 100644 index 00000000000..29b0e021af5 --- /dev/null +++ b/regression/cegis/cegis_control_benchmark_04/operators.h @@ -0,0 +1,57 @@ +/* + * operators.h + * + * Created on: 18 Jan 2017 + * Author: elipol + */ + +#ifndef OPERATORS_H_ +#define OPERATORS_H_ + +#ifndef INTERVAL + #define controller_mult(x,y) ((x) *(y)) + #define mult(x,y) ( (x) * (y)) + + #define _abs(a) ( (a) < 0 ? -(a) : (a)) + #define add(x,y) ( (x) + (y)) + + #define lessthan(x,y) ((x)<(y)) + #define greaterthan(x,y) ((x)>(y)) + #define lessthanzero(x) ((x) < 0) + #define lessthan_equaltozero(x) ((x) <= 0) + #define zero_type 0 + #define one_type (__plant_precisiont)1.0 + #define minusone (__plant_precisiont)-1 + #define div(x,y) ( (x) / (y)) + #define sub(x,y) ( (x) - (y)) + #define set(x,y) (x)=(y) + + +#endif +#ifdef INTERVAL + + #define controller_mult(x,y) (interval_fxp_mult((x),(y))) + #define mult(x,y) ( interval_mult((x),(y))) + + #define _abs(a) ( abs_interval(a)) + + #define lessthan(x,y) (interval_lessthan(x,y)) + #define greaterthan(x,y) (interval_greaterthan((x),(y))) + #define add(x,y) (interval_add((x),(y))) + #define lessthanzero(x) (interval_lessthanzero(x)) + #define lessthan_equaltozero(x) (interval_lessthan_equal_to_zero(x)) + + #define zero_type (zero_interval) + #define minusone (minusone_interval) + #define one_type one_interval + #define div(x,y) (interval_posDiv((x),(y))) + #define sub(x,y) (interval_sub((x),(y))) + + #define controller_cast(x) (fxp_interval_check(x)) + #define plant_cast(x) x + #define set(x,y) (x.low=y, x.high=y) + + +#endif + +#endif /* OPERATORS_H_ */ diff --git a/regression/cegis/cegis_control_benchmark_04/safety_stability.c b/regression/cegis/cegis_control_benchmark_04/safety_stability.c new file mode 100644 index 00000000000..386adbbc06e --- /dev/null +++ b/regression/cegis/cegis_control_benchmark_04/safety_stability.c @@ -0,0 +1,505 @@ +#include +#include "benchmark.h" //benchmark header file +//#include "control_types.h" //included via benchmark.h +//#define CPROVER +//#ifdef INTERVAL + // #include "intervals.h" //included via control_types.h +//#endif +#include "operators.h" + +#ifdef CPROVER + //#define __DSVERIFIER_assert(x) __CPROVER_assume(x) + #define __DSVERIFIER_assert(x) __CPROVER_assert(x, "") +#else + #include + #define __DSVERIFIER_assert(x) assert(x) +#endif + +//#define NUMBERLOOPS 5 // Defined by benchmark script +#define INITIALSTATE_UPPERBOUND (__plant_precisiont)0.5 +#define INITIALSTATE_LOWERBOUND (__plant_precisiont)-0.5 +#define SAFE_STATE_UPPERBOUND (__plant_precisiont)1.0 +#define SAFE_STATE_LOWERBOUND (__plant_precisiont)-1.0 + +//other plant variables +//__controller_typet nondet_controller_type(void); + +extern __controller_typet K_fxp[NSTATES]; //nondet controller +//__controller_typet K_fxp[NSTATES]; //nondet controller +//const __controller_typet K_fxp[NSTATES] = { (__controller_typet) 0.0626, (__controller_typet) 0.0, (__controller_typet) 12.2421875 }; //nondet controller +//const __controller_typet K_fxp[NSTATES] = { 249.53271484375, 51.430419921875, -1887.991455078125 }; +//const __controller_typet K_fxp[NSTATES] = { 0.0626, 0.0, 12.2421875 }; +//const __controller_typet K_fxp[NSTATES] = {interval(0.0234375),interval(-0.1328125), interval(0.00390625)}; +__plant_typet _controller_inputs; +extern __plant_typet _controller_states[NSTATES]; //nondet initial states + +//matrices for stability calculation +__plant_typet _AminusBK[NSTATES][NSTATES]; + +__plant_typet __CPROVER_EIGEN_poly[NSTATES + 1u]; + +//stablity calc + +__plant_typet internal_pow(__plant_typet a, unsigned int b){ + + __plant_typet acc = one_type; + for (int i=0; i < b; i++){ + acc = mult(acc,a); + } + return acc; +} + + +int check_stability(void){ + + + #if NSTATES==1 + if(greaterthan(_AminusBK[0][0], 1) || lessthan(_AminusBK[0][0], -1)) + {return 0;} + else + {return 1;} +#endif + + +#define __a __CPROVER_EIGEN_poly +#define __n NSTATES + 1u + int lines = 2 * __n - 1; + int columns = __n; + __plant_typet m[lines][__n]; + int i,j; + + /* to put current values in stability counter-example + * look for current_stability (use: --no-slice) */ + __plant_typet current_stability[__n]; + for (i=0; i < __n; i++){ + current_stability[i] = __a[i]; + } + + /* check the first constraint condition F(1) > 0 */ + __plant_typet sum = zero_type; + for (i=0; i < __n; i++){ + sum = add(sum, __a[i]); + } + if (lessthan_equaltozero(sum)){ + printf("[DEBUG] the first constraint of Jury criteria failed: (F(1) > 0)"); + return 0; + } + + /* check the second constraint condition F(-1)*(-1)^n > 0 */ + sum = zero_type; + for (i=0; i < __n; i++){ + sum = add(sum, mult(__a[i] , internal_pow(minusone, NSTATES-i) )); + } + sum = mult(sum,internal_pow(minusone, NSTATES) ); + + if (lessthan_equaltozero(sum)){ + printf("[DEBUG] the second constraint of Jury criteria failed: (F(-1)*(-1)^n > 0)"); + return 0; + } + + /* check the third constraint condition abs(a0 < an*(z^n) */ + if(greaterthan( _abs(__a[__n-1]), __a[0])){ + // if (abs(__a[__n-1]) > __a[0]){ + printf("[DEBUG] the third constraint of Jury criteria failed: (abs(a0) < a_{n}*z^{n})"); + return 0; + } + + /* check the fourth constraint of condition (Jury Table) */ + for (i=0; i < lines; i++){ + for (j=0; j < columns; j++){ + m[i][j] = zero_type; + } + } + for (i=0; i < lines; i++){ + for (j=0; j < columns; j++){ + if (i == 0){ + m[i][j] = __a[j]; + continue; + } + if (i % 2 != 0 ){ + int x; + for(x=0; x= 0 ? 1 : 0; + for (i=0; i < lines; i++){ + if (i % 2 == 0){ + int line_is_positive = lessthanzero(m[i][0])? 0 : 1; + // int line_is_positive = m[i][0] >= 0 ? 1 : 0; + if (first_is_positive != line_is_positive){ + return 0; + } + continue; + } + } + return 1; +} + +#define __m _AminusBK +#if NSTATES==2 +void __CPROVER_EIGEN_charpoly_2(void) { //m00*m11 - m10*m11 - m00*x - m11*x + x^2 + + __CPROVER_EIGEN_poly[2] = sub ( mult(__m[0][0],__m[1][1]), mult(__m[1][0] , __m[1][1]) ); + + __CPROVER_EIGEN_poly[1] = sub (zero_type, add (__m[0][0], __m[1][1]) ) ; + // s^2 + __CPROVER_EIGEN_poly[0] = one_type; +} +#endif + +#if NSTATES==3 +void __CPROVER_EIGEN_charpoly_3(void) { +// m_11*m_22*m_33 + m_11*m_23*m_32 + m_12*m_21*m_33 - m_12*m_23*m_31 - m_13*m_21*m_32 + m_13*m_22*m_31 +__CPROVER_EIGEN_poly[3] = add(sub(sub(add(add(mult(__m[0][0],mult( __m[1][1], __m[2][2])), mult( __m[0][0] ,mult( __m[1][2] , __m[2][1]))), + mult(__m[0][1],mult( __m[1][0], __m[2][2]))), mult(__m[0][1],mult( __m[1][2], __m[2][0]) )), mult(__m[0][2] ,mult(__m[1][0], __m[2][1]))), + mult( __m[0][2], mult(__m[1][1],__m[2][0]))); +// (m_11*m_22 + m_11*m_33 - m_12*m_21 - m_13*m_31 + m_22*m_33 - m_23*m_32) * s +__CPROVER_EIGEN_poly[2] = sub(add(sub(sub(mult(__m[0][0], mult( __m[1][1], mult( __m[0][0], __m[2][2]))), mult(__m[0][1], __m[1][0])), + mult(__m[0][2],__m[2][0])), mult(__m[1][1], __m[2][2])),mult(__m[1][2], __m[2][1])); +// (-m_11 - m_22 - m_33) * s^2 +__CPROVER_EIGEN_poly[1] = sub(sub(sub(zero_type,__m[0][0]), __m[1][1]), __m[2][2]); +// s^3 +__CPROVER_EIGEN_poly[0] = one_type; + +} +#endif +#if NSTATES==4 +void __CPROVER_EIGEN_charpoly_4(void) { + + __CPROVER_EIGEN_poly[4] = __m[0][0]*__m[1][1]*__m[2][2]*__m[3][3] - __m[0][0]*__m[1][1]*__m[2][3]*__m[3][2] - __m[0][0]*__m[1][2]*__m[2][1]*__m[3][3] + __m[0][0]*__m[1][2]*__m[2][3]*__m[3][1] + __m[0][0]*__m[1][3]*__m[2][1]*__m[3][2] - + __m[0][0]*__m[1][3]*__m[2][2]*__m[3][1] - __m[0][1]*__m[1][0]*__m[2][2]*__m[3][3] + __m[0][1]*__m[1][0]*__m[2][3]*__m[3][2] + __m[0][1]*__m[1][2]*__m[2][0]*__m[3][3] - __m[0][1]*__m[1][2]*__m[2][3]*__m[3][0] - + __m[0][1]*__m[1][3]*__m[2][0]*__m[3][2] + __m[0][1]*__m[1][3]*__m[2][2]*__m[3][0] + __m[0][2]*__m[1][0]*__m[2][1]*__m[3][3] - __m[0][2]*__m[1][0]*__m[2][3]*__m[3][1] - __m[0][2]*__m[1][1]*__m[2][0]*__m[3][3] + + __m[0][2]*__m[1][1]*__m[2][3]*__m[3][0] + __m[0][2]*__m[1][3]*__m[2][0]*__m[3][1] - __m[0][2]*__m[1][3]*__m[2][1]*__m[3][0] - __m[0][3]*__m[1][0]*__m[2][1]*__m[3][2] + __m[0][3]*__m[1][0]*__m[2][2]*__m[3][1] + + __m[0][3]*__m[1][1]*__m[2][0]*__m[3][2] - __m[0][3]*__m[1][1]*__m[2][2]*__m[3][0] - __m[0][3]*__m[1][2]*__m[2][0]*__m[3][1] + __m[0][3]*__m[1][2]*__m[2][1]*__m[3][0]; + + +__CPROVER_EIGEN_poly[3] = - __m[0][0]*__m[1][1]*__m[2][2] + __m[0][0]*__m[1][2]*__m[2][1] + __m[0][1]*__m[1][0]*__m[2][2] - __m[0][1]*__m[1][2]*__m[2][0] - __m[0][2]*__m[1][0]*__m[2][1] + __m[0][2]*__m[1][1]*__m[2][0] + - __m[0][0]*__m[1][1]*__m[3][3] + __m[0][0]*__m[1][3]*__m[3][1] + __m[0][1]*__m[1][0]*__m[3][3] - __m[0][1]*__m[1][3]*__m[3][0] - __m[0][3]*__m[1][0]*__m[3][1] + __m[0][3]*__m[1][1]*__m[3][0] + - __m[0][0]*__m[2][2]*__m[3][3] + __m[0][0]*__m[2][3]*__m[3][2] + __m[0][2]*__m[2][0]*__m[3][3] - __m[0][2]*__m[2][3]*__m[3][0] - __m[0][3]*__m[2][0]*__m[3][2] + __m[0][3]*__m[2][2]*__m[3][0] + - __m[1][1]*__m[2][2]*__m[3][3] + __m[1][1]*__m[2][3]*__m[3][2] + __m[1][2]*__m[2][1]*__m[3][3] - __m[1][2]*__m[2][3]*__m[3][1] - __m[1][3]*__m[2][1]*__m[3][2] + __m[1][3]*__m[2][2]*__m[3][1]; + + + __CPROVER_EIGEN_poly[2] = + __m[0][0]*__m[1][1] - __m[0][1]*__m[1][0] + __m[0][0]*__m[2][2] - __m[0][2]*__m[2][0] + __m[0][0]*__m[3][3] - __m[0][3]*__m[3][0] + __m[1][1]*__m[2][2] - + __m[1][2]*__m[2][1] + __m[1][1]*__m[3][3] - __m[1][3]*__m[3][1] + __m[2][2]*__m[3][3] - __m[2][3]*__m[3][2]; + + + __CPROVER_EIGEN_poly[1] = - __m[3][3] - __m[2][2] - __m[1][1] - __m[0][0]; + __CPROVER_EIGEN_poly[0] = 1.0; +} +#endif + +void __CPROVER_EIGEN_charpoly(void){ + + #if NSTATES==1 + //do nothing + #elif NSTATES==2 + __CPROVER_EIGEN_charpoly_2(); + #elif NSTATES==3 + __CPROVER_EIGEN_charpoly_3(); + #elif NSTATES==4 + __CPROVER_EIGEN_charpoly_4(); + #endif + + // Normalise + __plant_typet max_coefficient=zero_type; + for (int i = 0; i <= NSTATES; ++i) + if (lessthan(max_coefficient, __CPROVER_EIGEN_poly[i])) + max_coefficient=__CPROVER_EIGEN_poly[i]; + + for (int i = 0; i <= NSTATES; ++i) + __CPROVER_EIGEN_poly[i]=div(__CPROVER_EIGEN_poly[i], max_coefficient); +} + +void A_minus_B_K() +{ + +#ifdef CPROVER + __CPROVER_array_copy(_AminusBK, _controller_A); +#else + for(int i=0; iINPUT_LOWERBOUND); + #else + __CPROVER_assume(_controller_inputs < INPUT_UPPERBOUND && _controller_inputs > INPUT_LOWERBOUND); + #endif + #endif + + } + } + +__plant_typet states_equals_A_states_plus_B_inputs_result[NSTATES]; + +void states_equals_A_states_plus_B_inputs(void) +{ + + #ifdef CPROVER + __CPROVER_array_set(states_equals_A_states_plus_B_inputs_result, zero_type); + #else + for(int i=0; iSAFE_STATE_LOWERBOUND); + __DSVERIFIER_assert( _controller_states[1]SAFE_STATE_LOWERBOUND); + #if NSTATES==3 || NSTATES==4 + __DSVERIFIER_assert( _controller_states[2]SAFE_STATE_LOWERBOUND); + #endif + #if NSTATES==4 + __DSVERIFIER_assert( _controller_states[3]SAFE_STATE_LOWERBOUND); + #endif +#else + for(int i=0; iSAFE_STATE_LOWERBOUND); + } +#endif +#else +#ifdef CPROVER + __CPROVER_array_copy(_controller_states, states_equals_A_states_plus_B_inputs_result); + /*for(i=0; iSAFE_STATE_LOWERBOUND); + __DSVERIFIER_assert( _controller_states[1].highSAFE_STATE_LOWERBOUND); + #if NSTATES==3 || NSTATES==4 + __DSVERIFIER_assert( _controller_states[2].highSAFE_STATE_LOWERBOUND); + #endif + #if NSTATES==4 + __DSVERIFIER_assert( _controller_states[3].highSAFE_STATE_LOWERBOUND); + #endif +#else + for(int i=0; iSAFE_STATE_LOWERBOUND); + } +#endif +#endif + + + + } + + + +int check_safety(void) +{ + + for(int j=0; j=INITIALSTATE_LOWERBOUND); + //__CPROVER_assume(_controller_states[j]!=zero_type); + //#else + //__CPROVER_assume(_controller_states[j]<=INITIALSTATE_UPPERBOUND && _controller_states[j]>=INITIALSTATE_LOWERBOUND); + //__CPROVER_assume(_controller_states[j]!=zero_type); + //#endif + #endif + } + + for(int k=0; kSAFE_STATE_UPPERBOUND || _controller_states[i].highSAFE_STATE_UPPERBOUND || _controller_states[i] 0); +} + +int safety_stability(void) { +#ifdef INTERVAL + get_bounds(); //get interval bounds +#endif + closed_loop(); //calculate A - BK + __CPROVER_EIGEN_charpoly(); + __DSVERIFIER_assert(check_stability()); +#if NSTATES != 1 + //check_safety(); + __DSVERIFIER_assert(check_safety()); +#endif + +#ifdef CPROVER + __controller_typet K_fxp_trace[NSTATES] = { controller_cast(0.0) }; + __CPROVER_array_copy(K_fxp_trace, K_fxp); + //__CPROVER_assert(0 == 1, ""); +#endif + + return 0; +} + +int main(void) { +#ifdef CPROVER + assume_corner_cases_for_states(); +#else + for (int poleIndex = 0; poleIndex < NPOLES; ++poleIndex) { + for (int stateIndex = 0; stateIndex < NSTATES; ++stateIndex) { + _controller_states[stateIndex] = _state_poles[poleIndex][poleIndex]; + } +#endif + assert_nonzero_controller(); + safety_stability(); + //__CPROVER_assert(0 == 1, ""); +#ifndef CPROVER + } +#endif +} diff --git a/regression/cegis/cegis_control_benchmark_04/test.desc b/regression/cegis/cegis_control_benchmark_04/test.desc new file mode 100644 index 00000000000..a4d971121db --- /dev/null +++ b/regression/cegis/cegis_control_benchmark_04/test.desc @@ -0,0 +1,7 @@ +CORE +safety_stability.c +--gcc --round-to-minus-inf --cegis-control --cegis-statistics --cegis-max-size 1 --cegis-show-iterations -D CPROVER -D _CONTROL_FLOAT_WIDTH=64 -D _CONTORL_RADIX_WIDTH=24 -D NUMBERLOOPS=10 +EXIT=0 +SIGNAL=0 +-- +warning: ignoring From 940eb3493cbc1defaa11d0d8aad89523d8c4c68e Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 23 Jan 2017 10:59:22 +0000 Subject: [PATCH 005/166] Generalise dominators template (#422) This previously assumed some internal specifics of goto_programt. This generalises it to allow the CFG graph to specify how to retrieve the start and end nodes or detect an empty program, and moves the details particular to goto_programt into its particular specialisation. This allows us to use the generic dominators implementation on other control-flow graph representations. --- src/analyses/cfg_dominators.h | 51 ++++++++++++++++++++++++++--------- src/goto-programs/cfg.h | 3 +++ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/analyses/cfg_dominators.h b/src/analyses/cfg_dominators.h index 01ca0871a16..209a76852e6 100644 --- a/src/analyses/cfg_dominators.h +++ b/src/analyses/cfg_dominators.h @@ -124,13 +124,13 @@ void cfg_dominators_templatet::fixedpoint(P &program) { std::list worklist; - if(program.instructions.empty()) + if(cfg.nodes_empty(program)) return; if(post_dom) - entry_node = --program.instructions.end(); + entry_node=cfg.get_last_node(program); else - entry_node = program.instructions.begin(); + entry_node=cfg.get_first_node(program); typename cfgt::nodet &n=cfg[cfg.entry_map[entry_node]]; n.dominators.insert(entry_node); @@ -200,6 +200,25 @@ void cfg_dominators_templatet::fixedpoint(P &program) /*******************************************************************\ +Function: dominators_pretty_print_node + + Inputs: `node` to print and stream `out` to pretty-print it to + + Outputs: + + Purpose: Pretty-print a single node in the dominator tree. + Supply a specialisation if operator<< is not sufficient. + +\*******************************************************************/ + +template +void dominators_pretty_print_node(const T &node, std::ostream &out) +{ + out << node; +} + +/*******************************************************************\ + Function: cfg_dominators_templatet::output Inputs: @@ -215,20 +234,20 @@ void cfg_dominators_templatet::output(std::ostream &out) const { for(const auto &node : cfg.entry_map) { - unsigned n=node.first->location_number; + T n=node.first; + dominators_pretty_print_node(n, out); if(post_dom) - out << n << " post-dominated by "; + out << " post-dominated by "; else - out << n << " dominated by "; - for(typename target_sett::const_iterator - d_it=node.second.dominators.begin(); - d_it!=node.second.dominators.end(); - ) // no d_it++ + out << " dominated by "; + bool first=true; + for(const auto &d : cfg[node.second].dominators) { - out << (*d_it)->location_number; - if (++d_it!=node.second.dominators.end()) + if(!first) out << ", "; + first=false; + dominators_pretty_print_node(d, out); } out << "\n"; } @@ -240,4 +259,12 @@ typedef cfg_dominators_templatet cfg_post_dominatorst; +template<> +inline void dominators_pretty_print_node( + const goto_programt::const_targett& node, + std::ostream& out) +{ + out << node->location_number; +} + #endif // CPROVER_ANALYSES_CFG_DOMINATORS_H diff --git a/src/goto-programs/cfg.h b/src/goto-programs/cfg.h index 7c339782937..319f8d3542f 100644 --- a/src/goto-programs/cfg.h +++ b/src/goto-programs/cfg.h @@ -131,6 +131,9 @@ class cfg_baset:public graph< cfg_base_nodet > compute_edges(goto_functions, goto_program); } + I get_first_node(P &program) const { return program.instructions.begin(); } + I get_last_node(P &program) const { return --program.instructions.end(); } + bool nodes_empty(P &program) const { return program.instructions.empty(); } }; /*******************************************************************\ From 649d928948f87ac1acc1239b23bf84afedea657a Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 13 Dec 2016 16:15:16 +0000 Subject: [PATCH 006/166] Implement local variable live range merging Previously one entry in the local variable table meant one declaration at runtime. We now merge live ranges when it appears they refer to the same variable due to control flow from one live range to another. Variable declarations are placed at a program point that dominates all users. This is currently unused, but will be plumbed in in a subsequent commit. --- .../java_bytecode_convert_method.cpp | 458 +++++++++++++++++- 1 file changed, 456 insertions(+), 2 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 8ee9ba3db46..e9248c18440 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -6,8 +6,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#define DEBUG - #ifdef DEBUG #include #endif @@ -21,12 +19,17 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include +#include + #include "java_bytecode_convert_method.h" #include "bytecode_info.h" #include "java_types.h" #include #include +#include +#include class patternt { @@ -65,6 +68,8 @@ class java_bytecode_convert_methodt:public messaget typedef java_bytecode_parse_treet::methodt methodt; typedef java_bytecode_parse_treet::instructiont instructiont; typedef methodt::instructionst instructionst; + typedef methodt::local_variable_tablet local_variable_tablet; + typedef methodt::local_variablet local_variablet; void operator()(const symbolt &class_symbol, const methodt &method) { @@ -72,11 +77,27 @@ class java_bytecode_convert_methodt:public messaget } protected: + irep_idt method_id; symbol_tablet &symbol_table; irep_idt current_method; typet method_return_type; +public: + struct holet { + unsigned start_pc; + unsigned length; + }; + + struct local_variable_with_holest + { + local_variablet var; + std::vector holes; + }; + + typedef std::vector local_variable_table_with_holest; + +protected: class variablet { public: @@ -84,6 +105,8 @@ class java_bytecode_convert_methodt:public messaget size_t start_pc; size_t length; bool is_parameter; + std::vector holes; + variablet() : symbol_expr(), is_parameter(false) {} }; typedef std::vector variablest; @@ -239,7 +262,24 @@ class java_bytecode_convert_methodt:public messaget bool done; }; +public: typedef std::map address_mapt; + typedef cfg_dominators_templatet java_cfg_dominatorst; + +protected: + + void find_initialisers( + local_variable_table_with_holest& vars, + const address_mapt& amap, + const java_cfg_dominatorst& doms); + + void find_initialisers_for_slot( + local_variable_table_with_holest::iterator firstvar, + local_variable_table_with_holest::iterator varlimit, + const address_mapt& amap, + const java_cfg_dominatorst& doms); + + void setup_local_variables(const methodt& m, const address_mapt& amap); struct block_tree_nodet { @@ -505,6 +545,420 @@ void java_bytecode_convert_methodt::convert( symbol_table.add(method_symbol); } +typedef java_bytecode_convert_methodt::holet holet; +typedef java_bytecode_convert_methodt::local_variable_with_holest local_variable_with_holest; +typedef java_bytecode_convert_methodt::local_variable_table_with_holest local_variable_table_with_holest; + +namespace { + bool lt_index(const local_variable_with_holest& a, + const local_variable_with_holest& b) + { + return a.var.indexvar.start_pcvar.start_pc; + } +} + +// Convert the address-map to a cfg-graph so we can compute dominators: + +typedef java_bytecode_convert_methodt::address_mapt address_mapt; +typedef java_bytecode_convert_methodt::java_cfg_dominatorst java_cfg_dominatorst; + +template +struct procedure_local_cfg_baset : + public graph > +{ + typedef std::map entry_mapt; + entry_mapt entry_map; + + procedure_local_cfg_baset() {} + + void operator()(const address_mapt& amap) + { + for(const auto& inst : amap) + { + // Map instruction PCs onto node indices: + entry_map[inst.first]=this->add_node(); + // Map back: + (*this)[entry_map[inst.first]].PC=inst.first; + } + for(const auto& inst : amap) + { + for(auto succ : inst.second.successors) + this->add_edge(entry_map.at(inst.first),entry_map.at(succ)); + } + } + + unsigned get_first_node(const address_mapt& amap) const { return amap.begin()->first; } + unsigned get_last_node(const address_mapt& amap) const { return (--amap.end())->first; } + unsigned nodes_empty(const address_mapt& amap) const { return amap.empty(); } + +}; + +typedef java_bytecode_convert_methodt::local_variablet local_variablet; +typedef std::map > predecessor_mapt; + +struct is_predecessor_of +{ + const predecessor_mapt& order; + + is_predecessor_of(const predecessor_mapt& _order) : order(_order) {} + + bool operator()(local_variable_with_holest* a, + local_variable_with_holest* b) const + { + auto findit=order.find(a); + if(findit==order.end()) + return false; + return findit->second.count(b)>0; + } +}; + +static void gather_transitive_predecessors( + local_variable_with_holest* start, + const predecessor_mapt& predecessor_map, + std::set& result) +{ + if(!result.insert(start).second) + return; + auto findit=predecessor_map.find(start); + if(findit==predecessor_map.end()) + return; + for(const auto pred : findit->second) + gather_transitive_predecessors(pred,predecessor_map,result); +} + +static bool is_store_to_slot( + const java_bytecode_convert_methodt::instructiont& inst, + unsigned slotidx) +{ + const std::string prevstatement=id2string(inst.statement); + if(!(prevstatement.size()>=1 && prevstatement.substr(1,5)=="store")) + return false; + + std::string storeslot; + if(inst.args.size()==1) + { + const auto& arg=inst.args[0]; + storeslot=id2string(to_constant_expr(arg).get_value()); + } + else + { + assert(prevstatement[6]=='_' && prevstatement.size()==8); + storeslot=prevstatement[7]; + assert(isdigit(storeslot[0])); + } + auto storeslotidx=safe_string2unsigned(storeslot); + return storeslotidx==slotidx; +} + +static void maybe_add_hole( + local_variable_with_holest& var, + unsigned from, + unsigned to) +{ + assert(to>=from); + if(to!=from) + var.holes.push_back({from,to-from}); +} + +void java_bytecode_convert_methodt::find_initialisers_for_slot( + local_variable_table_with_holest::iterator firstvar, + local_variable_table_with_holest::iterator varlimit, + const address_mapt& amap, + const java_cfg_dominatorst& doms) +{ + // Build a simple map from instruction PC to the variable live in this slot at that PC, + // and a map from each variable to variables that flow into it: + + std::vector var_map; + predecessor_mapt predecessor_map; + for(auto it=firstvar, itend=varlimit; it!=itend; ++it) + { + if(it->var.start_pc+it->var.length > var_map.size()) + var_map.resize(it->var.start_pc+it->var.length); + + for(unsigned idx=it->var.start_pc, + idxlim=it->var.start_pc+it->var.length; + idx!=idxlim; ++idx) + { + assert((!var_map[idx]) && "Local variable table clash?"); + var_map[idx]=&*it; + } + } + + // Now find variables that flow together by walking backwards to find initialisers + // or branches from other live ranges: + + for(auto it=firstvar, itend=varlimit; it!=itend; ++it) + { + // Don't alter parameters: + if(it->var.start_pc==0) + continue; + + // Find the last instruction within the live range: + unsigned end_pc=it->var.start_pc+it->var.length; + auto amapit=amap.find(end_pc); + auto old_amapit=amapit; + --amapit; + if(old_amapit==amap.end()) + assert(end_pc>amapit->first && + "Instruction live range doesn't align to instruction boundary?"); + + // Find vartable entries that flow into this one: + unsigned new_start_pc=it->var.start_pc; + for(; amapit->first >= it->var.start_pc; --amapit) + { + for(auto pred : amapit->second.predecessors) + { + auto pred_var=var_map[pred]; + if(pred_var==&*it) + { + // Flow from within same live range? + continue; + } + else if(!pred_var) + { + // Flow from out of range? + // Check if this is an initialiser, and if so expand the live range + // to include it, but don't check its predecessors: + auto inst_before_this=amapit; + --inst_before_this; + if(amapit->first!=it->var.start_pc || inst_before_this->first!=pred) + throw "Local variable table: unexpected flow from out of range"; + if(!is_store_to_slot(*(inst_before_this->second.source),it->var.index)) + throw "Local variable table: didn't find expected initialising store"; + new_start_pc=pred; + } + else { + if(pred_var->var.name!=it->var.name || pred_var->var.signature!=it->var.signature) + throw "Local variable table: flow from variable with clashing name or signature"; + // OK, this is a flow from a similar but distinct entry in the local var table. + predecessor_map[&*it].insert(pred_var); + } + } + } + + // If a simple pre-block initialiser was found, add it to the live range now: + it->var.length+=(it->var.start_pc-new_start_pc); + it->var.start_pc=new_start_pc; + + } + + // OK, we've established the flows all seem sensible. Now merge vartable entries + // according to the predecessor_map: + + // Top-sort so that we get the bottom variables first: + is_predecessor_of comp(predecessor_map); + std::vector topsorted_vars; + for(auto it=firstvar,itend=varlimit; it!=itend; ++it) + topsorted_vars.push_back(&*it); + + std::sort(topsorted_vars.begin(),topsorted_vars.end(),comp); + + // Now merge the entries: + for(auto merge_into : topsorted_vars) + { + // Already merged into another variable? + if(merge_into->var.length==0) + continue; + + std::set merge_vars; + gather_transitive_predecessors(merge_into,predecessor_map,merge_vars); + if(merge_vars.size()==1) + continue; + + // Because we need a lexically-scoped declaration, we must have the merged variable + // enter scope both in a block that dominates all entries, and which + // precedes them in program order. + unsigned first_pc=var_map.size(); + unsigned last_pc=0; + for(auto v : merge_vars) + { + if(v->var.start_pc < first_pc) + first_pc = v->var.start_pc; + if(v->var.start_pc+v->var.length > last_pc) + last_pc=v->var.start_pc+v->var.length; + } + + std::vector candidate_dominators; + for(auto v : merge_vars) + { + const auto& this_var_doms=doms.cfg[doms.cfg.entry_map.at(v->var.start_pc)].dominators; + for(const auto this_var_dom : this_var_doms) + if(this_var_dom <= first_pc) + candidate_dominators.push_back(this_var_dom); + } + std::sort(candidate_dominators.begin(),candidate_dominators.end()); + + // Working from the back, simply find the first PC that occurs merge_vars.size() + // times and therefore dominates all vars we seek to merge: + + unsigned found_dominator=var_map.size(); + for(auto domit=candidate_dominators.rbegin(), domitend=candidate_dominators.rend(); + domit != domitend && found_dominator==var_map.size(); /* Don't increment here */) + { + unsigned repeats=0; + auto dom=*domit; + while(domit!=domitend && *domit==dom) + { + ++domit; + ++repeats; + } + assert(repeats<=merge_vars.size()); + if(repeats==merge_vars.size()) + found_dominator=dom; + } + + if(found_dominator==var_map.size()) + throw "Variable live ranges with no common dominator?"; + + // Populate the holes in the live range (addresses where the new variable + // will be in scope, but references to this stack slot should not resolve to it + // as it was not visible in the original local variable table) + std::vector sorted_by_startpc( + merge_vars.begin(),merge_vars.end()); + std::sort(sorted_by_startpc.begin(),sorted_by_startpc.end(),lt_startpc); + + maybe_add_hole(*merge_into,found_dominator,sorted_by_startpc[0]->var.start_pc); + for(unsigned idx=0; idxvar.start_pc + sorted_by_startpc[idx]->var.length, + sorted_by_startpc[idx+1]->var.start_pc); + + // Apply the changes: + merge_into->var.start_pc=found_dominator; + merge_into->var.length=last_pc-found_dominator; + + #ifdef DEBUG + status() << "Merging " << merge_vars.size() << " variables named " << merge_into->var.name << + "; new live range " << merge_into->var.start_pc << "-" << + merge_into->var.start_pc + merge_into->var.length << eom; + #endif + + // Nuke the now-subsumed var-table entries: + for(auto& v : merge_vars) + if(v!=merge_into) + v->var.length=0; + + } + +} + +static void walk_to_next_index( + local_variable_table_with_holest::iterator& it1, + local_variable_table_with_holest::iterator& it2, + local_variable_table_with_holest::iterator itend) +{ + if(it2==itend) + { + it1=itend; + return; + } + + auto old_it2=it2; + auto index=it2->var.index; + while(it2!=itend && it2->var.index==index) + ++it2; + it1=old_it2; +} + +void java_bytecode_convert_methodt::find_initialisers( + local_variable_table_with_holest& vars, + const address_mapt& amap, + const java_cfg_dominatorst& doms) +{ + // Handle one stack slot at a time: + std::sort(vars.begin(),vars.end(),lt_index); + + auto it1=vars.begin(); + auto it2=it1; + auto itend=vars.end(); + walk_to_next_index(it1,it2,itend); + for(; it1!=itend; walk_to_next_index(it1,it2,itend)) + find_initialisers_for_slot(it1,it2,amap,doms); +} + +void java_bytecode_convert_methodt::setup_local_variables(const methodt& m, + const address_mapt& amap) +{ + // Compute CFG dominator tree + java_cfg_dominatorst doms; + doms(amap); + + // Find out which local variable table entries should be merged: + // Wrap each entry so we have somewhere to record live ranges with holes: + std::vector vars_with_holes; + for(const auto& v : m.local_variable_table) + vars_with_holes.push_back({v, {}}); + + find_initialisers(vars_with_holes,amap,doms); + + // Clean up removed records from the variable table: + + size_t toremove=0; + for(size_t i=0; i<(vars_with_holes.size()-toremove); ++i) + { + auto& v=vars_with_holes[i]; + if(v.var.length==0) + { + // Move to end; consider the new element we've swapped in: + ++toremove; + if(i!=vars_with_holes.size()-toremove) // Already where it needs to be? + std::swap(v,vars_with_holes[vars_with_holes.size()-toremove]); + --i; + } + } + + // Remove un-needed entries. + vars_with_holes.resize(vars_with_holes.size()-toremove); + + // Do the locals and parameters in the variable table, which is available when + // compiled with -g or for methods with many local variables in the latter + // case, different variables can have the same index, depending on the + // context. + // + // to calculate which variable to use, one uses the address of the instruction + // that uses the variable, the size of the instruction and the start_pc / + // length values in the local variable table + for(const auto & v : vars_with_holes) + { + if(v.var.start_pc==0) // Parameter? + continue; + + typet t=java_type_from_string(v.var.signature); + std::ostringstream id_oss; + id_oss << method_id << "::" << v.var.start_pc << "::" << v.var.name; + irep_idt identifier(id_oss.str()); + symbol_exprt result(identifier, t); + result.set(ID_C_base_name, v.var.name); + + variables[v.var.index].push_back(variablet()); + auto& newv=variables[v.var.index].back(); + newv.symbol_expr = result; + newv.start_pc = v.var.start_pc; + newv.length = v.var.length; + newv.holes=std::move(v.holes); + + symbolt new_symbol; + new_symbol.name=identifier; + new_symbol.type=t; + new_symbol.base_name=v.var.name; + new_symbol.pretty_name=id2string(identifier).substr(6, std::string::npos); + new_symbol.mode=ID_java; + new_symbol.is_type=false; + new_symbol.is_file_local=true; + new_symbol.is_thread_local=true; + new_symbol.is_lvalue=true; + symbol_table.add(new_symbol); + } + +} + /*******************************************************************\ Function: java_bytecode_convert_methodt::get_bytecode_info From ac93ee32420d0a7b842a8d98c936d0721fab712d Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 19 Jan 2017 10:38:19 +0000 Subject: [PATCH 007/166] Replace old variable table implementation This uses the local variable table implementation introduced in the previous commit, replacing the existing simple variable table lookup code that could inadvertently split live ranges when a variable's live range occupies multiple disjoint address ranges and so is declared using multiple entries in the local variable table. --- .../java_bytecode_convert_method.cpp | 91 ++++++++++--------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index e9248c18440..4e0d9473725 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -120,18 +120,27 @@ class java_bytecode_convert_methodt:public messaget } instruction_sizet; // return corresponding reference of variable - const variablet &find_variable_for_slot( - size_t address, - variablest &var_list, - instruction_sizet inst_size) + const variablet &find_variable_for_slot(size_t address, variablest &var_list) { for(const variablet &var : var_list) { size_t start_pc=var.start_pc; size_t length=var.length; - if(address+(size_t)inst_size>=start_pc && - address=start_pc && address<(start_pc+length)) + { + bool found_hole=false; + for(auto &hole : var.holes) + { + if(address>=hole.start_pc && address<(hole.start_pc-hole.length)) + { + found_hole=true; + break; + } + } + if(found_hole) + continue; return var; + } } // add unnamed local variable to end of list at this index // with scope from 0 to INT_MAX @@ -155,7 +164,6 @@ class java_bytecode_convert_methodt:public messaget const exprt &arg, char type_char, size_t address, - instruction_sizet inst_size, variable_cast_argumentt do_cast) { irep_idt number=to_constant_expr(arg).get_value(); @@ -166,7 +174,7 @@ class java_bytecode_convert_methodt:public messaget // search variable in list for correct frame / address if necessary const variablet &var= - find_variable_for_slot(address, var_list, inst_size); + find_variable_for_slot(address, var_list); if(var.symbol_expr.get_identifier().empty()) { @@ -317,7 +325,7 @@ class java_bytecode_convert_methodt:public messaget void convert(const instructiont &); codet convert_instructions( - const instructionst &, const code_typet &); + const methodt &, const code_typet &); const bytecode_infot &get_bytecode_info(const irep_idt &statement); }; @@ -382,6 +390,7 @@ void java_bytecode_convert_methodt::convert( const irep_idt method_identifier= id2string(class_symbol.name)+"."+id2string(m.name)+":"+m.signature; + method_id=method_identifier; code_typet &code_type=to_code_type(member_type); method_return_type=code_type.return_type(); @@ -400,38 +409,24 @@ void java_bytecode_convert_methodt::convert( variables.clear(); - // Do the parameters and locals in the variable table, which is available when - // compiled with -g or for methods with many local variables in the latter - // case, different variables can have the same index, depending on the - // context. - // - // to calculate which variable to use, one uses the address of the instruction - // that uses the variable, the size of the instruction and the start_pc / - // length values in the local variable table + // find parameter names in the local variable table: for(const auto &v : m.local_variable_table) { + if(v.start_pc!=0) // Local? + continue; + typet t=java_type_from_string(v.signature); std::ostringstream id_oss; - id_oss << method_identifier << "::" << v.start_pc << "::" << v.name; + id_oss << method_id << "::" << v.name; irep_idt identifier(id_oss.str()); symbol_exprt result(identifier, t); result.set(ID_C_base_name, v.name); - size_t number_index_entries=variables[v.index].size(); - variables[v.index].resize(number_index_entries+1); - variables[v.index][number_index_entries].symbol_expr=result; - variables[v.index][number_index_entries].start_pc=v.start_pc; - variables[v.index][number_index_entries].length=v.length; - symbolt new_symbol; - new_symbol.name=identifier; - new_symbol.type=t; - new_symbol.base_name=v.name; - new_symbol.pretty_name=strip_java_namespace_prefix(identifier); - new_symbol.mode=ID_java; - new_symbol.is_type=false; - new_symbol.is_file_local=true; - new_symbol.is_thread_local=true; - new_symbol.is_lvalue=true; - symbol_table.add(new_symbol); + + variables[v.index].push_back(variablet()); + auto &newv=variables[v.index].back(); + newv.symbol_expr = result; + newv.start_pc = v.start_pc; + newv.length = v.length; } // set up variables array @@ -533,9 +528,8 @@ void java_bytecode_convert_methodt::convert( method_has_this=code_type.has_this(); tmp_vars.clear(); - if((!m.is_abstract) && (!m.is_native)) - method_symbol.value=convert_instructions(m.instructions, code_type); + method_symbol.value=convert_instructions(m, code_type); // do we have the method symbol already? const auto s_it=symbol_table.symbols.find(method.get_name()); @@ -1309,9 +1303,12 @@ static unsigned get_bytecode_type_width(const typet &ty) } codet java_bytecode_convert_methodt::convert_instructions( - const instructionst &instructions, + const methodt &method, const code_typet &method_type) { + + const instructionst& instructions=method.instructions; + // Run a worklist algorithm, assuming that the bytecode has not // been tampered with. See "Leroy, X. (2003). Java bytecode // verification: algorithms and formalizations. Journal of Automated @@ -1423,6 +1420,10 @@ codet java_bytecode_convert_methodt::convert_instructions( } } + // Now that the control flow graph is built, set up our local variables + // (these require the graph to determine live ranges) + setup_local_variables(method,address_map); + std::set working_set; if(!instructions.empty()) working_set.insert(instructions.front().address); @@ -1652,7 +1653,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // store value into some local variable assert(op.size()==1 && results.empty()); - exprt var=variable(arg0, statement[0], i_it->address, INST_INDEX, NO_CAST); + exprt var=variable(arg0, statement[0], i_it->address, NO_CAST); exprt toassign=op[0]; if('a'==statement[0] && toassign.type()!=var.type()) @@ -1683,7 +1684,7 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement==patternt("?load")) { // load a value from a local variable - results[0]=variable(arg0, statement[0], i_it->address, INST_INDEX, CAST_AS_NEEDED); + results[0]=variable(arg0, statement[0], i_it->address, CAST_AS_NEEDED); } else if(statement=="ldc" || statement=="ldc_w" || statement=="ldc2" || statement=="ldc2_w") @@ -1751,7 +1752,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // if(retaddr==5) goto 5; else if(retaddr==10) goto 10; ... assert(op.empty() && results.empty()); code_blockt branches; - auto retvar=variable(arg0, 'a', i_it->address, INST_INDEX, NO_CAST); + auto retvar=variable(arg0, 'a', i_it->address, NO_CAST); assert(!jsr_ret_targets.empty()); for(size_t idx=0, idxlim=jsr_ret_targets.size(); idx!=idxlim; ++idx) { @@ -1889,9 +1890,9 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement=="iinc") { code_assignt code_assign; - code_assign.lhs()=variable(arg0, 'i', i_it->address, INST_INDEX_CONST, NO_CAST); + code_assign.lhs()=variable(arg0, 'i', i_it->address, NO_CAST); code_assign.rhs()=plus_exprt( - variable(arg0, 'i', i_it->address, INST_INDEX_CONST, CAST_AS_NEEDED), + variable(arg0, 'i', i_it->address, CAST_AS_NEEDED), typecast_exprt(arg1, java_int_type())); c=code_assign; } @@ -2424,10 +2425,12 @@ codet java_bytecode_convert_methodt::convert_instructions( // Try to recover block structure as indicated in the local variable table: // The block tree node mirrors the block structure of root_block, - // indexing the Java PCs were each subblock starts and ends. + // indexing the Java PCs where each subblock starts and ends. block_tree_nodet root; code_blockt root_block; + // First create a simple flat list of basic blocks. We'll add lexical nesting + // constructs as variable live-ranges require next. bool start_new_block=true; for(const auto &address_pair : address_map) { @@ -2492,13 +2495,13 @@ codet java_bytecode_convert_methodt::convert_instructions( // Skip anonymous variables: if(v.symbol_expr.get_identifier()==irep_idt()) continue; - code_declt d(v.symbol_expr); auto &block=get_block_for_pcrange( root, root_block, v.start_pc, v.start_pc+v.length, std::numeric_limits::max()); + code_declt d(v.symbol_expr); block.operands().insert(block.operands().begin(), d); } } From 23f7d817ce5140c64d0d5e42310edd3fbb369d4a Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 19 Jan 2017 10:53:24 +0000 Subject: [PATCH 008/166] Factor the jbcm type and LVT functions into individual files --- src/java_bytecode/Makefile | 2 +- .../java_bytecode_convert_method.cpp | 787 +++--------------- .../java_bytecode_convert_method_class.h | 182 ++++ .../java_local_variable_table.cpp | 514 ++++++++++++ 4 files changed, 794 insertions(+), 691 deletions(-) create mode 100644 src/java_bytecode/java_bytecode_convert_method_class.h create mode 100644 src/java_bytecode/java_local_variable_table.cpp diff --git a/src/java_bytecode/Makefile b/src/java_bytecode/Makefile index 5a9626b1a6d..f13c327ef77 100644 --- a/src/java_bytecode/Makefile +++ b/src/java_bytecode/Makefile @@ -5,7 +5,7 @@ SRC = java_bytecode_language.cpp java_bytecode_parse_tree.cpp \ java_bytecode_typecheck_type.cpp java_bytecode_internal_additions.cpp \ java_root_class.cpp java_bytecode_parser.cpp bytecode_info.cpp \ java_class_loader.cpp jar_file.cpp java_object_factory.cpp \ - java_bytecode_convert_method.cpp + java_bytecode_convert_method.cpp java_local_variable_table.cpp INCLUDES= -I .. diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 4e0d9473725..2ad56bc9230 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -23,6 +23,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "java_bytecode_convert_method.h" +#include "java_bytecode_convert_method_class.h" #include "bytecode_info.h" #include "java_types.h" @@ -54,282 +55,6 @@ class patternt const char *p; }; -class java_bytecode_convert_methodt:public messaget -{ -public: - java_bytecode_convert_methodt( - symbol_tablet &_symbol_table, - message_handlert &_message_handler): - messaget(_message_handler), - symbol_table(_symbol_table) - { - } - - typedef java_bytecode_parse_treet::methodt methodt; - typedef java_bytecode_parse_treet::instructiont instructiont; - typedef methodt::instructionst instructionst; - typedef methodt::local_variable_tablet local_variable_tablet; - typedef methodt::local_variablet local_variablet; - - void operator()(const symbolt &class_symbol, const methodt &method) - { - convert(class_symbol, method); - } - -protected: - irep_idt method_id; - symbol_tablet &symbol_table; - - irep_idt current_method; - typet method_return_type; - -public: - struct holet { - unsigned start_pc; - unsigned length; - }; - - struct local_variable_with_holest - { - local_variablet var; - std::vector holes; - }; - - typedef std::vector local_variable_table_with_holest; - -protected: - class variablet - { - public: - symbol_exprt symbol_expr; - size_t start_pc; - size_t length; - bool is_parameter; - std::vector holes; - variablet() : symbol_expr(), is_parameter(false) {} - }; - - typedef std::vector variablest; - expanding_vector variables; - std::set used_local_names; - bool method_has_this; - - typedef enum instruction_sizet - { - INST_INDEX=2, INST_INDEX_CONST=3 - } instruction_sizet; - - // return corresponding reference of variable - const variablet &find_variable_for_slot(size_t address, variablest &var_list) - { - for(const variablet &var : var_list) - { - size_t start_pc=var.start_pc; - size_t length=var.length; - if(address>=start_pc && address<(start_pc+length)) - { - bool found_hole=false; - for(auto &hole : var.holes) - { - if(address>=hole.start_pc && address<(hole.start_pc-hole.length)) - { - found_hole=true; - break; - } - } - if(found_hole) - continue; - return var; - } - } - // add unnamed local variable to end of list at this index - // with scope from 0 to INT_MAX - // as it is at the end of the vector, it will only be taken into account - // if no other variable is valid - size_t list_length=var_list.size(); - var_list.resize(list_length+1); - var_list[list_length].start_pc=0; - var_list[list_length].length=std::numeric_limits::max(); - return var_list[list_length]; - } - - // JVM local variables - enum variable_cast_argumentt - { - CAST_AS_NEEDED, - NO_CAST - }; - - const exprt variable( - const exprt &arg, - char type_char, - size_t address, - variable_cast_argumentt do_cast) - { - irep_idt number=to_constant_expr(arg).get_value(); - - std::size_t number_int=safe_string2size_t(id2string(number)); - typet t=java_type_from_char(type_char); - variablest &var_list=variables[number_int]; - - // search variable in list for correct frame / address if necessary - const variablet &var= - find_variable_for_slot(address, var_list); - - if(var.symbol_expr.get_identifier().empty()) - { - // an un-named local variable - irep_idt base_name="anonlocal::"+id2string(number)+type_char; - irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); - - symbol_exprt result(identifier, t); - result.set(ID_C_base_name, base_name); - used_local_names.insert(result); - - return result; - } - else - { - exprt result=var.symbol_expr; - if(do_cast==CAST_AS_NEEDED && t!=result.type()) - result=typecast_exprt(result, t); - return result; - } - } - - // temporary variables - std::list tmp_vars; - - symbol_exprt tmp_variable(const std::string &prefix, const typet &type) - { - irep_idt base_name=prefix+"_tmp"+std::to_string(tmp_vars.size()); - irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); - - auxiliary_symbolt tmp_symbol; - tmp_symbol.base_name=base_name; - tmp_symbol.is_static_lifetime=false; - tmp_symbol.mode=ID_java; - tmp_symbol.name=identifier; - tmp_symbol.type=type; - symbol_table.add(tmp_symbol); - - symbol_exprt result(identifier, type); - result.set(ID_C_base_name, base_name); - tmp_vars.push_back(result); - - return result; - } - - // JVM program locations - irep_idt label(const irep_idt &address) - { - return "pc"+id2string(address); - } - - // JVM Stack - typedef std::vector stackt; - stackt stack; - - exprt::operandst pop(std::size_t n) - { - if(stack.size() successors; - std::set predecessors; - codet code; - stackt stack; - bool done; - }; - -public: - typedef std::map address_mapt; - typedef cfg_dominators_templatet java_cfg_dominatorst; - -protected: - - void find_initialisers( - local_variable_table_with_holest& vars, - const address_mapt& amap, - const java_cfg_dominatorst& doms); - - void find_initialisers_for_slot( - local_variable_table_with_holest::iterator firstvar, - local_variable_table_with_holest::iterator varlimit, - const address_mapt& amap, - const java_cfg_dominatorst& doms); - - void setup_local_variables(const methodt& m, const address_mapt& amap); - - struct block_tree_nodet - { - bool leaf; - std::vector branch_addresses; - std::vector branch; - block_tree_nodet():leaf(false) {} - explicit block_tree_nodet(bool l):leaf(l) {} - static block_tree_nodet get_leaf() { return block_tree_nodet(true); } - }; - - static void replace_goto_target( - codet &repl, - const irep_idt &old_label, - const irep_idt &new_label); - - code_blockt &get_block_for_pcrange( - block_tree_nodet &tree, - code_blockt &this_block, - unsigned address_start, - unsigned address_limit, - unsigned next_block_start_address); - - code_blockt &get_or_create_block_for_pcrange( - block_tree_nodet &tree, - code_blockt &this_block, - unsigned address_start, - unsigned address_limit, - unsigned next_block_start_address, - const address_mapt &amap, - bool allow_merge=true); - - // conversion - void convert(const symbolt &class_symbol, const methodt &); - void convert(const instructiont &); - - codet convert_instructions( - const methodt &, const code_typet &); - - const bytecode_infot &get_bytecode_info(const irep_idt &statement); -}; - const size_t SLOTS_PER_INTEGER(1u); const size_t INTEGER_WIDTH(64u); static size_t count_slots( @@ -368,6 +93,102 @@ static irep_idt strip_java_namespace_prefix(const irep_idt to_strip) return to_strip_str.substr(6, std::string::npos); } +java_bytecode_convert_methodt::java_bytecode_convert_methodt( + symbol_tablet &_symbol_table, + message_handlert &_message_handler) : + messaget(_message_handler), + symbol_table(_symbol_table) +{ +} + +const exprt java_bytecode_convert_methodt::variable( + const exprt &arg, + char type_char, + size_t address, + variable_cast_argumentt do_cast) +{ + irep_idt number=to_constant_expr(arg).get_value(); + + std::size_t number_int=safe_string2size_t(id2string(number)); + typet t=java_type_from_char(type_char); + variablest &var_list=variables[number_int]; + + // search variable in list for correct frame / address if necessary + const variablet &var=find_variable_for_slot(address, var_list); + + if(var.symbol_expr.get_identifier().empty()) + { + // an un-named local variable + irep_idt base_name="anonlocal::"+id2string(number)+type_char; + irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); + + symbol_exprt result(identifier, t); + result.set(ID_C_base_name, base_name); + used_local_names.insert(result); + return result; + } + else + { + exprt result=var.symbol_expr; + if(do_cast==CAST_AS_NEEDED && t!=result.type()) + result=typecast_exprt(result, t); + return result; + } +} + +symbol_exprt java_bytecode_convert_methodt::tmp_variable( + const std::string &prefix, const typet &type) +{ + irep_idt base_name=prefix+"_tmp"+std::to_string(tmp_vars.size()); + irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); + + auxiliary_symbolt tmp_symbol; + tmp_symbol.base_name=base_name; + tmp_symbol.is_static_lifetime=false; + tmp_symbol.mode=ID_java; + tmp_symbol.name=identifier; + tmp_symbol.type=type; + symbol_table.add(tmp_symbol); + + symbol_exprt result(identifier, type); + result.set(ID_C_base_name, base_name); + tmp_vars.push_back(result); + + return result; +} + +irep_idt java_bytecode_convert_methodt::label(const irep_idt &address) +{ + return "pc"+id2string(address); +} + +exprt::operandst java_bytecode_convert_methodt::pop(std::size_t n) +{ + if(stack.size()var.start_pcvar.start_pc; - } -} - -// Convert the address-map to a cfg-graph so we can compute dominators: - -typedef java_bytecode_convert_methodt::address_mapt address_mapt; -typedef java_bytecode_convert_methodt::java_cfg_dominatorst java_cfg_dominatorst; - -template -struct procedure_local_cfg_baset : - public graph > -{ - typedef std::map entry_mapt; - entry_mapt entry_map; - - procedure_local_cfg_baset() {} - - void operator()(const address_mapt& amap) - { - for(const auto& inst : amap) - { - // Map instruction PCs onto node indices: - entry_map[inst.first]=this->add_node(); - // Map back: - (*this)[entry_map[inst.first]].PC=inst.first; - } - for(const auto& inst : amap) - { - for(auto succ : inst.second.successors) - this->add_edge(entry_map.at(inst.first),entry_map.at(succ)); - } - } - - unsigned get_first_node(const address_mapt& amap) const { return amap.begin()->first; } - unsigned get_last_node(const address_mapt& amap) const { return (--amap.end())->first; } - unsigned nodes_empty(const address_mapt& amap) const { return amap.empty(); } - -}; - -typedef java_bytecode_convert_methodt::local_variablet local_variablet; -typedef std::map > predecessor_mapt; - -struct is_predecessor_of -{ - const predecessor_mapt& order; - - is_predecessor_of(const predecessor_mapt& _order) : order(_order) {} - - bool operator()(local_variable_with_holest* a, - local_variable_with_holest* b) const - { - auto findit=order.find(a); - if(findit==order.end()) - return false; - return findit->second.count(b)>0; - } -}; - -static void gather_transitive_predecessors( - local_variable_with_holest* start, - const predecessor_mapt& predecessor_map, - std::set& result) -{ - if(!result.insert(start).second) - return; - auto findit=predecessor_map.find(start); - if(findit==predecessor_map.end()) - return; - for(const auto pred : findit->second) - gather_transitive_predecessors(pred,predecessor_map,result); -} - -static bool is_store_to_slot( - const java_bytecode_convert_methodt::instructiont& inst, - unsigned slotidx) -{ - const std::string prevstatement=id2string(inst.statement); - if(!(prevstatement.size()>=1 && prevstatement.substr(1,5)=="store")) - return false; - - std::string storeslot; - if(inst.args.size()==1) - { - const auto& arg=inst.args[0]; - storeslot=id2string(to_constant_expr(arg).get_value()); - } - else - { - assert(prevstatement[6]=='_' && prevstatement.size()==8); - storeslot=prevstatement[7]; - assert(isdigit(storeslot[0])); - } - auto storeslotidx=safe_string2unsigned(storeslot); - return storeslotidx==slotidx; -} - -static void maybe_add_hole( - local_variable_with_holest& var, - unsigned from, - unsigned to) -{ - assert(to>=from); - if(to!=from) - var.holes.push_back({from,to-from}); -} - -void java_bytecode_convert_methodt::find_initialisers_for_slot( - local_variable_table_with_holest::iterator firstvar, - local_variable_table_with_holest::iterator varlimit, - const address_mapt& amap, - const java_cfg_dominatorst& doms) -{ - // Build a simple map from instruction PC to the variable live in this slot at that PC, - // and a map from each variable to variables that flow into it: - - std::vector var_map; - predecessor_mapt predecessor_map; - for(auto it=firstvar, itend=varlimit; it!=itend; ++it) - { - if(it->var.start_pc+it->var.length > var_map.size()) - var_map.resize(it->var.start_pc+it->var.length); - - for(unsigned idx=it->var.start_pc, - idxlim=it->var.start_pc+it->var.length; - idx!=idxlim; ++idx) - { - assert((!var_map[idx]) && "Local variable table clash?"); - var_map[idx]=&*it; - } - } - - // Now find variables that flow together by walking backwards to find initialisers - // or branches from other live ranges: - - for(auto it=firstvar, itend=varlimit; it!=itend; ++it) - { - // Don't alter parameters: - if(it->var.start_pc==0) - continue; - - // Find the last instruction within the live range: - unsigned end_pc=it->var.start_pc+it->var.length; - auto amapit=amap.find(end_pc); - auto old_amapit=amapit; - --amapit; - if(old_amapit==amap.end()) - assert(end_pc>amapit->first && - "Instruction live range doesn't align to instruction boundary?"); - - // Find vartable entries that flow into this one: - unsigned new_start_pc=it->var.start_pc; - for(; amapit->first >= it->var.start_pc; --amapit) - { - for(auto pred : amapit->second.predecessors) - { - auto pred_var=var_map[pred]; - if(pred_var==&*it) - { - // Flow from within same live range? - continue; - } - else if(!pred_var) - { - // Flow from out of range? - // Check if this is an initialiser, and if so expand the live range - // to include it, but don't check its predecessors: - auto inst_before_this=amapit; - --inst_before_this; - if(amapit->first!=it->var.start_pc || inst_before_this->first!=pred) - throw "Local variable table: unexpected flow from out of range"; - if(!is_store_to_slot(*(inst_before_this->second.source),it->var.index)) - throw "Local variable table: didn't find expected initialising store"; - new_start_pc=pred; - } - else { - if(pred_var->var.name!=it->var.name || pred_var->var.signature!=it->var.signature) - throw "Local variable table: flow from variable with clashing name or signature"; - // OK, this is a flow from a similar but distinct entry in the local var table. - predecessor_map[&*it].insert(pred_var); - } - } - } - - // If a simple pre-block initialiser was found, add it to the live range now: - it->var.length+=(it->var.start_pc-new_start_pc); - it->var.start_pc=new_start_pc; - - } - - // OK, we've established the flows all seem sensible. Now merge vartable entries - // according to the predecessor_map: - - // Top-sort so that we get the bottom variables first: - is_predecessor_of comp(predecessor_map); - std::vector topsorted_vars; - for(auto it=firstvar,itend=varlimit; it!=itend; ++it) - topsorted_vars.push_back(&*it); - - std::sort(topsorted_vars.begin(),topsorted_vars.end(),comp); - - // Now merge the entries: - for(auto merge_into : topsorted_vars) - { - // Already merged into another variable? - if(merge_into->var.length==0) - continue; - - std::set merge_vars; - gather_transitive_predecessors(merge_into,predecessor_map,merge_vars); - if(merge_vars.size()==1) - continue; - - // Because we need a lexically-scoped declaration, we must have the merged variable - // enter scope both in a block that dominates all entries, and which - // precedes them in program order. - unsigned first_pc=var_map.size(); - unsigned last_pc=0; - for(auto v : merge_vars) - { - if(v->var.start_pc < first_pc) - first_pc = v->var.start_pc; - if(v->var.start_pc+v->var.length > last_pc) - last_pc=v->var.start_pc+v->var.length; - } - - std::vector candidate_dominators; - for(auto v : merge_vars) - { - const auto& this_var_doms=doms.cfg[doms.cfg.entry_map.at(v->var.start_pc)].dominators; - for(const auto this_var_dom : this_var_doms) - if(this_var_dom <= first_pc) - candidate_dominators.push_back(this_var_dom); - } - std::sort(candidate_dominators.begin(),candidate_dominators.end()); - - // Working from the back, simply find the first PC that occurs merge_vars.size() - // times and therefore dominates all vars we seek to merge: - - unsigned found_dominator=var_map.size(); - for(auto domit=candidate_dominators.rbegin(), domitend=candidate_dominators.rend(); - domit != domitend && found_dominator==var_map.size(); /* Don't increment here */) - { - unsigned repeats=0; - auto dom=*domit; - while(domit!=domitend && *domit==dom) - { - ++domit; - ++repeats; - } - assert(repeats<=merge_vars.size()); - if(repeats==merge_vars.size()) - found_dominator=dom; - } - - if(found_dominator==var_map.size()) - throw "Variable live ranges with no common dominator?"; - - // Populate the holes in the live range (addresses where the new variable - // will be in scope, but references to this stack slot should not resolve to it - // as it was not visible in the original local variable table) - std::vector sorted_by_startpc( - merge_vars.begin(),merge_vars.end()); - std::sort(sorted_by_startpc.begin(),sorted_by_startpc.end(),lt_startpc); - - maybe_add_hole(*merge_into,found_dominator,sorted_by_startpc[0]->var.start_pc); - for(unsigned idx=0; idxvar.start_pc + sorted_by_startpc[idx]->var.length, - sorted_by_startpc[idx+1]->var.start_pc); - - // Apply the changes: - merge_into->var.start_pc=found_dominator; - merge_into->var.length=last_pc-found_dominator; - - #ifdef DEBUG - status() << "Merging " << merge_vars.size() << " variables named " << merge_into->var.name << - "; new live range " << merge_into->var.start_pc << "-" << - merge_into->var.start_pc + merge_into->var.length << eom; - #endif - - // Nuke the now-subsumed var-table entries: - for(auto& v : merge_vars) - if(v!=merge_into) - v->var.length=0; - - } - -} - -static void walk_to_next_index( - local_variable_table_with_holest::iterator& it1, - local_variable_table_with_holest::iterator& it2, - local_variable_table_with_holest::iterator itend) -{ - if(it2==itend) - { - it1=itend; - return; - } - - auto old_it2=it2; - auto index=it2->var.index; - while(it2!=itend && it2->var.index==index) - ++it2; - it1=old_it2; -} - -void java_bytecode_convert_methodt::find_initialisers( - local_variable_table_with_holest& vars, - const address_mapt& amap, - const java_cfg_dominatorst& doms) -{ - // Handle one stack slot at a time: - std::sort(vars.begin(),vars.end(),lt_index); - - auto it1=vars.begin(); - auto it2=it1; - auto itend=vars.end(); - walk_to_next_index(it1,it2,itend); - for(; it1!=itend; walk_to_next_index(it1,it2,itend)) - find_initialisers_for_slot(it1,it2,amap,doms); -} - -void java_bytecode_convert_methodt::setup_local_variables(const methodt& m, - const address_mapt& amap) -{ - // Compute CFG dominator tree - java_cfg_dominatorst doms; - doms(amap); - - // Find out which local variable table entries should be merged: - // Wrap each entry so we have somewhere to record live ranges with holes: - std::vector vars_with_holes; - for(const auto& v : m.local_variable_table) - vars_with_holes.push_back({v, {}}); - - find_initialisers(vars_with_holes,amap,doms); - - // Clean up removed records from the variable table: - - size_t toremove=0; - for(size_t i=0; i<(vars_with_holes.size()-toremove); ++i) - { - auto& v=vars_with_holes[i]; - if(v.var.length==0) - { - // Move to end; consider the new element we've swapped in: - ++toremove; - if(i!=vars_with_holes.size()-toremove) // Already where it needs to be? - std::swap(v,vars_with_holes[vars_with_holes.size()-toremove]); - --i; - } - } - - // Remove un-needed entries. - vars_with_holes.resize(vars_with_holes.size()-toremove); - - // Do the locals and parameters in the variable table, which is available when - // compiled with -g or for methods with many local variables in the latter - // case, different variables can have the same index, depending on the - // context. - // - // to calculate which variable to use, one uses the address of the instruction - // that uses the variable, the size of the instruction and the start_pc / - // length values in the local variable table - for(const auto & v : vars_with_holes) - { - if(v.var.start_pc==0) // Parameter? - continue; - - typet t=java_type_from_string(v.var.signature); - std::ostringstream id_oss; - id_oss << method_id << "::" << v.var.start_pc << "::" << v.var.name; - irep_idt identifier(id_oss.str()); - symbol_exprt result(identifier, t); - result.set(ID_C_base_name, v.var.name); - - variables[v.var.index].push_back(variablet()); - auto& newv=variables[v.var.index].back(); - newv.symbol_expr = result; - newv.start_pc = v.var.start_pc; - newv.length = v.var.length; - newv.holes=std::move(v.holes); - - symbolt new_symbol; - new_symbol.name=identifier; - new_symbol.type=t; - new_symbol.base_name=v.var.name; - new_symbol.pretty_name=id2string(identifier).substr(6, std::string::npos); - new_symbol.mode=ID_java; - new_symbol.is_type=false; - new_symbol.is_file_local=true; - new_symbol.is_thread_local=true; - new_symbol.is_lvalue=true; - symbol_table.add(new_symbol); - } - -} - /*******************************************************************\ Function: java_bytecode_convert_methodt::get_bytecode_info diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h new file mode 100644 index 00000000000..643b913a71a --- /dev/null +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -0,0 +1,182 @@ + +#ifndef JBCM_CLASS_H +#define JBCM_CLASS_H + +#include +#include +#include +#include +#include +#include "java_bytecode_parse_tree.h" + +#include +#include + +class symbol_tablet; +class symbolt; + +class java_bytecode_convert_methodt:public messaget +{ +public: + java_bytecode_convert_methodt( + symbol_tablet &_symbol_table, + message_handlert &_message_handler); + + typedef java_bytecode_parse_treet::methodt methodt; + typedef java_bytecode_parse_treet::instructiont instructiont; + typedef methodt::instructionst instructionst; + typedef methodt::local_variable_tablet local_variable_tablet; + typedef methodt::local_variablet local_variablet; + + void operator()(const symbolt &class_symbol, const methodt &method) + { + convert(class_symbol, method); + } + +protected: + irep_idt method_id; + symbol_tablet &symbol_table; + + irep_idt current_method; + typet method_return_type; + +public: + struct holet { + unsigned start_pc; + unsigned length; + }; + + struct local_variable_with_holest + { + local_variablet var; + std::vector holes; + }; + + typedef std::vector local_variable_table_with_holest; + +protected: + class variablet + { + public: + symbol_exprt symbol_expr; + size_t start_pc; + size_t length; + bool is_parameter; + std::vector holes; + variablet() : symbol_expr(), is_parameter(false) {} + }; + + typedef std::vector variablest; + expanding_vector variables; + std::set used_local_names; + bool method_has_this; + + // return corresponding reference of variable + const variablet &find_variable_for_slot(size_t address, variablest &var_list); + + // JVM local variables + enum variable_cast_argumentt + { + CAST_AS_NEEDED, + NO_CAST + }; + + const exprt variable( + const exprt &arg, + char type_char, + size_t address, + variable_cast_argumentt do_cast); + + // temporary variables + std::list tmp_vars; + + symbol_exprt tmp_variable(const std::string &prefix, const typet &type); + + // JVM program locations + irep_idt label(const irep_idt &address); + + // JVM Stack + typedef std::vector stackt; + stackt stack; + + exprt::operandst pop(std::size_t n); + + void push(const exprt::operandst &o); + + struct converted_instructiont + { + converted_instructiont( + const instructionst::const_iterator &it, + const codet &_code):source(it), code(_code), done(false) + {} + + instructionst::const_iterator source; + std::list successors; + std::set predecessors; + codet code; + stackt stack; + bool done; + }; + +public: + typedef std::map address_mapt; + typedef cfg_dominators_templatet java_cfg_dominatorst; + +protected: + + void find_initialisers( + local_variable_table_with_holest& vars, + const address_mapt& amap, + const java_cfg_dominatorst& doms); + + void find_initialisers_for_slot( + local_variable_table_with_holest::iterator firstvar, + local_variable_table_with_holest::iterator varlimit, + const address_mapt& amap, + const java_cfg_dominatorst& doms); + + void setup_local_variables(const methodt& m, const address_mapt& amap); + + struct block_tree_nodet + { + bool leaf; + std::vector branch_addresses; + std::vector branch; + block_tree_nodet():leaf(false) {} + explicit block_tree_nodet(bool l):leaf(l) {} + static block_tree_nodet get_leaf() { return block_tree_nodet(true); } + }; + + static void replace_goto_target( + codet &repl, + const irep_idt &old_label, + const irep_idt &new_label); + + code_blockt &get_block_for_pcrange( + block_tree_nodet &tree, + code_blockt &this_block, + unsigned address_start, + unsigned address_limit, + unsigned next_block_start_address); + + code_blockt &get_or_create_block_for_pcrange( + block_tree_nodet &tree, + code_blockt &this_block, + unsigned address_start, + unsigned address_limit, + unsigned next_block_start_address, + const address_mapt &amap, + bool allow_merge=true); + + // conversion + void convert(const symbolt &class_symbol, const methodt &); + void convert(const instructiont &); + + codet convert_instructions( + const methodt &, + const code_typet &); + + const bytecode_infot &get_bytecode_info(const irep_idt &statement); +}; + +#endif diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp new file mode 100644 index 00000000000..6145a723f39 --- /dev/null +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -0,0 +1,514 @@ + +#include "java_bytecode_convert_method_class.h" + +#include +#include "java_types.h" + +#include + +// Specialise the CFG representation to work over Java instead of GOTO programs. +// This must be done at global scope due to template resolution rules. + +template +struct procedure_local_cfg_baset : + public graph > +{ + typedef java_bytecode_convert_methodt::address_mapt address_mapt; + typedef std::map entry_mapt; + entry_mapt entry_map; + + procedure_local_cfg_baset() {} + + void operator()(const address_mapt& amap) + { + for(const auto& inst : amap) + { + // Map instruction PCs onto node indices: + entry_map[inst.first]=this->add_node(); + // Map back: + (*this)[entry_map[inst.first]].PC=inst.first; + } + for(const auto& inst : amap) + { + for(auto succ : inst.second.successors) + this->add_edge(entry_map.at(inst.first),entry_map.at(succ)); + } + } + + unsigned get_first_node(const address_mapt& amap) const { return amap.begin()->first; } + unsigned get_last_node(const address_mapt& amap) const { return (--amap.end())->first; } + unsigned nodes_empty(const address_mapt& amap) const { return amap.empty(); } + +}; + +namespace { + +typedef java_bytecode_convert_methodt::holet holet; +typedef java_bytecode_convert_methodt::local_variable_with_holest local_variable_with_holest; +typedef java_bytecode_convert_methodt::local_variable_table_with_holest local_variable_table_with_holest; +typedef java_bytecode_convert_methodt::address_mapt address_mapt; +typedef java_bytecode_convert_methodt::java_cfg_dominatorst java_cfg_dominatorst; + +// Comparators for local variables: + +static bool lt_index(const local_variable_with_holest& a, + const local_variable_with_holest& b) +{ + return a.var.indexvar.start_pcvar.start_pc; +} + +// The predecessor map, and a top-sorting comparator: + +typedef std::map > predecessor_mapt; + +struct is_predecessor_of +{ + const predecessor_mapt& order; + + is_predecessor_of(const predecessor_mapt& _order) : order(_order) {} + + bool operator()(local_variable_with_holest* a, + local_variable_with_holest* b) const + { + auto findit=order.find(a); + if(findit==order.end()) + return false; + return findit->second.count(b)>0; + } +}; + +// Helper routines for the find-initialisers code below: + +static void gather_transitive_predecessors( + local_variable_with_holest* start, + const predecessor_mapt& predecessor_map, + std::set& result) +{ + if(!result.insert(start).second) + return; + auto findit=predecessor_map.find(start); + if(findit==predecessor_map.end()) + return; + for(const auto pred : findit->second) + gather_transitive_predecessors(pred,predecessor_map,result); +} + +static bool is_store_to_slot( + const java_bytecode_convert_methodt::instructiont& inst, + unsigned slotidx) +{ + const std::string prevstatement=id2string(inst.statement); + if(!(prevstatement.size()>=1 && prevstatement.substr(1,5)=="store")) + return false; + + std::string storeslot; + if(inst.args.size()==1) + { + const auto& arg=inst.args[0]; + storeslot=id2string(to_constant_expr(arg).get_value()); + } + else + { + assert(prevstatement[6]=='_' && prevstatement.size()==8); + storeslot=prevstatement[7]; + assert(isdigit(storeslot[0])); + } + auto storeslotidx=safe_string2unsigned(storeslot); + return storeslotidx==slotidx; +} + +static void maybe_add_hole( + local_variable_with_holest& var, + unsigned from, + unsigned to) +{ + assert(to>=from); + if(to!=from) + var.holes.push_back({from,to-from}); +} + +static void populate_variable_address_map( + local_variable_table_with_holest::iterator firstvar, + local_variable_table_with_holest::iterator varlimit, + std::vector& live_variable_at_address) +{ + for(auto it=firstvar, itend=varlimit; it!=itend; ++it) + { + if(it->var.start_pc+it->var.length > live_variable_at_address.size()) + live_variable_at_address.resize(it->var.start_pc+it->var.length); + + for(unsigned idx=it->var.start_pc, + idxlim=it->var.start_pc+it->var.length; + idx!=idxlim; ++idx) + { + assert((!live_variable_at_address[idx]) && "Local variable table clash?"); + live_variable_at_address[idx]=&*it; + } + } + +} + +static void populate_predecessor_map( + local_variable_table_with_holest::iterator firstvar, + local_variable_table_with_holest::iterator varlimit, + const std::vector& live_variable_at_address, + const address_mapt& amap, + predecessor_mapt& predecessor_map) +{ + + for(auto it=firstvar, itend=varlimit; it!=itend; ++it) + { + // Parameters are irrelevant to us and shouldn't be changed: + if(it->var.start_pc==0) + continue; + + // Find the last instruction within the live range: + unsigned end_pc=it->var.start_pc+it->var.length; + auto amapit=amap.find(end_pc); + auto old_amapit=amapit; + --amapit; + if(old_amapit==amap.end()) + assert(end_pc>amapit->first && + "Instruction live range doesn't align to instruction boundary?"); + + // Find vartable entries that flow into this one: + unsigned new_start_pc=it->var.start_pc; + for(; amapit->first >= it->var.start_pc; --amapit) + { + for(auto pred : amapit->second.predecessors) + { + auto pred_var=live_variable_at_address[pred]; + if(pred_var==&*it) + { + // Flow from within same live range? + continue; + } + else if(!pred_var) + { + // Flow from out of range? + // Check if this is an initialiser, and if so expand the live range + // to include it, but don't check its predecessors: + auto inst_before_this=amapit; + --inst_before_this; + if(amapit->first!=it->var.start_pc || inst_before_this->first!=pred) + throw "Local variable table: unexpected flow from out of range"; + if(!is_store_to_slot(*(inst_before_this->second.source),it->var.index)) + throw "Local variable table: didn't find expected initialising store"; + new_start_pc=pred; + } + else { + if(pred_var->var.name!=it->var.name || pred_var->var.signature!=it->var.signature) + throw "Local variable table: flow from variable with clashing name or signature"; + // OK, this is a flow from a similar but distinct entry in the local var table. + predecessor_map[&*it].insert(pred_var); + } + } + } + + // If a simple pre-block initialiser was found, add it to the live range now: + it->var.length+=(it->var.start_pc-new_start_pc); + it->var.start_pc=new_start_pc; + + } + +} + +static unsigned get_common_dominator( + const std::set& merge_vars, + const java_cfg_dominatorst& dominator_analysis) +{ + assert(merge_vars.size()!=0); + + unsigned first_pc=UINT_MAX; + for(auto v : merge_vars) + { + if(v->var.start_pc < first_pc) + first_pc = v->var.start_pc; + } + + std::vector candidate_dominators; + for(auto v : merge_vars) + { + const auto& dominator_nodeidx=dominator_analysis.cfg.entry_map.at(v->var.start_pc); + const auto& this_var_doms=dominator_analysis.cfg[dominator_nodeidx].dominators; + for(const auto this_var_dom : this_var_doms) + if(this_var_dom <= first_pc) + candidate_dominators.push_back(this_var_dom); + } + std::sort(candidate_dominators.begin(),candidate_dominators.end()); + + // Working from the back, simply find the first PC that occurs merge_vars.size() + // times and therefore dominates all vars we seek to merge: + for(auto domit=candidate_dominators.rbegin(), domitend=candidate_dominators.rend(); + domit != domitend; /* Don't increment here */) + { + unsigned repeats=0; + auto dom=*domit; + while(domit!=domitend && *domit==dom) + { + ++domit; + ++repeats; + } + assert(repeats<=merge_vars.size()); + if(repeats==merge_vars.size()) + return dom; + } + + throw "Variable live ranges with no common dominator?"; +} + +static void populate_live_range_holes( + local_variable_with_holest& merge_into, + const std::set& merge_vars, + unsigned expanded_live_range_start) +{ + std::vector sorted_by_startpc( + merge_vars.begin(),merge_vars.end()); + std::sort(sorted_by_startpc.begin(),sorted_by_startpc.end(),lt_startpc); + + maybe_add_hole(merge_into,expanded_live_range_start,sorted_by_startpc[0]->var.start_pc); + for(unsigned idx=0; idxvar.start_pc + sorted_by_startpc[idx]->var.length, + sorted_by_startpc[idx+1]->var.start_pc); +} + +static void merge_variable_table_entries( + local_variable_with_holest& merge_into, + const std::set& merge_vars, + const java_cfg_dominatorst& dominator_analysis, + std::ostream& debug_out) +{ + // Because we need a lexically-scoped declaration, we must have the merged variable + // enter scope both in a block that dominates all entries, and which + // precedes them in program order. + unsigned found_dominator= + get_common_dominator(merge_vars,dominator_analysis); + + // Populate the holes in the live range (addresses where the new variable + // will be in scope, but references to this stack slot should not resolve to it + // as it was not visible in the original local variable table) + populate_live_range_holes(merge_into,merge_vars,found_dominator); + + unsigned last_pc=0; + for(auto v : merge_vars) + if(v->var.start_pc+v->var.length > last_pc) + last_pc=v->var.start_pc+v->var.length; + + // Apply the changes: + merge_into.var.start_pc=found_dominator; + merge_into.var.length=last_pc-found_dominator; + +#ifdef DEBUG + debug_out << "Merged " << merge_vars.size() << " variables named " << merge_into.var.name << + "; new live range " << merge_into.var.start_pc << "-" << + merge_into.var.start_pc + merge_into.var.length << messaget::eom; +#endif + + // Nuke the now-subsumed var-table entries: + for(auto& v : merge_vars) + if(v!=&merge_into) + v->var.length=0; +} + +} // End anonymous namespace + +void java_bytecode_convert_methodt::find_initialisers_for_slot( + local_variable_table_with_holest::iterator firstvar, + local_variable_table_with_holest::iterator varlimit, + const address_mapt& amap, + const java_cfg_dominatorst& dominator_analysis) +{ + // Build a simple map from instruction PC to the variable live in this slot at that PC, + // and a map from each variable to variables that flow into it: + std::vector live_variable_at_address; + populate_variable_address_map(firstvar,varlimit,live_variable_at_address); + + // Now find variables that flow together by walking backwards to find initialisers + // or branches from other live ranges: + predecessor_mapt predecessor_map; + populate_predecessor_map(firstvar,varlimit,live_variable_at_address,amap,predecessor_map); + + // OK, we've established the flows all seem sensible. Now merge vartable entries + // according to the predecessor_map: + + // Top-sort so that we get the bottom variables first: + is_predecessor_of comp(predecessor_map); + std::vector topsorted_vars; + for(auto it=firstvar,itend=varlimit; it!=itend; ++it) + topsorted_vars.push_back(&*it); + + std::sort(topsorted_vars.begin(),topsorted_vars.end(),comp); + + // Now merge the entries: + for(auto merge_into : topsorted_vars) + { + // Already merged into another variable? + if(merge_into->var.length==0) + continue; + + std::set merge_vars; + gather_transitive_predecessors(merge_into,predecessor_map,merge_vars); + // Nothing to do? + if(merge_vars.size()==1) + continue; + + merge_variable_table_entries(*merge_into,merge_vars,dominator_analysis,status()); + } + +} + +static void walk_to_next_index( + local_variable_table_with_holest::iterator& it1, + local_variable_table_with_holest::iterator& it2, + local_variable_table_with_holest::iterator itend) +{ + if(it2==itend) + { + it1=itend; + return; + } + + auto old_it2=it2; + auto index=it2->var.index; + while(it2!=itend && it2->var.index==index) + ++it2; + it1=old_it2; +} + +void java_bytecode_convert_methodt::find_initialisers( + local_variable_table_with_holest& vars, + const address_mapt& amap, + const java_cfg_dominatorst& dominator_analysis) +{ + // Handle one stack slot at a time: + std::sort(vars.begin(),vars.end(),lt_index); + + auto it1=vars.begin(); + auto it2=it1; + auto itend=vars.end(); + walk_to_next_index(it1,it2,itend); + for(; it1!=itend; walk_to_next_index(it1,it2,itend)) + find_initialisers_for_slot(it1,it2,amap,dominator_analysis); +} + +static void cleanup_var_table(std::vector& vars_with_holes) +{ + size_t toremove=0; + for(size_t i=0; i<(vars_with_holes.size()-toremove); ++i) + { + auto& v=vars_with_holes[i]; + if(v.var.length==0) + { + // Move to end; consider the new element we've swapped in: + ++toremove; + if(i!=vars_with_holes.size()-toremove) // Already where it needs to be? + std::swap(v,vars_with_holes[vars_with_holes.size()-toremove]); + --i; + } + } + + // Remove un-needed entries. + vars_with_holes.resize(vars_with_holes.size()-toremove); +} + +void java_bytecode_convert_methodt::setup_local_variables(const methodt& m, + const address_mapt& amap) +{ + // Compute CFG dominator tree + java_cfg_dominatorst dominator_analysis; + dominator_analysis(amap); + + // Find out which local variable table entries should be merged: + // Wrap each entry so we have somewhere to record live ranges with holes: + std::vector vars_with_holes; + for(const auto& v : m.local_variable_table) + vars_with_holes.push_back({v, {}}); + + // Merge variable records: + find_initialisers(vars_with_holes,amap,dominator_analysis); + + // Clean up removed records from the variable table: + cleanup_var_table(vars_with_holes); + + // Do the locals and parameters in the variable table, which is available when + // compiled with -g or for methods with many local variables in the latter + // case, different variables can have the same index, depending on the + // context. + // + // to calculate which variable to use, one uses the address of the instruction + // that uses the variable, the size of the instruction and the start_pc / + // length values in the local variable table + for(const auto & v : vars_with_holes) + { + if(v.var.start_pc==0) // Parameter? + continue; + + typet t=java_type_from_string(v.var.signature); + std::ostringstream id_oss; + id_oss << method_id << "::" << v.var.start_pc << "::" << v.var.name; + irep_idt identifier(id_oss.str()); + symbol_exprt result(identifier, t); + result.set(ID_C_base_name, v.var.name); + + variables[v.var.index].push_back(variablet()); + auto& newv=variables[v.var.index].back(); + newv.symbol_expr = result; + newv.start_pc = v.var.start_pc; + newv.length = v.var.length; + newv.holes=std::move(v.holes); + + symbolt new_symbol; + new_symbol.name=identifier; + new_symbol.type=t; + new_symbol.base_name=v.var.name; + new_symbol.pretty_name=id2string(identifier).substr(6, std::string::npos); + new_symbol.mode=ID_java; + new_symbol.is_type=false; + new_symbol.is_file_local=true; + new_symbol.is_thread_local=true; + new_symbol.is_lvalue=true; + symbol_table.add(new_symbol); + } + +} + +const java_bytecode_convert_methodt::variablet & +java_bytecode_convert_methodt::find_variable_for_slot( + size_t address, + variablest &var_list) +{ + for(const variablet &var : var_list) + { + size_t start_pc = var.start_pc; + size_t length = var.length; + if (address>=start_pc && address<(start_pc+length)) + { + bool found_hole=false; + for(auto &hole : var.holes) + if(address>=hole.start_pc && address<(hole.start_pc-hole.length)) + { + found_hole=true; + break; + } + if(found_hole) + continue; + return var; + } + } + // add unnamed local variable to end of list at this index + // with scope from 0 to INT_MAX + // as it is at the end of the vector, it will only be taken into account + // if no other variable is valid + size_t list_length = var_list.size(); + var_list.resize(list_length+1); + var_list[list_length].start_pc=0; + var_list[list_length].length=std::numeric_limits::max(); + return var_list[list_length]; +} From 0610bae17cf3a75be80da6479aaca57ca4ddadd8 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 26 Oct 2016 17:29:15 +0100 Subject: [PATCH 009/166] Use a total order when top-sorting variables --- .../java_local_variable_table.cpp | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index 6145a723f39..430593bef26 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -5,6 +5,7 @@ #include "java_types.h" #include +#include // Specialise the CFG representation to work over Java instead of GOTO programs. // This must be done at global scope due to template resolution rules. @@ -159,9 +160,10 @@ static void populate_predecessor_map( local_variable_table_with_holest::iterator varlimit, const std::vector& live_variable_at_address, const address_mapt& amap, - predecessor_mapt& predecessor_map) + predecessor_mapt& predecessor_map, + message_handlert& msg_handler) { - + messaget msg(msg_handler); for(auto it=firstvar, itend=varlimit; it!=itend; ++it) { // Parameters are irrelevant to us and shouldn't be changed: @@ -197,7 +199,11 @@ static void populate_predecessor_map( auto inst_before_this=amapit; --inst_before_this; if(amapit->first!=it->var.start_pc || inst_before_this->first!=pred) - throw "Local variable table: unexpected flow from out of range"; + { + msg.warning() << "Local variable table: ignoring flow from out of range for " << + it->var.name << " " << pred << " -> " << amapit->first << "\n"; + continue; + } if(!is_store_to_slot(*(inst_before_this->second.source),it->var.index)) throw "Local variable table: didn't find expected initialising store"; new_start_pc=pred; @@ -333,11 +339,25 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( // Now find variables that flow together by walking backwards to find initialisers // or branches from other live ranges: predecessor_mapt predecessor_map; - populate_predecessor_map(firstvar,varlimit,live_variable_at_address,amap,predecessor_map); + populate_predecessor_map( + firstvar, + varlimit, + live_variable_at_address, + amap, + predecessor_map, + get_message_handler()); // OK, we've established the flows all seem sensible. Now merge vartable entries // according to the predecessor_map: + // Take the transitive closure of the predecessor map: + for(auto& kv : predecessor_map) + { + std::set closed_preds; + gather_transitive_predecessors(kv.first,predecessor_map,closed_preds); + kv.second=std::move(closed_preds); + } + // Top-sort so that we get the bottom variables first: is_predecessor_of comp(predecessor_map); std::vector topsorted_vars; @@ -353,12 +373,14 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( if(merge_into->var.length==0) continue; - std::set merge_vars; - gather_transitive_predecessors(merge_into,predecessor_map,merge_vars); + auto findit=predecessor_map.find(merge_into); // Nothing to do? - if(merge_vars.size()==1) + if(findit==predecessor_map.end()) continue; + const auto& merge_vars=findit->second; + assert(merge_vars.size()>=2); + merge_variable_table_entries(*merge_into,merge_vars,dominator_analysis,status()); } From 5f740c651ebbfbd1f1154dd04479b86c36d7bb35 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 1 Dec 2016 16:12:30 +0000 Subject: [PATCH 010/166] Local variable table: tolerate impossible flows Flows from out of range or from a clashing variable declaration can happen because jsr / ret control flow is imprecisely modelled, so control flow edges are present which are in practice infeasible, hence the compiler generating code which naively appears to change a stack slot's name or type without re-initialising it. Consequently, demote these to warnings, and perhaps in the future do proper control-flow analysis to determine which callsites can really reach which jsr subroutines. --- src/java_bytecode/java_local_variable_table.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index 430593bef26..b1ac6ed1a66 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -185,7 +185,7 @@ static void populate_predecessor_map( { for(auto pred : amapit->second.predecessors) { - auto pred_var=live_variable_at_address[pred]; + auto pred_var=(pred < live_variable_at_address.size() ? live_variable_at_address[pred] : 0); if(pred_var==&*it) { // Flow from within same live range? @@ -200,8 +200,10 @@ static void populate_predecessor_map( --inst_before_this; if(amapit->first!=it->var.start_pc || inst_before_this->first!=pred) { + // These sorts of infeasible edges can occur because jsr handling is presently vague + // (any subroutine is assumed to be able to return to any callsite) msg.warning() << "Local variable table: ignoring flow from out of range for " << - it->var.name << " " << pred << " -> " << amapit->first << "\n"; + it->var.name << " " << pred << " -> " << amapit->first << messaget::eom; continue; } if(!is_store_to_slot(*(inst_before_this->second.source),it->var.index)) @@ -210,7 +212,13 @@ static void populate_predecessor_map( } else { if(pred_var->var.name!=it->var.name || pred_var->var.signature!=it->var.signature) - throw "Local variable table: flow from variable with clashing name or signature"; + { + // These sorts of infeasible edges can occur because jsr handling is presently vague + // (any subroutine is assumed to be able to return to any callsite) + msg.warning() << "Local variable table: ignoring flow from clashing variable for " << + it->var.name << " " << pred << " -> " << amapit->first << messaget::eom; + continue; + } // OK, this is a flow from a similar but distinct entry in the local var table. predecessor_map[&*it].insert(pred_var); } From 923b7abf0b3b64e387696b26f94aa39be95c4438 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 5 Dec 2016 16:58:01 +0000 Subject: [PATCH 011/166] Fix hole-in-variable-live-range test --- src/java_bytecode/java_local_variable_table.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index b1ac6ed1a66..92f4941c915 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -522,7 +522,7 @@ java_bytecode_convert_methodt::find_variable_for_slot( { bool found_hole=false; for(auto &hole : var.holes) - if(address>=hole.start_pc && address<(hole.start_pc-hole.length)) + if(address>=hole.start_pc && address<(hole.start_pc+hole.length)) { found_hole=true; break; From 41d2b27875455e4c054bc4aca6adfe74f92457a5 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 19 Jan 2017 11:32:18 +0000 Subject: [PATCH 012/166] Style fixes --- .../java_bytecode_convert_method.cpp | 12 +- .../java_bytecode_convert_method_class.h | 21 +- .../java_local_variable_table.cpp | 284 +++++++++++------- 3 files changed, 196 insertions(+), 121 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 2ad56bc9230..854d50ac9ba 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -82,7 +82,8 @@ static void cast_if_necessary(binary_relation_exprt &condition) exprt &lhs(condition.lhs()); exprt &rhs(condition.rhs()); const typet &lhs_type(lhs.type()); - if(lhs_type==rhs.type()) return; + if(lhs_type==rhs.type()) + return; rhs=typecast_exprt(rhs, lhs_type); } @@ -137,7 +138,8 @@ const exprt java_bytecode_convert_methodt::variable( } symbol_exprt java_bytecode_convert_methodt::tmp_variable( - const std::string &prefix, const typet &type) + const std::string &prefix, + const typet &type) { irep_idt base_name=prefix+"_tmp"+std::to_string(tmp_vars.size()); irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); @@ -245,9 +247,9 @@ void java_bytecode_convert_methodt::convert( variables[v.index].push_back(variablet()); auto &newv=variables[v.index].back(); - newv.symbol_expr = result; - newv.start_pc = v.start_pc; - newv.length = v.length; + newv.symbol_expr=result; + newv.start_pc=v.start_pc; + newv.length=v.length; } // set up variables array diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index 643b913a71a..8a456d0a99a 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -1,6 +1,13 @@ +/*******************************************************************\ -#ifndef JBCM_CLASS_H -#define JBCM_CLASS_H +Module: JAVA Bytecode Language Conversion + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + +#ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_METHOD_CLASS_H +#define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_METHOD_CLASS_H #include #include @@ -41,7 +48,8 @@ class java_bytecode_convert_methodt:public messaget typet method_return_type; public: - struct holet { + struct holet + { unsigned start_pc; unsigned length; }; @@ -52,7 +60,8 @@ class java_bytecode_convert_methodt:public messaget std::vector holes; }; - typedef std::vector local_variable_table_with_holest; + typedef std::vector + local_variable_table_with_holest; protected: class variablet @@ -120,10 +129,10 @@ class java_bytecode_convert_methodt:public messaget public: typedef std::map address_mapt; - typedef cfg_dominators_templatet java_cfg_dominatorst; + typedef cfg_dominators_templatet + java_cfg_dominatorst; protected: - void find_initialisers( local_variable_table_with_holest& vars, const address_mapt& amap, diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index 92f4941c915..fa566318d24 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -1,8 +1,15 @@ +/*******************************************************************\ + +Module: Java local variable table processing + +Author: Chris Smowton, chris.smowton@diffblue.com + +\*******************************************************************/ #include "java_bytecode_convert_method_class.h" +#include "java_types.h" #include -#include "java_types.h" #include #include @@ -11,8 +18,11 @@ // This must be done at global scope due to template resolution rules. template -struct procedure_local_cfg_baset : - public graph > +struct procedure_local_cfg_baset< + T, + const java_bytecode_convert_methodt::address_mapt, + unsigned> : + public graph > { typedef java_bytecode_convert_methodt::address_mapt address_mapt; typedef std::map entry_mapt; @@ -32,50 +42,66 @@ struct procedure_local_cfg_basetadd_edge(entry_map.at(inst.first),entry_map.at(succ)); + this->add_edge(entry_map.at(inst.first), entry_map.at(succ)); } } - unsigned get_first_node(const address_mapt& amap) const { return amap.begin()->first; } - unsigned get_last_node(const address_mapt& amap) const { return (--amap.end())->first; } - unsigned nodes_empty(const address_mapt& amap) const { return amap.empty(); } - + unsigned get_first_node(const address_mapt& amap) const + { + return amap.begin()->first; + } + unsigned get_last_node(const address_mapt& amap) const + { + return (--amap.end())->first; + } + unsigned nodes_empty(const address_mapt& amap) const + { + return amap.empty(); + } }; -namespace { - -typedef java_bytecode_convert_methodt::holet holet; -typedef java_bytecode_convert_methodt::local_variable_with_holest local_variable_with_holest; -typedef java_bytecode_convert_methodt::local_variable_table_with_holest local_variable_table_with_holest; -typedef java_bytecode_convert_methodt::address_mapt address_mapt; -typedef java_bytecode_convert_methodt::java_cfg_dominatorst java_cfg_dominatorst; +typedef java_bytecode_convert_methodt::holet + holet; +typedef java_bytecode_convert_methodt::local_variable_with_holest + local_variable_with_holest; +typedef java_bytecode_convert_methodt::local_variable_table_with_holest + local_variable_table_with_holest; +typedef java_bytecode_convert_methodt::address_mapt + address_mapt; +typedef java_bytecode_convert_methodt::java_cfg_dominatorst + java_cfg_dominatorst; // Comparators for local variables: -static bool lt_index(const local_variable_with_holest& a, - const local_variable_with_holest& b) +static bool lt_index( + const local_variable_with_holest& a, + const local_variable_with_holest& b) { return a.var.indexvar.start_pcvar.start_pc; } // The predecessor map, and a top-sorting comparator: -typedef std::map > predecessor_mapt; +typedef std::map< + local_variable_with_holest*, + std::set > + predecessor_mapt; -struct is_predecessor_of +struct is_predecessor_oft { const predecessor_mapt& order; - is_predecessor_of(const predecessor_mapt& _order) : order(_order) {} + explicit is_predecessor_oft(const predecessor_mapt& _order) : order(_order) {} - bool operator()(local_variable_with_holest* a, - local_variable_with_holest* b) const + bool operator()( + local_variable_with_holest* a, + local_variable_with_holest* b) const { auto findit=order.find(a); if(findit==order.end()) @@ -97,7 +123,7 @@ static void gather_transitive_predecessors( if(findit==predecessor_map.end()) return; for(const auto pred : findit->second) - gather_transitive_predecessors(pred,predecessor_map,result); + gather_transitive_predecessors(pred, predecessor_map, result); } static bool is_store_to_slot( @@ -105,7 +131,7 @@ static bool is_store_to_slot( unsigned slotidx) { const std::string prevstatement=id2string(inst.statement); - if(!(prevstatement.size()>=1 && prevstatement.substr(1,5)=="store")) + if(!(prevstatement.size()>=1 && prevstatement.substr(1, 5)=="store")) return false; std::string storeslot; @@ -131,7 +157,7 @@ static void maybe_add_hole( { assert(to>=from); if(to!=from) - var.holes.push_back({from,to-from}); + var.holes.push_back({from, to-from}); } static void populate_variable_address_map( @@ -141,7 +167,7 @@ static void populate_variable_address_map( { for(auto it=firstvar, itend=varlimit; it!=itend; ++it) { - if(it->var.start_pc+it->var.length > live_variable_at_address.size()) + if(it->var.start_pc+it->var.length>live_variable_at_address.size()) live_variable_at_address.resize(it->var.start_pc+it->var.length); for(unsigned idx=it->var.start_pc, @@ -152,7 +178,6 @@ static void populate_variable_address_map( live_variable_at_address[idx]=&*it; } } - } static void populate_predecessor_map( @@ -176,16 +201,22 @@ static void populate_predecessor_map( auto old_amapit=amapit; --amapit; if(old_amapit==amap.end()) - assert(end_pc>amapit->first && - "Instruction live range doesn't align to instruction boundary?"); + { + assert( + end_pc>amapit->first && + "Instruction live range doesn't align to instruction boundary?"); + } // Find vartable entries that flow into this one: unsigned new_start_pc=it->var.start_pc; - for(; amapit->first >= it->var.start_pc; --amapit) + for(; amapit->first>=it->var.start_pc; --amapit) { for(auto pred : amapit->second.predecessors) { - auto pred_var=(pred < live_variable_at_address.size() ? live_variable_at_address[pred] : 0); + auto pred_var= + (predfirst!=it->var.start_pc || inst_before_this->first!=pred) { - // These sorts of infeasible edges can occur because jsr handling is presently vague - // (any subroutine is assumed to be able to return to any callsite) - msg.warning() << "Local variable table: ignoring flow from out of range for " << - it->var.name << " " << pred << " -> " << amapit->first << messaget::eom; + // These sorts of infeasible edges can occur because jsr + // handling is presently vague (any subroutine is assumed to + // be able to return to any callsite) + msg.warning() << "Local variable table: ignoring flow from " + << "out of range for " << it->var.name << " " + << pred << " -> " << amapit->first + << messaget::eom; continue; } - if(!is_store_to_slot(*(inst_before_this->second.source),it->var.index)) - throw "Local variable table: didn't find expected initialising store"; + if(!is_store_to_slot( + *(inst_before_this->second.source), + it->var.index)) + { + throw "local variable table: didn't find initialising store"; + } new_start_pc=pred; } - else { - if(pred_var->var.name!=it->var.name || pred_var->var.signature!=it->var.signature) + else + { + if(pred_var->var.name!=it->var.name || + pred_var->var.signature!=it->var.signature) { - // These sorts of infeasible edges can occur because jsr handling is presently vague - // (any subroutine is assumed to be able to return to any callsite) - msg.warning() << "Local variable table: ignoring flow from clashing variable for " << - it->var.name << " " << pred << " -> " << amapit->first << messaget::eom; + // These sorts of infeasible edges can occur because + // jsr handling is presently vague (any subroutine is + // assumed to be able to return to any callsite) + msg.warning() << "Local variable table: ignoring flow from " + << "clashing variable for " + << it->var.name << " " << pred << " -> " + << amapit->first << messaget::eom; continue; } - // OK, this is a flow from a similar but distinct entry in the local var table. + // OK, this is a flow from a similar but + // distinct entry in the local var table. predecessor_map[&*it].insert(pred_var); } } } - // If a simple pre-block initialiser was found, add it to the live range now: + // If a simple pre-block initialiser was found, + // add it to the live range now: it->var.length+=(it->var.start_pc-new_start_pc); it->var.start_pc=new_start_pc; - } - } static unsigned get_common_dominator( @@ -242,25 +285,30 @@ static unsigned get_common_dominator( unsigned first_pc=UINT_MAX; for(auto v : merge_vars) { - if(v->var.start_pc < first_pc) - first_pc = v->var.start_pc; + if(v->var.start_pcvar.start_pc; } std::vector candidate_dominators; for(auto v : merge_vars) { - const auto& dominator_nodeidx=dominator_analysis.cfg.entry_map.at(v->var.start_pc); - const auto& this_var_doms=dominator_analysis.cfg[dominator_nodeidx].dominators; + const auto& dominator_nodeidx= + dominator_analysis.cfg.entry_map.at(v->var.start_pc); + const auto& this_var_doms= + dominator_analysis.cfg[dominator_nodeidx].dominators; for(const auto this_var_dom : this_var_doms) - if(this_var_dom <= first_pc) + if(this_var_dom<=first_pc) candidate_dominators.push_back(this_var_dom); } - std::sort(candidate_dominators.begin(),candidate_dominators.end()); - - // Working from the back, simply find the first PC that occurs merge_vars.size() - // times and therefore dominates all vars we seek to merge: - for(auto domit=candidate_dominators.rbegin(), domitend=candidate_dominators.rend(); - domit != domitend; /* Don't increment here */) + std::sort(candidate_dominators.begin(), candidate_dominators.end()); + + // Working from the back, simply find the first PC + // that occurs merge_vars.size() times and therefore + // dominates all vars we seek to merge: + for(auto domit=candidate_dominators.rbegin(), + domitend=candidate_dominators.rend(); + domit!=domitend; + /* Don't increment here */) { unsigned repeats=0; auto dom=*domit; @@ -274,7 +322,7 @@ static unsigned get_common_dominator( return dom; } - throw "Variable live ranges with no common dominator?"; + throw "variable live ranges with no common dominator?"; } static void populate_live_range_holes( @@ -283,14 +331,20 @@ static void populate_live_range_holes( unsigned expanded_live_range_start) { std::vector sorted_by_startpc( - merge_vars.begin(),merge_vars.end()); - std::sort(sorted_by_startpc.begin(),sorted_by_startpc.end(),lt_startpc); + merge_vars.begin(), merge_vars.end()); + std::sort(sorted_by_startpc.begin(), sorted_by_startpc.end(), lt_startpc); - maybe_add_hole(merge_into,expanded_live_range_start,sorted_by_startpc[0]->var.start_pc); + maybe_add_hole( + merge_into, + expanded_live_range_start, + sorted_by_startpc[0]->var.start_pc); for(unsigned idx=0; idxvar.start_pc + sorted_by_startpc[idx]->var.length, - sorted_by_startpc[idx+1]->var.start_pc); + { + maybe_add_hole( + merge_into, + sorted_by_startpc[idx]->var.start_pc+sorted_by_startpc[idx]->var.length, + sorted_by_startpc[idx+1]->var.start_pc); + } } static void merge_variable_table_entries( @@ -299,30 +353,36 @@ static void merge_variable_table_entries( const java_cfg_dominatorst& dominator_analysis, std::ostream& debug_out) { - // Because we need a lexically-scoped declaration, we must have the merged variable + // Because we need a lexically-scoped declaration, + // we must have the merged variable // enter scope both in a block that dominates all entries, and which // precedes them in program order. unsigned found_dominator= - get_common_dominator(merge_vars,dominator_analysis); + get_common_dominator(merge_vars, dominator_analysis); - // Populate the holes in the live range (addresses where the new variable - // will be in scope, but references to this stack slot should not resolve to it + // Populate the holes in the live range + // (addresses where the new variable will be in scope, + // but references to this stack slot should not resolve to it // as it was not visible in the original local variable table) - populate_live_range_holes(merge_into,merge_vars,found_dominator); + populate_live_range_holes(merge_into, merge_vars, found_dominator); unsigned last_pc=0; for(auto v : merge_vars) - if(v->var.start_pc+v->var.length > last_pc) + { + if(v->var.start_pc+v->var.length>last_pc) last_pc=v->var.start_pc+v->var.length; + } // Apply the changes: merge_into.var.start_pc=found_dominator; merge_into.var.length=last_pc-found_dominator; #ifdef DEBUG - debug_out << "Merged " << merge_vars.size() << " variables named " << merge_into.var.name << - "; new live range " << merge_into.var.start_pc << "-" << - merge_into.var.start_pc + merge_into.var.length << messaget::eom; + debug_out << "Merged " << merge_vars.size() << " variables named " + << merge_into.var.name << "; new live range " + << merge_into.var.start_pc << "-" + << merge_into.var.start_pc + merge_into.var.length + << messaget::eom; #endif // Nuke the now-subsumed var-table entries: @@ -331,20 +391,20 @@ static void merge_variable_table_entries( v->var.length=0; } -} // End anonymous namespace - void java_bytecode_convert_methodt::find_initialisers_for_slot( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, const address_mapt& amap, const java_cfg_dominatorst& dominator_analysis) { - // Build a simple map from instruction PC to the variable live in this slot at that PC, - // and a map from each variable to variables that flow into it: + // Build a simple map from instruction PC to the variable + // live in this slot at that PC, and a map from each variable + // to variables that flow into it: std::vector live_variable_at_address; - populate_variable_address_map(firstvar,varlimit,live_variable_at_address); + populate_variable_address_map(firstvar, varlimit, live_variable_at_address); - // Now find variables that flow together by walking backwards to find initialisers + // Now find variables that flow together by + // walking backwards to find initialisers // or branches from other live ranges: predecessor_mapt predecessor_map; populate_predecessor_map( @@ -355,24 +415,24 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( predecessor_map, get_message_handler()); - // OK, we've established the flows all seem sensible. Now merge vartable entries - // according to the predecessor_map: + // OK, we've established the flows all seem sensible. + // Now merge vartable entries according to the predecessor_map: // Take the transitive closure of the predecessor map: for(auto& kv : predecessor_map) { std::set closed_preds; - gather_transitive_predecessors(kv.first,predecessor_map,closed_preds); + gather_transitive_predecessors(kv.first, predecessor_map, closed_preds); kv.second=std::move(closed_preds); } // Top-sort so that we get the bottom variables first: - is_predecessor_of comp(predecessor_map); + is_predecessor_oft comp(predecessor_map); std::vector topsorted_vars; - for(auto it=firstvar,itend=varlimit; it!=itend; ++it) + for(auto it=firstvar, itend=varlimit; it!=itend; ++it) topsorted_vars.push_back(&*it); - std::sort(topsorted_vars.begin(),topsorted_vars.end(),comp); + std::sort(topsorted_vars.begin(), topsorted_vars.end(), comp); // Now merge the entries: for(auto merge_into : topsorted_vars) @@ -389,9 +449,12 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( const auto& merge_vars=findit->second; assert(merge_vars.size()>=2); - merge_variable_table_entries(*merge_into,merge_vars,dominator_analysis,status()); + merge_variable_table_entries( + *merge_into, + merge_vars, + dominator_analysis, + status()); } - } static void walk_to_next_index( @@ -418,28 +481,29 @@ void java_bytecode_convert_methodt::find_initialisers( const java_cfg_dominatorst& dominator_analysis) { // Handle one stack slot at a time: - std::sort(vars.begin(),vars.end(),lt_index); + std::sort(vars.begin(), vars.end(), lt_index); auto it1=vars.begin(); auto it2=it1; auto itend=vars.end(); - walk_to_next_index(it1,it2,itend); - for(; it1!=itend; walk_to_next_index(it1,it2,itend)) - find_initialisers_for_slot(it1,it2,amap,dominator_analysis); + walk_to_next_index(it1, it2, itend); + for(; it1!=itend; walk_to_next_index(it1, it2, itend)) + find_initialisers_for_slot(it1, it2, amap, dominator_analysis); } -static void cleanup_var_table(std::vector& vars_with_holes) +static void cleanup_var_table( + std::vector& vars_with_holes) { size_t toremove=0; for(size_t i=0; i<(vars_with_holes.size()-toremove); ++i) { - auto& v=vars_with_holes[i]; + auto &v=vars_with_holes[i]; if(v.var.length==0) { // Move to end; consider the new element we've swapped in: ++toremove; if(i!=vars_with_holes.size()-toremove) // Already where it needs to be? - std::swap(v,vars_with_holes[vars_with_holes.size()-toremove]); + std::swap(v, vars_with_holes[vars_with_holes.size()-toremove]); --i; } } @@ -448,8 +512,9 @@ static void cleanup_var_table(std::vector& vars_with vars_with_holes.resize(vars_with_holes.size()-toremove); } -void java_bytecode_convert_methodt::setup_local_variables(const methodt& m, - const address_mapt& amap) +void java_bytecode_convert_methodt::setup_local_variables( + const methodt& m, + const address_mapt& amap) { // Compute CFG dominator tree java_cfg_dominatorst dominator_analysis; @@ -462,7 +527,7 @@ void java_bytecode_convert_methodt::setup_local_variables(const methodt& m, vars_with_holes.push_back({v, {}}); // Merge variable records: - find_initialisers(vars_with_holes,amap,dominator_analysis); + find_initialisers(vars_with_holes, amap, dominator_analysis); // Clean up removed records from the variable table: cleanup_var_table(vars_with_holes); @@ -488,10 +553,10 @@ void java_bytecode_convert_methodt::setup_local_variables(const methodt& m, result.set(ID_C_base_name, v.var.name); variables[v.var.index].push_back(variablet()); - auto& newv=variables[v.var.index].back(); - newv.symbol_expr = result; - newv.start_pc = v.var.start_pc; - newv.length = v.var.length; + auto &newv=variables[v.var.index].back(); + newv.symbol_expr=result; + newv.start_pc=v.var.start_pc; + newv.length=v.var.length; newv.holes=std::move(v.holes); symbolt new_symbol; @@ -506,7 +571,6 @@ void java_bytecode_convert_methodt::setup_local_variables(const methodt& m, new_symbol.is_lvalue=true; symbol_table.add(new_symbol); } - } const java_bytecode_convert_methodt::variablet & @@ -516,9 +580,9 @@ java_bytecode_convert_methodt::find_variable_for_slot( { for(const variablet &var : var_list) { - size_t start_pc = var.start_pc; - size_t length = var.length; - if (address>=start_pc && address<(start_pc+length)) + size_t start_pc=var.start_pc; + size_t length=var.length; + if(address>=start_pc && address<(start_pc+length)) { bool found_hole=false; for(auto &hole : var.holes) @@ -536,7 +600,7 @@ java_bytecode_convert_methodt::find_variable_for_slot( // with scope from 0 to INT_MAX // as it is at the end of the vector, it will only be taken into account // if no other variable is valid - size_t list_length = var_list.size(); + size_t list_length=var_list.size(); var_list.resize(list_length+1); var_list[list_length].start_pc=0; var_list[list_length].length=std::numeric_limits::max(); From b309f0604286970d6de6f80c143a07397fd0f97f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 19 Jan 2017 12:49:05 +0000 Subject: [PATCH 013/166] Add documentation --- .../java_local_variable_table.cpp | 252 +++++++++++++++++- 1 file changed, 247 insertions(+), 5 deletions(-) diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index fa566318d24..d70fd18264e 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -60,6 +60,7 @@ struct procedure_local_cfg_baset< } }; +// Grab some class typdefs for brevity: typedef java_bytecode_convert_methodt::holet holet; typedef java_bytecode_convert_methodt::local_variable_with_holest @@ -112,6 +113,20 @@ struct is_predecessor_oft // Helper routines for the find-initialisers code below: +/*******************************************************************\ + +Function: gather_transitive_predecessors + + Inputs: `start`: Variable to find the predecessors of + `predecessor_map`: Map from local variables + to sets of predecessors + Outputs: `result`: populated with all transitive predecessors of + `start` found in `predecessor_map` + + Purpose: See above + +\*******************************************************************/ + static void gather_transitive_predecessors( local_variable_with_holest* start, const predecessor_mapt& predecessor_map, @@ -126,6 +141,20 @@ static void gather_transitive_predecessors( gather_transitive_predecessors(pred, predecessor_map, result); } +/*******************************************************************\ + +Function: is_store_to_slot + + Inputs: `inst`: Java bytecode instruction + `slotidx`: local variable slot number + + Outputs: Returns true if `inst` is any form of store instruction + targeting slot `slotidx` + + Purpose: See above + +\*******************************************************************/ + static bool is_store_to_slot( const java_bytecode_convert_methodt::instructiont& inst, unsigned slotidx) @@ -137,11 +166,13 @@ static bool is_store_to_slot( std::string storeslot; if(inst.args.size()==1) { + // Store with an argument: const auto& arg=inst.args[0]; storeslot=id2string(to_constant_expr(arg).get_value()); } else { + // Store shorthands, like "store_0", "store_1" assert(prevstatement[6]=='_' && prevstatement.size()==8); storeslot=prevstatement[7]; assert(isdigit(storeslot[0])); @@ -150,6 +181,19 @@ static bool is_store_to_slot( return storeslotidx==slotidx; } +/*******************************************************************\ + +Function: maybe_add_hole + + Inputs: `from`, `to`: bounds of a gap in `var`'s live range, + inclusive and exclusive respectively + + Outputs: Adds a hole to `var`, unless it would be of zero size. + + Purpose: See above + +\*******************************************************************/ + static void maybe_add_hole( local_variable_with_holest& var, unsigned from, @@ -160,6 +204,22 @@ static void maybe_add_hole( var.holes.push_back({from, to-from}); } +/*******************************************************************\ + +Function: populate_variable_address_map + + Inputs: `firstvar`-`varlimit`: range of local variable table + entries to consider + + Outputs: `live_variable_at_address` is populated with a sequence of + local variable table entry pointers, such that + `live_variable_at_address[addr]` yields the unique table + entry covering that address. Asserts if entries overlap. + + Purpose: See above + +\*******************************************************************/ + static void populate_variable_address_map( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, @@ -172,7 +232,8 @@ static void populate_variable_address_map( for(unsigned idx=it->var.start_pc, idxlim=it->var.start_pc+it->var.length; - idx!=idxlim; ++idx) + idx!=idxlim; + ++idx) { assert((!live_variable_at_address[idx]) && "Local variable table clash?"); live_variable_at_address[idx]=&*it; @@ -180,6 +241,32 @@ static void populate_variable_address_map( } } +/*******************************************************************\ + +Function: populate_predecessor_map + + Inputs: `firstvar`-`varlimit`: range of local variable table + entries to consider + `live_variable_at_address`: map from bytecode address + to table entry (drawn from firstvar-varlimit) live + at that address + `amap`: map from bytecode address to instructions + + Outputs: Populates `predecessor_map` with a graph from local variable + table entries to their predecessors (table entries which + may flow together and thus may be considered the same live + range). + + Purpose: Usually a live variable range begins with a store + instruction initialising the relevant local variable slot, + but instead of or in addition to this, control flow edges + may exist from bytecode addresses that fall under a + table entry which differs, but which has the same variable + name and type descriptor. This indicates a split live + range, and will be recorded in the predecessor map. + +\*******************************************************************/ + static void populate_predecessor_map( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, @@ -198,6 +285,7 @@ static void populate_predecessor_map( // Find the last instruction within the live range: unsigned end_pc=it->var.start_pc+it->var.length; auto amapit=amap.find(end_pc); + assert(amapit!=amap.begin()); auto old_amapit=amapit; --amapit; if(old_amapit==amap.end()) @@ -228,6 +316,7 @@ static void populate_predecessor_map( // Check if this is an initialiser, and if so expand the live range // to include it, but don't check its predecessors: auto inst_before_this=amapit; + assert(inst_before_this!=amap.begin()); --inst_before_this; if(amapit->first!=it->var.start_pc || inst_before_this->first!=pred) { @@ -276,11 +365,29 @@ static void populate_predecessor_map( } } +/*******************************************************************\ + +Function: get_common_dominator + + Inputs: `merge_vars`: Set of variables we want the common dominator + for. + `dominator_analysis`: Already-initialised dominator tree + + Outputs: Returns the bytecode address of the closest common + dominator of all given variable table entries. + In the worst case the function entry point should always + satisfy this criterion. + + Purpose: Used to find out where to put a variable declaration that + subsumes several variable live ranges. + +\*******************************************************************/ + static unsigned get_common_dominator( const std::set& merge_vars, const java_cfg_dominatorst& dominator_analysis) { - assert(merge_vars.size()!=0); + assert(!merge_vars.empty()); unsigned first_pc=UINT_MAX; for(auto v : merge_vars) @@ -325,6 +432,24 @@ static unsigned get_common_dominator( throw "variable live ranges with no common dominator?"; } +/*******************************************************************\ + +Function: populate_live_range_holes + + Inputs: `merge_vars`: a set of 2+ variable table entries to merge + `expanded_live_range_start`: address where the merged + variable will be declared + + Outputs: Adds holes to `merge_into`, indicating where gaps in the + variable's live range fall. For example, if the + declaration happens at address 10 and the entries in + `merge_into` have live ranges [(20-30), (40-50)] then + holes will be added at (10-20) and (30-40). + + Purpose: See above + +\*******************************************************************/ + static void populate_live_range_holes( local_variable_with_holest& merge_into, const std::set& merge_vars, @@ -347,6 +472,22 @@ static void populate_live_range_holes( } } +/*******************************************************************\ + +Function: merge_variable_table_entries + + Inputs: `merge_vars`: a set of 2+ variable table entries to merge + `dominator_analysis`: already-calculated dominator tree + + Outputs: Populates `merge_into` as a combined variable table entry, + with live range holes if the `merge_vars` entries do not + cover a contiguous address range, beginning the combined + live range at the common dominator of all `merge_vars`. + + Purpose: See above + +\*******************************************************************/ + static void merge_variable_table_entries( local_variable_with_holest& merge_into, const std::set& merge_vars, @@ -391,6 +532,28 @@ static void merge_variable_table_entries( v->var.length=0; } +/*******************************************************************\ + +Function: find_initialisers_for_slot + + Inputs: `firstvar`-`varlimit`: sequence of variable table entries, + all of which should concern the same slot index. + `amap`: Map from bytecode address to instruction + + Outputs: Side-effect: merges variable table entries which flow into + one another (e.g. there are branches from one live range + to another without re-initialising the local slot). + + Purpose: Given a sequence of users of the same local variable slot, + this figures out which ones are related by control flow, + and combines them into a single entry with holes, such that + after combination we can create a single + declaration per variable table entry, + placed at the live range's start address, which may + be moved back so that the declaration dominates all uses. + +\*******************************************************************/ + void java_bytecode_convert_methodt::find_initialisers_for_slot( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, @@ -457,6 +620,23 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( } } +/*******************************************************************\ + +Function: walk_to_next_index + + Inputs: `it1` and `it2`, which are iterators into the same vector, + of which `itend` is the end() iterator. + + Outputs: Moves `it1` and `it2` to delimit a sequence of variable + table entries with slot index equal to it2->var.index + on entering this function, or to both equal itend if + it2==itend on entry. + + Purpose: Walk a vector, a contiguous block of entries with equal + slot index at a time. + +\*******************************************************************/ + static void walk_to_next_index( local_variable_table_with_holest::iterator& it1, local_variable_table_with_holest::iterator& it2, @@ -475,14 +655,31 @@ static void walk_to_next_index( it1=old_it2; } +/*******************************************************************\ + +Function: find_initialisers + + Inputs: `vars`: Local variable table + `amap`: Map from bytecode index to instruction + `dominator_analysis`: Already computed dominator tree for + the Java function described by `amap` + + Outputs: Combines entries in `vars` which flow together + + Purpose: See `find_initialisers_for_slot` above for more detail. + +\*******************************************************************/ + void java_bytecode_convert_methodt::find_initialisers( local_variable_table_with_holest& vars, const address_mapt& amap, const java_cfg_dominatorst& dominator_analysis) { - // Handle one stack slot at a time: + // Sort table entries by local slot index: std::sort(vars.begin(), vars.end(), lt_index); + // For each block of entries using a particular index, + // try to combine them: auto it1=vars.begin(); auto it2=it1; auto itend=vars.end(); @@ -491,6 +688,18 @@ void java_bytecode_convert_methodt::find_initialisers( find_initialisers_for_slot(it1, it2, amap, dominator_analysis); } +/*******************************************************************\ + +Function: cleanup_var_table + + Inputs: `vars_with_holes`: variable table + + Outputs: Removes zero-size entries from `vars_with_holes` + + Purpose: See above + +\*******************************************************************/ + static void cleanup_var_table( std::vector& vars_with_holes) { @@ -504,7 +713,8 @@ static void cleanup_var_table( ++toremove; if(i!=vars_with_holes.size()-toremove) // Already where it needs to be? std::swap(v, vars_with_holes[vars_with_holes.size()-toremove]); - --i; + --i; // May make i (size_t)-1, but it will immediately be + // re-incremented as the loop iterates. } } @@ -512,6 +722,22 @@ static void cleanup_var_table( vars_with_holes.resize(vars_with_holes.size()-toremove); } +/*******************************************************************\ + +Function: setup_local_variables + + Inputs: `m`: Java method + `amap`: Map from bytecode indices to instructions in `m` + + Outputs: Populates `this->vars_with_holes` equal to + `this->local_variable_table`, only with variable table + entries that flow together combined. + Also symbol-table registers all locals. + + Purpose: See `find_initialisers_for_slot` above for more detail. + +\*******************************************************************/ + void java_bytecode_convert_methodt::setup_local_variables( const methodt& m, const address_mapt& amap) @@ -573,6 +799,22 @@ void java_bytecode_convert_methodt::setup_local_variables( } } +/*******************************************************************\ + +Function: find_variable_for_slot + + Inputs: `address`: Address to find a variable table entry for + `var_list`: List of candidates that use the slot we're + interested in + + Outputs: Returns the list entry covering this address (taking live + range holes into account), or creates/returns an anonymous + variable entry if nothing covers `address`. + + Purpose: See above + +\*******************************************************************/ + const java_bytecode_convert_methodt::variablet & java_bytecode_convert_methodt::find_variable_for_slot( size_t address, @@ -597,7 +839,7 @@ java_bytecode_convert_methodt::find_variable_for_slot( } } // add unnamed local variable to end of list at this index - // with scope from 0 to INT_MAX + // with scope from 0 to SIZE_T_MAX // as it is at the end of the vector, it will only be taken into account // if no other variable is valid size_t list_length=var_list.size(); From 7372e8f5c3a240f6b2cd34163de0c67a9ddd4d48 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 7 Dec 2016 15:06:13 +0000 Subject: [PATCH 014/166] Add tests for local variable live ranges with holes Both of these feature local variables that are declared in the class file LVT with two or more live ranges, because of initialisation by a try/catch or the cases of a switch statement. The tests assert that the initialisation is as expected, to catch cases where the two live ranges are erroneously treated seperately and so the variable read in the assertion is an effective nondet. --- .../live_range_with_holes.class | Bin 0 -> 798 bytes .../LocalVarTable3/live_range_with_holes.java | 26 ++++++++++++++++++ regression/cbmc-java/LocalVarTable3/test.desc | 7 +++++ .../LocalVarTable4/live_range_exception.class | Bin 0 -> 780 bytes .../LocalVarTable4/live_range_exception.java | 18 ++++++++++++ regression/cbmc-java/LocalVarTable4/test.desc | 7 +++++ 6 files changed, 58 insertions(+) create mode 100644 regression/cbmc-java/LocalVarTable3/live_range_with_holes.class create mode 100644 regression/cbmc-java/LocalVarTable3/live_range_with_holes.java create mode 100644 regression/cbmc-java/LocalVarTable3/test.desc create mode 100644 regression/cbmc-java/LocalVarTable4/live_range_exception.class create mode 100644 regression/cbmc-java/LocalVarTable4/live_range_exception.java create mode 100644 regression/cbmc-java/LocalVarTable4/test.desc diff --git a/regression/cbmc-java/LocalVarTable3/live_range_with_holes.class b/regression/cbmc-java/LocalVarTable3/live_range_with_holes.class new file mode 100644 index 0000000000000000000000000000000000000000..af3f7e4358a4ac1e72766f3ca16506c8dcbce045 GIT binary patch literal 798 zcmZuuO-~b16g_V~I&B%Cv;}HgYxxQvA?=2p#b^*BN!100L^jQ|eW4GBj+vRF{uSJs zuyCa&l4zoPe~AA=<9Vf&g)H8?_nvw8oOAE|`upt%fGw<~;h>a)jk1HgX_zQEsHAZZ zRR;?Kxn(bkWEiWUA3au)*Y;&sKpY7q8mh122Lk5W`k{ce6Lh7(bW`=^v%zUwhA;GE zfowDAc>bXmDqW92EAFXCV7}?AGuaBg{;_PmQE{);3w#;fC*7&1`V4FPnq0i)+2?sj zIWIgGm^_HR&a0>1>k(nH(eX!q(g(pH?8rT()r+?Z)K0uJ&qW#&E|N$I6f{ux>7)MW zdfweI3_^j~TNxZIx>&-pK<1|PdHY0mVlLqZ+VQzRfw``XR4BV+a@vmv{J`ZMVS(#+ z_&Y?VpzSa-A+$T*E~`4DV6-~G zOrsU%RjMt~%L+ZL(!~ZHY$Asm=CF&x(B%`3S>dob|;w}>9MB)!jA*LKUDU27kHJlEZ$=Y9$IEQ0hz%swU_= 0 && x <= 2); + + } + +} diff --git a/regression/cbmc-java/LocalVarTable3/test.desc b/regression/cbmc-java/LocalVarTable3/test.desc new file mode 100644 index 00000000000..a50e15252db --- /dev/null +++ b/regression/cbmc-java/LocalVarTable3/test.desc @@ -0,0 +1,7 @@ +CORE +live_range_with_holes.class +--function live_range_with_holes.main +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- diff --git a/regression/cbmc-java/LocalVarTable4/live_range_exception.class b/regression/cbmc-java/LocalVarTable4/live_range_exception.class new file mode 100644 index 0000000000000000000000000000000000000000..71b1dd48d11031ebdc6475f126df195b1d1aa977 GIT binary patch literal 780 zcmZuvO>fgc6r7E>apF3So2DTRpKSva4&;(sA_OW0A*FCAs?=U8$63J^*Qso$DnEr@ zIQGJ&AW;b}<* zRC>d}4|n}on|Pd*=^LF0)Ow*lQ3tUfy;cY6G*HJzs6)0RUq{qAr9G#;qmgU5cj%w^ zt&sTE)<5vlPU;75xBcUco);1*bc1j_ptCa^#esUN%{VKw6dxE`7xQp=;~5ezif{z# z)6(O=TiJ@^VJuLcMQh`>i#xb0;7vPU_77E%a#PdPX2>OT8v~W-SPdrJyj414fg9e( zD&MHUXA@rCOheCtFeCF@V$|X(c+TCwgt(xS!veqgESW=@zJU?|4~smDs7#ta5^XWp zv^rMz9EEM!k=;+Q&QNW0TwIy dFR;&G%X3KUGpzqtV2C(?`^YTnDuW!Z{Q;aDk0by9 literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/LocalVarTable4/live_range_exception.java b/regression/cbmc-java/LocalVarTable4/live_range_exception.java new file mode 100644 index 00000000000..52e5d54070a --- /dev/null +++ b/regression/cbmc-java/LocalVarTable4/live_range_exception.java @@ -0,0 +1,18 @@ + +public class live_range_exception { + public static void main() { + int x; + int y; + try + { + x = 0; + y = 0; + } + catch(Exception e) + { + x = 1; + y = 1; + } + assert(x==0 || x==1); + } +} diff --git a/regression/cbmc-java/LocalVarTable4/test.desc b/regression/cbmc-java/LocalVarTable4/test.desc new file mode 100644 index 00000000000..bf94c110fcc --- /dev/null +++ b/regression/cbmc-java/LocalVarTable4/test.desc @@ -0,0 +1,7 @@ +CORE +live_range_exception.class +--function live_range_exception.main +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- From e12cf9bab4511e88a7c0b90af5e7e738a9416a62 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 21 Jan 2014 21:03:51 +0000 Subject: [PATCH 015/166] Cleanup of operands() accesses Use iterators instead of indexed access. This may re-enable std::list support (for exprt::operandst) if taken further. --- src/cpp/cpp_template_args.h | 4 +-- src/cpp/cpp_typecheck.cpp | 2 +- src/cpp/cpp_typecheck_expr.cpp | 25 +++++++------ src/cpp/cpp_typecheck_fargs.cpp | 35 ++++++++++--------- src/cpp/cpp_typecheck_resolve.cpp | 24 +++++++------ src/solvers/flattening/boolbv_get.cpp | 6 ++-- src/solvers/flattening/boolbv_struct.cpp | 14 ++++---- .../flattening/flatten_byte_operators.cpp | 2 +- src/solvers/prop/prop_conv.cpp | 2 +- src/util/base_type.cpp | 11 ++++-- src/util/expr_util.cpp | 9 +++-- src/util/std_code.h | 12 +++---- 12 files changed, 80 insertions(+), 66 deletions(-) diff --git a/src/cpp/cpp_template_args.h b/src/cpp/cpp_template_args.h index 18c27b83cae..b30e17b7f4e 100644 --- a/src/cpp/cpp_template_args.h +++ b/src/cpp/cpp_template_args.h @@ -9,7 +9,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #ifndef CPROVER_CPP_CPP_TEMPLATE_ARGS_H #define CPROVER_CPP_CPP_TEMPLATE_ARGS_H -#include +#include // A data structures for template arguments, i.e., // a sequence of types/expressions of the form . @@ -22,7 +22,7 @@ class cpp_template_args_baset:public irept { } - typedef std::vector argumentst; + typedef exprt::operandst argumentst; argumentst &arguments() { diff --git a/src/cpp/cpp_typecheck.cpp b/src/cpp/cpp_typecheck.cpp index 3a2adda985f..6a53c0aa04d 100644 --- a/src/cpp/cpp_typecheck.cpp +++ b/src/cpp/cpp_typecheck.cpp @@ -343,7 +343,7 @@ void cpp_typecheckt::do_not_typechecked() } else if(symbol.value.operands().size()==1) { - exprt tmp = symbol.value.operands()[0]; + exprt tmp = symbol.value.op0(); symbol.value.swap(tmp); convert_function(symbol); cont=true; diff --git a/src/cpp/cpp_typecheck_expr.cpp b/src/cpp/cpp_typecheck_expr.cpp index 8e98bf1a937..1bc298665f3 100644 --- a/src/cpp/cpp_typecheck_expr.cpp +++ b/src/cpp/cpp_typecheck_expr.cpp @@ -2577,28 +2577,31 @@ void cpp_typecheckt::typecheck_function_call_arguments( } } - for(std::size_t i=0; iid()!=ID_temporary_object) { // create a temporary for the parameter exprt arg("already_typechecked"); - arg.copy_to_operands(expr.arguments()[i]); + arg.copy_to_operands(*arg_it); exprt temporary; - new_temporary(expr.arguments()[i].source_location(), - parameters[i].type().subtype(), - arg, - temporary); - expr.arguments()[i].swap(temporary); + new_temporary( + arg_it->source_location(), + parameter.type().subtype(), + arg, + temporary); + arg_it->swap(temporary); } - } + + ++arg_it; } c_typecheck_baset::typecheck_function_call_arguments(expr); diff --git a/src/cpp/cpp_typecheck_fargs.cpp b/src/cpp/cpp_typecheck_fargs.cpp index 48088cd3e6f..b0beff42864 100644 --- a/src/cpp/cpp_typecheck_fargs.cpp +++ b/src/cpp/cpp_typecheck_fargs.cpp @@ -83,7 +83,7 @@ bool cpp_typecheck_fargst::match( { distance=0; - exprt::operandst ops = operands; + exprt::operandst ops=operands; const code_typet::parameterst ¶meters=code_type.parameters(); if(parameters.size()>ops.size()) @@ -109,7 +109,8 @@ bool cpp_typecheck_fargst::match( return false; } - for(std::size_t i=0; i=parameters.size()) - { - // Ellipsis is the 'worst' of the conversion sequences - distance+=1000; - continue; - } - - exprt parameter=parameters[i]; - - exprt &operand=ops[i]; + assert(it!=ops.end()); + const exprt &operand=*it; + typet type=parameter.type(); #if 0 // unclear, todo @@ -140,13 +134,13 @@ bool cpp_typecheck_fargst::match( // "this" is a special case -- we turn the pointer type // into a reference type to do the type matching - if(i==0 && parameter.get(ID_C_base_name)==ID_this) + if(it==ops.begin() && parameter.get(ID_C_base_name)==ID_this) { - parameter.type().set(ID_C_reference, true); - parameter.type().set("#this", true); + type.set(ID_C_reference, true); + type.set("#this", true); } - unsigned rank = 0; + unsigned rank=0; exprt new_expr; #if 0 @@ -156,7 +150,7 @@ bool cpp_typecheck_fargst::match( // can we do the standard conversion sequence? if(cpp_typecheck.implicit_conversion_sequence( - operand, parameter.type(), new_expr, rank)) + operand, type, new_expr, rank)) { // ok distance+=rank; @@ -171,7 +165,14 @@ bool cpp_typecheck_fargst::match( #endif return false; // no conversion possible } + + ++it; } + // we may not have used all operands + for( ; it!=ops.end(); ++it) + // Ellipsis is the 'worst' of the conversion sequences + distance+=1000; + return true; } diff --git a/src/cpp/cpp_typecheck_resolve.cpp b/src/cpp/cpp_typecheck_resolve.cpp index 3974920870c..e8502c1419a 100644 --- a/src/cpp/cpp_typecheck_resolve.cpp +++ b/src/cpp/cpp_typecheck_resolve.cpp @@ -358,7 +358,7 @@ exprt cpp_typecheck_resolvet::convert_identifier( { // the object is given to us in fargs assert(!fargs.operands.empty()); - object=fargs.operands[0]; + object=fargs.operands.front(); } else if(this_expr.is_not_nil()) { @@ -841,7 +841,7 @@ exprt cpp_typecheck_resolvet::do_builtin( throw 0; } - const exprt &argument=arguments[0]; + const exprt &argument=arguments.front(); if(argument.id()==ID_type) { @@ -2193,13 +2193,16 @@ exprt cpp_typecheck_resolvet::guess_function_template_args( const irept::subt ¶meters= function_declarator.type().find(ID_parameters).get_sub(); - for(std::size_t i=0; itype()); } + + ++it; } // see if that has worked out @@ -2633,10 +2638,9 @@ void cpp_typecheck_resolvet::resolve_with_arguments( const cpp_typecheck_fargst &fargs) { // not clear what this is good for - for(std::size_t i=0; itype(); - const exprt &op=expr.operands()[i]; + const typet &subtype=comp.type(); + const exprt &op=*op_it; if(!base_type_eq(subtype, op.type(), ns)) { @@ -76,7 +74,7 @@ bvt boolbvt::convert_struct(const struct_exprt &expr) offset+=op_bv.size(); } - i++; + ++op_it; } assert(offset==width); diff --git a/src/solvers/flattening/flatten_byte_operators.cpp b/src/solvers/flattening/flatten_byte_operators.cpp index 2f27e88b05b..bd3d4198da6 100644 --- a/src/solvers/flattening/flatten_byte_operators.cpp +++ b/src/solvers/flattening/flatten_byte_operators.cpp @@ -87,7 +87,7 @@ exprt flatten_byte_extract( // TODO this doesn't seem correct if size_bits%8!=0 as more // bits than the original expression will be returned. if(width_bytes==1) - return op[0]; + return op.front(); else // width_bytes>=2 { concatenation_exprt concatenation(src.type()); diff --git a/src/solvers/prop/prop_conv.cpp b/src/solvers/prop/prop_conv.cpp index b717ff6f836..e8bdcbdfb11 100644 --- a/src/solvers/prop/prop_conv.cpp +++ b/src/solvers/prop/prop_conv.cpp @@ -399,7 +399,7 @@ literalt prop_conv_solvert::convert_bool(const exprt &expr) if(op.size()!=1) throw "not takes one operand"; - return !convert(op[0]); + return !convert(op.front()); } else if(expr.id()==ID_equal || expr.id()==ID_notequal) { diff --git a/src/util/base_type.cpp b/src/util/base_type.cpp index 898c235db05..2090d863339 100644 --- a/src/util/base_type.cpp +++ b/src/util/base_type.cpp @@ -301,11 +301,16 @@ bool base_type_eqt::base_type_eq_rec( if(!base_type_eq(expr1.type(), expr2.type())) return false; - if(expr1.operands().size()!=expr2.operands().size()) + const exprt::operandst &expr1_op=expr1.operands(); + const exprt::operandst &expr2_op=expr2.operands(); + if(expr1_op.size()!=expr2_op.size()) return false; - for(unsigned i=0; i &_list):codet(ID_block) { operandst &o=operands(); - o.reserve(_list.size()); + reserve_operands(_list.size()); for(std::list::const_iterator it=_list.begin(); it!=_list.end(); @@ -282,7 +282,7 @@ class code_assumet:public codet inline code_assumet():codet(ID_assume) { // will change to resize(1) in the future - operands().reserve(1); + reserve_operands(1); } inline explicit code_assumet(const exprt &expr):codet(ID_assume) @@ -321,7 +321,7 @@ class code_assertt:public codet inline code_assertt():codet(ID_assert) { // will change to resize(1) in the future - operands().reserve(1); + reserve_operands(1); } inline explicit code_assertt(const exprt &expr):codet(ID_assert) @@ -723,7 +723,7 @@ class code_returnt:public codet public: inline code_returnt():codet(ID_return) { - operands().reserve(1); + reserve_operands(1); } explicit inline code_returnt(const exprt &_op):codet(ID_return) @@ -931,7 +931,7 @@ class code_asmt:public codet inline explicit code_asmt(const exprt &expr):codet(ID_asm) { - operands().push_back(expr); + copy_to_operands(expr); } inline const irep_idt &get_flavor() const @@ -969,7 +969,7 @@ class code_expressiont:public codet inline explicit code_expressiont(const exprt &expr):codet(ID_expression) { - operands().push_back(expr); + copy_to_operands(expr); } inline friend code_expressiont &to_code_expression(codet &code) From 85118e140c46182077697eef76e11614eeb0d943 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Wed, 18 Jan 2017 07:45:40 -0800 Subject: [PATCH 016/166] Consistently resize instead of just reserving in codet classes --- src/util/std_code.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/util/std_code.h b/src/util/std_code.h index a6339fad62f..2f58d71352e 100644 --- a/src/util/std_code.h +++ b/src/util/std_code.h @@ -281,8 +281,7 @@ class code_assumet:public codet public: inline code_assumet():codet(ID_assume) { - // will change to resize(1) in the future - reserve_operands(1); + operands().resize(1); } inline explicit code_assumet(const exprt &expr):codet(ID_assume) @@ -320,8 +319,7 @@ class code_assertt:public codet public: inline code_assertt():codet(ID_assert) { - // will change to resize(1) in the future - reserve_operands(1); + operands().resize(1); } inline explicit code_assertt(const exprt &expr):codet(ID_assert) @@ -723,7 +721,8 @@ class code_returnt:public codet public: inline code_returnt():codet(ID_return) { - reserve_operands(1); + operands().resize(1); + op0().make_nil(); } explicit inline code_returnt(const exprt &_op):codet(ID_return) @@ -738,13 +737,14 @@ class code_returnt:public codet inline exprt &return_value() { - operands().resize(1); return op0(); } inline bool has_return_value() const { - return operands().size()==1; + if(operands().empty()) + return false; // backwards compatibility + return return_value().is_not_nil(); } }; From bce928f6f312be9ba8d254752fe314e89fc647d5 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 23 Jan 2017 12:36:27 +0000 Subject: [PATCH 017/166] Fix package_friendly1 test This used to check for an interface method getting added as a goto function, which doesn't happen anymore. --- regression/cbmc-java/package_friendly1/test.desc | 1 - 1 file changed, 1 deletion(-) diff --git a/regression/cbmc-java/package_friendly1/test.desc b/regression/cbmc-java/package_friendly1/test.desc index 4559f083646..108ea5defb1 100644 --- a/regression/cbmc-java/package_friendly1/test.desc +++ b/regression/cbmc-java/package_friendly1/test.desc @@ -2,7 +2,6 @@ CORE main.class package_friendly1.class package_friendly2.class --show-goto-functions ^main[.]main[(][)].*$ -^package_friendly1[.]operation1[(][)].*$ ^package_friendly2[.]operation2[(][)].*$ ^EXIT=0$ ^SIGNAL=0$ From e647aafca495d4fca919faa54bc270dd9271db86 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 23 Jan 2017 12:37:06 +0000 Subject: [PATCH 018/166] Enable Java regression tests The primary `make test` goal now also runs the cbmc-java test subdirectory. --- regression/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression/Makefile b/regression/Makefile index e8a0f506983..1243ec9a468 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -1,5 +1,5 @@ -DIRS = ansi-c cbmc cpp goto-instrument goto-analyzer +DIRS = ansi-c cbmc cpp goto-instrument goto-analyzer cbmc-java test: $(foreach var,$(DIRS), $(MAKE) -C $(var) test || exit 1;) From 7c2e95ace7928ac5c7f298ad5cda62484bfa198c Mon Sep 17 00:00:00 2001 From: Pascal Kesseli Date: Mon, 23 Jan 2017 16:01:15 +0000 Subject: [PATCH 019/166] Fixed CEGIS control vector solution nondet Nondet was added too late in _start, leading to a new nondet solution at each CEGIS counterexample loop iteration. The bug was not present in the verification phase, hence any solution produced by this was still sound. However, this severely affects CEGIS' ability to find adequate solutions and worst case leads to a "same counterexample" assertion violation. --- .../cegis_control_benchmark_04/test.desc | 2 +- .../learn/vector_solution_configuration.cpp | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/regression/cegis/cegis_control_benchmark_04/test.desc b/regression/cegis/cegis_control_benchmark_04/test.desc index a4d971121db..5c8ebf51923 100644 --- a/regression/cegis/cegis_control_benchmark_04/test.desc +++ b/regression/cegis/cegis_control_benchmark_04/test.desc @@ -1,6 +1,6 @@ CORE safety_stability.c ---gcc --round-to-minus-inf --cegis-control --cegis-statistics --cegis-max-size 1 --cegis-show-iterations -D CPROVER -D _CONTROL_FLOAT_WIDTH=64 -D _CONTORL_RADIX_WIDTH=24 -D NUMBERLOOPS=10 +--gcc --round-to-minus-inf --cegis-control --cegis-statistics --cegis-max-size 1 --cegis-show-iterations -D CPROVER -D _CONTROL_FLOAT_WIDTH=32 -D _CONTORL_RADIX_WIDTH=24 -D NUMBERLOOPS=10 EXIT=0 SIGNAL=0 -- diff --git a/src/cegis/control/learn/vector_solution_configuration.cpp b/src/cegis/control/learn/vector_solution_configuration.cpp index 664a04fe8f9..fd7ee3c400d 100644 --- a/src/cegis/control/learn/vector_solution_configuration.cpp +++ b/src/cegis/control/learn/vector_solution_configuration.cpp @@ -2,15 +2,41 @@ #include +#include +#include #include #include #include #include #include +namespace +{ +bool is_assignment_to_solution_var(const goto_programt::instructiont &instr) +{ + if (goto_program_instruction_typet::ASSIGN != instr.type) return false; + const std::string &var_name=id2string(get_affected_variable(instr)); + return CEGIS_CONTROL_VECTOR_SOLUTION_VAR_NAME == var_name; +} +} + void vector_solution_configurationt::nondeterminise_solution_configuration( symbol_tablet &st, goto_functionst &gf) { + goto_programt &init_body=get_body(gf, CPROVER_INIT); + goto_programt::instructionst &init_instrs=init_body.instructions; + const goto_programt::targett assignment=std::find_if(init_instrs.begin(), + init_instrs.end(), is_assignment_to_solution_var); + goto_programt &entry_body=get_entry_body(gf); + const goto_programt::targett first_entry=entry_body.instructions.begin(); + const goto_programt::targett new_assignment=entry_body.insert_before( + first_entry); + new_assignment->source_location=first_entry->source_location; + new_assignment->type=assignment->type; + new_assignment->code=assignment->code; + init_body.instructions.erase(assignment); + init_body.update(); + entry_body.update(); } namespace From 1a9c2b3914c025e439d504b70d9e1a0f9ffbbde3 Mon Sep 17 00:00:00 2001 From: Pascal Kesseli Date: Mon, 23 Jan 2017 17:06:38 +0000 Subject: [PATCH 020/166] Fixed nondet returns in benchmark Benchmark contained unused, nondet return values which caused an assertion violation in remove_returns.cpp. --- .../cegis/cegis_control_benchmark_03/safety_stability.c | 5 ++--- .../cegis/cegis_control_benchmark_04/safety_stability.c | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/regression/cegis/cegis_control_benchmark_03/safety_stability.c b/regression/cegis/cegis_control_benchmark_03/safety_stability.c index c41d2bed5ba..2471d35b8ba 100644 --- a/regression/cegis/cegis_control_benchmark_03/safety_stability.c +++ b/regression/cegis/cegis_control_benchmark_03/safety_stability.c @@ -450,7 +450,7 @@ void assert_nonzero_controller(void) { __DSVERIFIER_assert(nonzero_coefficients > 0); } -int safety_stability(void) { +void safety_stability(void) { #ifdef INTERVAL get_bounds(); //get interval bounds #endif @@ -466,8 +466,6 @@ int safety_stability(void) { __CPROVER_array_copy(K_fxp_trace, K_fxp); //__CPROVER_assert(0 == 1, ""); #endif - - return 0; } int main(void) { @@ -484,4 +482,5 @@ int main(void) { #ifndef CPROVER } #endif + return 0; } diff --git a/regression/cegis/cegis_control_benchmark_04/safety_stability.c b/regression/cegis/cegis_control_benchmark_04/safety_stability.c index 386adbbc06e..786ac6ce87f 100644 --- a/regression/cegis/cegis_control_benchmark_04/safety_stability.c +++ b/regression/cegis/cegis_control_benchmark_04/safety_stability.c @@ -466,7 +466,7 @@ void assert_nonzero_controller(void) { __DSVERIFIER_assert(nonzero_coefficients > 0); } -int safety_stability(void) { +void safety_stability(void) { #ifdef INTERVAL get_bounds(); //get interval bounds #endif @@ -502,4 +502,5 @@ int main(void) { #ifndef CPROVER } #endif + return 0; } From 76cf8be850532bba153e01d7601abd2751177591 Mon Sep 17 00:00:00 2001 From: thk123 Date: Tue, 10 Jan 2017 15:55:08 +0000 Subject: [PATCH 021/166] Fixing simple linting errors in CVC Mostly if statement clauses on a new line --- src/solvers/cvc/cvc_conv.cpp | 67 ++++++++++++++++++---------- src/solvers/cvc/cvc_conv.h | 3 +- src/solvers/cvc/cvc_dec.cpp | 14 +++--- src/solvers/cvc/cvc_prop.cpp | 84 +++++++++++++++++++++++------------- src/solvers/cvc/cvc_prop.h | 5 ++- 5 files changed, 112 insertions(+), 61 deletions(-) diff --git a/src/solvers/cvc/cvc_conv.cpp b/src/solvers/cvc/cvc_conv.cpp index 2a39409d5e3..aa854adf84c 100644 --- a/src/solvers/cvc/cvc_conv.cpp +++ b/src/solvers/cvc/cvc_conv.cpp @@ -58,8 +58,10 @@ Function: cvc_convt::l_get tvt cvc_convt::l_get(literalt l) const { - if(l.is_true()) return tvt(true); - if(l.is_false()) return tvt(false); + if(l.is_true()) + return tvt(true); + if(l.is_false()) + return tvt(false); assert(l.var_no() bool"; + throw "todo typecast1 "+op.type().id_string()+" -> bool"; } } else if(expr.type().id()==ID_signedbv || expr.type().id()==ID_unsignedbv) { - unsigned to_width=unsafe_string2unsigned(id2string(expr.type().get(ID_width))); + unsigned to_width= + unsafe_string2unsigned(id2string(expr.type().get(ID_width))); if(op.type().id()==ID_signedbv) { - unsigned from_width=unsafe_string2unsigned(id2string(op.type().get(ID_width))); + unsigned from_width= + unsafe_string2unsigned(id2string(op.type().get(ID_width))); if(from_width==to_width) convert_expr(op); @@ -585,7 +588,8 @@ void cvc_convt::convert_expr(const exprt &expr) } else if(op.type().id()==ID_unsignedbv) { - unsigned from_width=unsafe_string2unsigned(id2string(op.type().get(ID_width))); + unsigned from_width= + unsafe_string2unsigned(id2string(op.type().get(ID_width))); if(from_width==to_width) convert_expr(op); @@ -633,7 +637,7 @@ void cvc_convt::convert_expr(const exprt &expr) } else { - throw "TODO typecast2 "+op.type().id_string()+ + throw "todo typecast2 "+op.type().id_string()+ " -> "+expr.type().id_string(); } } @@ -644,10 +648,10 @@ void cvc_convt::convert_expr(const exprt &expr) convert_expr(op); } else - throw "TODO typecast3 "+op.type().id_string()+" -> pointer"; + throw "todo typecast3 "+op.type().id_string()+" -> pointer"; } else - throw "TODO typecast4 ? -> "+expr.type().id_string(); + throw "todo typecast4 ? -> "+expr.type().id_string(); } else if(expr.id()==ID_struct) { @@ -666,7 +670,9 @@ void cvc_convt::convert_expr(const exprt &expr) it!=components.end(); it++, i++) { - if(i!=0) out << ", "; + if(i!=0) + out << ", "; + out << it->get(ID_name); out << ":="; convert_expr(expr.operands()[i]); @@ -897,13 +903,16 @@ void cvc_convt::convert_expr(const exprt &expr) if(expr.op0().type().id()==ID_bool) { - if(expr.id()==ID_notequal) out << "NOT ("; + if(expr.id()==ID_notequal) + out << "NOT ("; + out << "("; convert_expr(expr.op0()); out << ") <=> ("; convert_expr(expr.op1()); out << ")"; - if(expr.id()==ID_notequal) out << ")"; + if(expr.id()==ID_notequal) + out << ")"; } else { @@ -960,7 +969,10 @@ void cvc_convt::convert_expr(const exprt &expr) out << ")"; } else - throw "unsupported type for "+expr.id_string()+": "+expr.type().id_string(); + { + throw "unsupported type for "+expr.id_string()+": "+ + expr.type().id_string(); + } } else if(expr.id()==ID_plus) { @@ -1154,7 +1166,10 @@ void cvc_convt::convert_expr(const exprt &expr) out << ")"; } else - throw "unsupported type for "+expr.id_string()+": "+expr.type().id_string(); + { + throw "unsupported type for "+expr.id_string()+": "+ + expr.type().id_string(); + } } else if(expr.id()==ID_with) { @@ -1192,7 +1207,10 @@ void cvc_convt::convert_expr(const exprt &expr) out << ")"; } else - throw "with expects struct or array type, but got "+expr.type().id_string(); + { + throw "with expects struct or array type, but got "+ + expr.type().id_string(); + } } } else if(expr.id()==ID_member) @@ -1216,7 +1234,7 @@ void cvc_convt::convert_expr(const exprt &expr) out << "("; convert_expr(expr.op0()); out << ").object"; - // TODO, this has the wrong type + // TODO(kroening) this has the wrong type } #endif else if(expr.id()==ID_string_constant) @@ -1240,7 +1258,10 @@ void cvc_convt::convert_expr(const exprt &expr) out << "[" << i << ":" << i << "]=0bin1)"; } else - throw "unsupported type for "+expr.id_string()+": "+expr.op0().type().id_string(); + { + throw "unsupported type for "+expr.id_string()+": "+ + expr.op0().type().id_string(); + } } else if(expr.id()==ID_replication) { @@ -1258,7 +1279,8 @@ void cvc_convt::convert_expr(const exprt &expr) for(mp_integer i=0; iget(ID_name); out << ": "; diff --git a/src/solvers/cvc/cvc_conv.h b/src/solvers/cvc/cvc_conv.h index edf9720d0eb..a21009c3c10 100644 --- a/src/solvers/cvc/cvc_conv.h +++ b/src/solvers/cvc/cvc_conv.h @@ -16,8 +16,7 @@ Author: Daniel Kroening, kroening@kroening.com class cvc_convt:public prop_convt { public: - cvc_convt(const namespacet &_ns, - std::ostream &_out): + cvc_convt(const namespacet &_ns, std::ostream &_out): prop_convt(_ns), out(_out), pointer_logic(_ns), diff --git a/src/solvers/cvc/cvc_dec.cpp b/src/solvers/cvc/cvc_dec.cpp index 3b174ac4c2f..b7fd3a2c3e2 100644 --- a/src/solvers/cvc/cvc_dec.cpp +++ b/src/solvers/cvc/cvc_dec.cpp @@ -99,7 +99,7 @@ decision_proceduret::resultt cvc_dect::dec_solve() "cvcl "+temp_out_filename+" > "+temp_result_filename+" 2>&1"; int res=system(command.c_str()); - assert(0 == res); + assert(0==res); status() << "Reading result from CVCL" << eom; @@ -122,7 +122,8 @@ void cvc_dect::read_assert(std::istream &in, std::string &line) { // strip ASSERT line=std::string(line, strlen("ASSERT "), std::string::npos); - if(line=="") return; + if(line=="") + return; // bit-vector if(line[0]=='(') @@ -134,7 +135,8 @@ void cvc_dect::read_assert(std::istream &in, std::string &line) std::string identifier=std::string(line, 1, pos-1); // get value - if(!std::getline(in, line)) return; + if(!std::getline(in, line)) + return; // skip spaces pos=0; @@ -142,7 +144,8 @@ void cvc_dect::read_assert(std::istream &in, std::string &line) // get final ")" std::string::size_type pos2=line.rfind(')'); - if(pos2==std::string::npos) return; + if(pos2==std::string::npos) + return; std::string value=std::string(line, pos, pos2-pos); @@ -162,7 +165,8 @@ void cvc_dect::read_assert(std::istream &in, std::string &line) value=false; } - if(line=="") return; + if(line=="") + return; if(line[0]=='l') { diff --git a/src/solvers/cvc/cvc_prop.cpp b/src/solvers/cvc/cvc_prop.cpp index d941e6c8235..27c499620ea 100644 --- a/src/solvers/cvc/cvc_prop.cpp +++ b/src/solvers/cvc/cvc_prop.cpp @@ -24,7 +24,7 @@ Function: cvc_propt::cvc_propt \*******************************************************************/ -cvc_propt::cvc_propt(std::ostream &_out):out(_out) +explicit cvc_propt::cvc_propt(std::ostream &_out):out(_out) { _no_variables=0; } @@ -47,7 +47,7 @@ cvc_propt::~cvc_propt() /*******************************************************************\ -Function: +Function: cvc_propt::land Inputs: @@ -67,7 +67,7 @@ void cvc_propt::land(literalt a, literalt b, literalt o) /*******************************************************************\ -Function: +Function: cvc_propt::lor Inputs: @@ -87,7 +87,7 @@ void cvc_propt::lor(literalt a, literalt b, literalt o) /*******************************************************************\ -Function: +Function: cvc_propt::lxor Inputs: @@ -107,7 +107,7 @@ void cvc_propt::lxor(literalt a, literalt b, literalt o) /*******************************************************************\ -Function: +Function: cvc_propt::lnand Inputs: @@ -127,7 +127,7 @@ void cvc_propt::lnand(literalt a, literalt b, literalt o) /*******************************************************************\ -Function: +Function: cvc_propt::lnor Inputs: @@ -205,7 +205,8 @@ literalt cvc_propt::land(const bvt &bv) forall_literals(it, bv) { - if(it!=bv.begin()) out << " AND "; + if(it!=bv.begin()) + out << " AND "; out << cvc_literal(*it); } @@ -234,7 +235,8 @@ literalt cvc_propt::lor(const bvt &bv) forall_literals(it, bv) { - if(it!=bv.begin()) out << " OR "; + if(it!=bv.begin()) + out << " OR "; out << cvc_literal(*it); } @@ -257,9 +259,12 @@ Function: cvc_propt::lxor literalt cvc_propt::lxor(const bvt &bv) { - if(bv.empty()) return const_literal(false); - if(bv.size()==1) return bv[0]; - if(bv.size()==2) return lxor(bv[0], bv[1]); + if(bv.empty()) + return const_literal(false); + if(bv.size()==1) + return bv[0]; + if(bv.size()==2) + return lxor(bv[0], bv[1]); literalt literal=const_literal(false); @@ -283,11 +288,16 @@ Function: cvc_propt::land literalt cvc_propt::land(literalt a, literalt b) { - if(a==const_literal(true)) return b; - if(b==const_literal(true)) return a; - if(a==const_literal(false)) return const_literal(false); - if(b==const_literal(false)) return const_literal(false); - if(a==b) return a; + if(a==const_literal(true)) + return b; + if(b==const_literal(true)) + return a; + if(a==const_literal(false)) + return const_literal(false); + if(b==const_literal(false)) + return const_literal(false); + if(a==b) + return a; out << "%% land" << std::endl; @@ -313,11 +323,16 @@ Function: cvc_propt::lor literalt cvc_propt::lor(literalt a, literalt b) { - if(a==const_literal(false)) return b; - if(b==const_literal(false)) return a; - if(a==const_literal(true)) return const_literal(true); - if(b==const_literal(true)) return const_literal(true); - if(a==b) return a; + if(a==const_literal(false)) + return b; + if(b==const_literal(false)) + return a; + if(a==const_literal(true)) + return const_literal(true); + if(b==const_literal(true)) + return const_literal(true); + if(a==b) + return a; out << "%% lor" << std::endl; @@ -343,10 +358,14 @@ Function: cvc_propt::lxor literalt cvc_propt::lxor(literalt a, literalt b) { - if(a==const_literal(false)) return b; - if(b==const_literal(false)) return a; - if(a==const_literal(true)) return !b; - if(b==const_literal(true)) return !a; + if(a==const_literal(false)) + return b; + if(b==const_literal(false)) + return a; + if(a==const_literal(true)) + return !b; + if(b==const_literal(true)) + return !a; out << "%% lxor" << std::endl; @@ -440,9 +459,12 @@ Function: cvc_propt::lselect literalt cvc_propt::lselect(literalt a, literalt b, literalt c) { - if(a==const_literal(true)) return b; - if(a==const_literal(false)) return c; - if(b==c) return b; + if(a==const_literal(true)) + return b; + if(a==const_literal(false)) + return c; + if(b==c) + return b; out << "%% lselect" << std::endl; @@ -512,7 +534,8 @@ Function: cvc_propt::lcnf void cvc_propt::lcnf(const bvt &bv) { - if(bv.empty()) return; + if(bv.empty()) + return; bvt new_bv; std::set s; @@ -537,7 +560,8 @@ void cvc_propt::lcnf(const bvt &bv) for(bvt::const_iterator it=new_bv.begin(); it!=new_bv.end(); it++) { - if(it!=new_bv.begin()) out << " OR "; + if(it!=new_bv.begin()) + out << " OR "; out << cvc_literal(*it); } diff --git a/src/solvers/cvc/cvc_prop.h b/src/solvers/cvc/cvc_prop.h index 2222b8c9e29..cc83906a3f7 100644 --- a/src/solvers/cvc/cvc_prop.h +++ b/src/solvers/cvc/cvc_prop.h @@ -18,7 +18,7 @@ Author: Daniel Kroening, kroening@kroening.com class cvc_propt:virtual public propt { public: - cvc_propt(std::ostream &_out); + explicit cvc_propt(std::ostream &_out); virtual ~cvc_propt(); virtual void land(literalt a, literalt b, literalt o); @@ -52,7 +52,8 @@ class cvc_propt:virtual public propt virtual tvt l_get(literalt literal) const { unsigned v=literal.var_no(); - if(v>=assignment.size()) return tvt(tvt::tv_enumt::TV_UNKNOWN); + if(v>=assignment.size()) + return tvt(tvt::tv_enumt::TV_UNKNOWN); tvt r=assignment[v]; return literal.sign()?!r:r; } From 01967341c296ba88b303a4246c41b33b4be67382 Mon Sep 17 00:00:00 2001 From: thk123 Date: Tue, 10 Jan 2017 16:31:30 +0000 Subject: [PATCH 022/166] Split convert_expr into a collection of smaller functions The convert_expr function was over 600 lines as so triggered the linter. I have taken each substantial if clause and put them into individual functions. The body of the function should remain unchanged. Future improvements could include making it more functional in style so that it isn't modifying the member variable out and instead returning somehting. Also could use a dictionary of irep_idt->function to make the function fewer lines and easier to see which types are handled. --- src/solvers/cvc/cvc_conv.cpp | 944 ++++++++++++++++++++--------------- src/solvers/cvc/cvc_conv.h | 9 + 2 files changed, 559 insertions(+), 394 deletions(-) diff --git a/src/solvers/cvc/cvc_conv.cpp b/src/solvers/cvc/cvc_conv.cpp index aa854adf84c..8102f86754d 100644 --- a/src/solvers/cvc/cvc_conv.cpp +++ b/src/solvers/cvc/cvc_conv.cpp @@ -68,6 +68,543 @@ tvt cvc_convt::l_get(literalt l) const /*******************************************************************\ +Function: cvc_convt::convert_binary_expr + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void cvc_convt::convert_binary_expr(const exprt &expr, const exprt &op) +{ + unsigned to_width= + unsafe_string2unsigned(id2string(expr.type().get(ID_width))); + + if(op.type().id()==ID_signedbv) + { + unsigned from_width= + unsafe_string2unsigned(id2string(op.type().get(ID_width))); + + if(from_width==to_width) + convert_expr(op); + else if(from_width1) + { + out << "(0bin"; + + for(unsigned i=1; i "+expr.type().id_string(); + } +} + +/*******************************************************************\ + +Function: cvc_convt::convert_constant_expr + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void cvc_convt::convert_constant_expr(const exprt &expr) +{ + if(expr.type().id()==ID_unsignedbv || + expr.type().id()==ID_signedbv || + expr.type().id()==ID_bv) + { + const irep_idt &value=expr.get(ID_value); + + if(value.size()==8 || + value.size()==16 || + value.size()==32 || + value.size()==64) + { + std::size_t w=value.size()/4; + + mp_integer i=binary2integer(id2string(value), false); + std::string hex=integer2string(i, 16); + + while(hex.size()=2) + { + if(expr.type().id()==ID_unsignedbv || + expr.type().id()==ID_signedbv) + { + out << "BVPLUS(" << expr.type().get(ID_width); + + forall_operands(it, expr) + { + out << ", "; + convert_expr(*it); + } + + out << ")"; + } + else if(expr.type().id()==ID_pointer) + { + if(expr.operands().size()!=2) + throw "pointer arithmetic with more than two operands"; + + const exprt *p, *i; + + if(expr.op0().type().id()==ID_pointer) + { + p=&expr.op0(); + i=&expr.op1(); + } + else if(expr.op1().type().id()==ID_pointer) + { + p=&expr.op1(); + i=&expr.op0(); + } + else + throw "unexpected mixture in pointer arithmetic"; + + out << "(LET P: " << cvc_pointer_type() << " = "; + convert_expr(*p); + out << " IN P WITH .offset:=BVPLUS(" + << config.ansi_c.pointer_width + << ", P.offset, "; + convert_expr(*i); + out << "))"; + } + else + throw "unsupported type for +: "+expr.type().id_string(); + } + else if(expr.operands().size()==1) + { + convert_expr(expr.op0()); + } + else + assert(false); +} + +/*******************************************************************\ + +Function: cvc_convt::convert_typecast_expr + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void cvc_convt::convert_typecast_expr(const exprt &expr) +{ + assert(expr.operands().size()==1); + const exprt &op=expr.op0(); + + if(expr.type().id()==ID_bool) + { + if(op.type().id()==ID_signedbv || + op.type().id()==ID_unsignedbv || + op.type().id()==ID_pointer) + { + convert_expr(op); + out << "/="; + convert_expr(gen_zero(op.type())); + } + else + { + throw "todo typecast1 "+op.type().id_string()+" -> bool"; + } + } + else if(expr.type().id()==ID_signedbv || + expr.type().id()==ID_unsignedbv) + { + convert_binary_expr(expr, op); + } + else if(expr.type().id()==ID_pointer) + { + if(op.type().id()==ID_pointer) + { + convert_expr(op); + } + else + throw "todo typecast3 "+op.type().id_string()+" -> pointer"; + } + else + throw "todo typecast4 ? -> "+expr.type().id_string(); +} + +/*******************************************************************\ + +Function: cvc_convt::convert_struct_expr + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void cvc_convt::convert_struct_expr(const exprt &expr) +{ + out << "(# "; + + const struct_typet &struct_type=to_struct_type(expr.type()); + + const struct_typet::componentst &components= + struct_type.components(); + + assert(components.size()==expr.operands().size()); + + unsigned i=0; + for(const struct_union_typet::componentt &component : components) + { + if(i!=0) + out << ", "; + + out << component.get(ID_name); + out << ":="; + convert_expr(expr.operands()[i]); + ++i; + } + + out << " #)"; +} + +/*******************************************************************\ + +Function: cvc_convt::convert_equality_expr + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void cvc_convt::convert_equality_expr(const exprt &expr) +{ + assert(expr.operands().size()==2); + assert(expr.op0().type()==expr.op1().type()); + + if(expr.op0().type().id()==ID_bool) + { + if(expr.id()==ID_notequal) + out << "NOT ("; + + out << "("; + convert_expr(expr.op0()); + out << ") <=> ("; + convert_expr(expr.op1()); + out << ")"; + if(expr.id()==ID_notequal) + out << ")"; + } + else + { + out << "("; + convert_expr(expr.op0()); + out << ")"; + out << (expr.id()==ID_equal?"=":"/="); + out << "("; + convert_expr(expr.op1()); + out << ")"; + } +} + +/*******************************************************************\ + +Function: cvc_convt::convert_comparison_expr + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void cvc_convt::convert_comparison_expr(const exprt &expr) +{ + assert(expr.operands().size()==2); + + const typet &op_type=expr.op0().type(); + + if(op_type.id()==ID_unsignedbv) + { + if(expr.id()==ID_le) + out << "BVLE"; + else if(expr.id()==ID_lt) + out << "BVLT"; + else if(expr.id()==ID_ge) + out << "BVGE"; + else if(expr.id()==ID_gt) + out << "BVGT"; + + out << "("; + convert_expr(expr.op0()); + out << ", "; + convert_expr(expr.op1()); + out << ")"; + } + else if(op_type.id()==ID_signedbv) + { + if(expr.id()==ID_le) + out << "SBVLE"; + else if(expr.id()==ID_lt) + out << "SBVLT"; + else if(expr.id()==ID_ge) + out << "SBVGE"; + else if(expr.id()==ID_gt) + out << "SBVGT"; + + out << "("; + convert_expr(expr.op0()); + out << ", "; + convert_expr(expr.op1()); + out << ")"; + } + else + { + throw "unsupported type for "+expr.id_string()+": "+ + expr.type().id_string(); + } +} + +/*******************************************************************\ + +Function: cvc_convt::convert_minus_expr + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void cvc_convt::convert_minus_expr(const exprt &expr) +{ + if(expr.operands().size()==2) + { + if(expr.type().id()==ID_unsignedbv || + expr.type().id()==ID_signedbv) + { + out << "BVSUB(" << expr.type().get(ID_width) << ", "; + convert_expr(expr.op0()); + out << ", "; + convert_expr(expr.op1()); + out << ")"; + } + else + throw "unsupported type for -: "+expr.type().id_string(); + } + else if(expr.operands().size()==1) + { + convert_expr(expr.op0()); + } + else + assert(false); +} + +/*******************************************************************\ + +Function: cvc_convt::convert_with_expr + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void cvc_convt::convert_with_expr(const exprt &expr) +{ + assert(expr.operands().size()>=1); + out << "("; + convert_expr(expr.op0()); + out << ")"; + + for(unsigned i=1; i bool"; - } - } - else if(expr.type().id()==ID_signedbv || - expr.type().id()==ID_unsignedbv) - { - unsigned to_width= - unsafe_string2unsigned(id2string(expr.type().get(ID_width))); - - if(op.type().id()==ID_signedbv) - { - unsigned from_width= - unsafe_string2unsigned(id2string(op.type().get(ID_width))); - - if(from_width==to_width) - convert_expr(op); - else if(from_width1) - { - out << "(0bin"; - - for(unsigned i=1; i "+expr.type().id_string(); - } - } - else if(expr.type().id()==ID_pointer) - { - if(op.type().id()==ID_pointer) - { - convert_expr(op); - } - else - throw "todo typecast3 "+op.type().id_string()+" -> pointer"; - } - else - throw "todo typecast4 ? -> "+expr.type().id_string(); + convert_typecast_expr(expr); } else if(expr.id()==ID_struct) { - out << "(# "; - - const struct_typet &struct_type=to_struct_type(expr.type()); - - const struct_typet::componentst &components= - struct_type.components(); - - assert(components.size()==expr.operands().size()); - - unsigned i=0; - for(struct_typet::componentst::const_iterator - it=components.begin(); - it!=components.end(); - it++, i++) - { - if(i!=0) - out << ", "; - - out << it->get(ID_name); - out << ":="; - convert_expr(expr.operands()[i]); - } - - out << " #)"; + convert_struct_expr(expr); } else if(expr.id()==ID_constant) { - if(expr.type().id()==ID_unsignedbv || - expr.type().id()==ID_signedbv || - expr.type().id()==ID_bv) - { - const irep_idt &value=expr.get(ID_value); - - if(value.size()==8 || - value.size()==16 || - value.size()==32 || - value.size()==64) - { - std::size_t w=value.size()/4; - - mp_integer i=binary2integer(id2string(value), false); - std::string hex=integer2string(i, 16); - - while(hex.size() ("; - convert_expr(expr.op1()); - out << ")"; - if(expr.id()==ID_notequal) - out << ")"; - } - else - { - out << "("; - convert_expr(expr.op0()); - out << ")"; - out << (expr.id()==ID_equal?"=":"/="); - out << "("; - convert_expr(expr.op1()); - out << ")"; - } + convert_equality_expr(expr); } else if(expr.id()==ID_le || expr.id()==ID_lt || expr.id()==ID_ge || expr.id()==ID_gt) { - assert(expr.operands().size()==2); - - const typet &op_type=expr.op0().type(); - - if(op_type.id()==ID_unsignedbv) - { - if(expr.id()==ID_le) - out << "BVLE"; - else if(expr.id()==ID_lt) - out << "BVLT"; - else if(expr.id()==ID_ge) - out << "BVGE"; - else if(expr.id()==ID_gt) - out << "BVGT"; - - out << "("; - convert_expr(expr.op0()); - out << ", "; - convert_expr(expr.op1()); - out << ")"; - } - else if(op_type.id()==ID_signedbv) - { - if(expr.id()==ID_le) - out << "SBVLE"; - else if(expr.id()==ID_lt) - out << "SBVLT"; - else if(expr.id()==ID_ge) - out << "SBVGE"; - else if(expr.id()==ID_gt) - out << "SBVGT"; - - out << "("; - convert_expr(expr.op0()); - out << ", "; - convert_expr(expr.op1()); - out << ")"; - } - else - { - throw "unsupported type for "+expr.id_string()+": "+ - expr.type().id_string(); - } + convert_comparison_expr(expr); } else if(expr.id()==ID_plus) { - if(expr.operands().size()>=2) - { - if(expr.type().id()==ID_unsignedbv || - expr.type().id()==ID_signedbv) - { - out << "BVPLUS(" << expr.type().get(ID_width); - - forall_operands(it, expr) - { - out << ", "; - convert_expr(*it); - } - - out << ")"; - } - else if(expr.type().id()==ID_pointer) - { - if(expr.operands().size()!=2) - throw "pointer arithmetic with more than two operands"; - - const exprt *p, *i; - - if(expr.op0().type().id()==ID_pointer) - { - p=&expr.op0(); - i=&expr.op1(); - } - else if(expr.op1().type().id()==ID_pointer) - { - p=&expr.op1(); - i=&expr.op0(); - } - else - throw "unexpected mixture in pointer arithmetic"; - - out << "(LET P: " << cvc_pointer_type() << " = "; - convert_expr(*p); - out << " IN P WITH .offset:=BVPLUS(" - << config.ansi_c.pointer_width - << ", P.offset, "; - convert_expr(*i); - out << "))"; - } - else - throw "unsupported type for +: "+expr.type().id_string(); - } - else if(expr.operands().size()==1) - { - convert_expr(expr.op0()); - } - else - assert(false); + convert_plus_expr(expr); } else if(expr.id()==ID_minus) { - if(expr.operands().size()==2) - { - if(expr.type().id()==ID_unsignedbv || - expr.type().id()==ID_signedbv) - { - out << "BVSUB(" << expr.type().get(ID_width) << ", "; - convert_expr(expr.op0()); - out << ", "; - convert_expr(expr.op1()); - out << ")"; - } - else - throw "unsupported type for -: "+expr.type().id_string(); - } - else if(expr.operands().size()==1) - { - convert_expr(expr.op0()); - } - else - assert(false); + convert_minus_expr(expr); } else if(expr.id()==ID_div) { @@ -1173,45 +1367,7 @@ void cvc_convt::convert_expr(const exprt &expr) } else if(expr.id()==ID_with) { - assert(expr.operands().size()>=1); - out << "("; - convert_expr(expr.op0()); - out << ")"; - - for(unsigned i=1; i Date: Fri, 20 Jan 2017 14:22:40 +0000 Subject: [PATCH 023/166] Replaced loop with simpler expression Previously we were piping a number of zeros inside a for loop. This can be simply done use the string constructor. --- src/solvers/cvc/cvc_conv.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/solvers/cvc/cvc_conv.cpp b/src/solvers/cvc/cvc_conv.cpp index 8102f86754d..a5cfa98aa78 100644 --- a/src/solvers/cvc/cvc_conv.cpp +++ b/src/solvers/cvc/cvc_conv.cpp @@ -8,6 +8,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include #include @@ -114,8 +115,8 @@ void cvc_convt::convert_binary_expr(const exprt &expr, const exprt &op) { out << "(0bin"; - for(unsigned i=from_width; i from_width) + out << std::string(to_width-from_width, '0'); out << " @ "; @@ -136,8 +137,8 @@ void cvc_convt::convert_binary_expr(const exprt &expr, const exprt &op) { out << "(0bin"; - for(unsigned i=1; i 1) + out << std::string(to_width-1, '0'); out << " @ "; From 704ed4f263a9abbe9e9832e69c3b7a5e4fae293b Mon Sep 17 00:00:00 2001 From: thk123 Date: Fri, 20 Jan 2017 14:24:05 +0000 Subject: [PATCH 024/166] Replaced a for loop with a ranged based for loop --- src/solvers/cvc/cvc_conv.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/solvers/cvc/cvc_conv.cpp b/src/solvers/cvc/cvc_conv.cpp index a5cfa98aa78..6e01448d5e2 100644 --- a/src/solvers/cvc/cvc_conv.cpp +++ b/src/solvers/cvc/cvc_conv.cpp @@ -1619,17 +1619,15 @@ void cvc_convt::convert_type(const typet &type) const struct_typet::componentst &components= struct_type.components(); - for(struct_typet::componentst::const_iterator - it=components.begin(); - it!=components.end(); - it++) + for(struct_typet::componentt component : components) { - if(it!=components.begin()) + if(component!=components.front()) out << ","; + out << " "; - out << it->get(ID_name); + out << component.get_name(); out << ": "; - convert_type(it->type()); + convert_type(component.type()); } out << " #]"; From 0f80ad46d5770bcd3da80162286d37ccd8551b6f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 23 Sep 2016 11:42:53 +0100 Subject: [PATCH 025/166] Parse the exception table --- src/java_bytecode/java_bytecode_parse_tree.h | 6 +++++- src/java_bytecode/java_bytecode_parser.cpp | 15 +++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index 35e6b768b41..87b55b27b4a 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -82,8 +82,12 @@ class java_bytecode_parse_treet return instructions.back(); } - class exceptiont + struct exceptiont { + std::size_t start_pc; + std::size_t end_pc; + std::size_t handler_pc; + symbol_typet catch_type; }; typedef std::vector exception_tablet; diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 2f79c7bce89..8a6483abef1 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -968,13 +968,20 @@ void java_bytecode_parsert::rmethod_attribute(methodt &method) rbytecode(method.instructions); u2 exception_table_length=read_u2(); + method.exception_table.resize(exception_table_length); for(std::size_t e=0; e Date: Mon, 23 Jan 2017 15:37:22 +0000 Subject: [PATCH 026/166] Make the method object, and thus the exception table, available to dominator analysis --- .../java_bytecode_convert_method_class.h | 3 ++- .../java_local_variable_table.cpp | 24 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index 8a456d0a99a..003492355d1 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -129,7 +129,8 @@ class java_bytecode_convert_methodt:public messaget public: typedef std::map address_mapt; - typedef cfg_dominators_templatet + typedef std::pair method_with_amapt; + typedef cfg_dominators_templatet java_cfg_dominatorst; protected: diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index d70fd18264e..ad3590342ad 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -20,18 +20,19 @@ Author: Chris Smowton, chris.smowton@diffblue.com template struct procedure_local_cfg_baset< T, - const java_bytecode_convert_methodt::address_mapt, + java_bytecode_convert_methodt::method_with_amapt, unsigned> : public graph > { - typedef java_bytecode_convert_methodt::address_mapt address_mapt; + typedef java_bytecode_convert_methodt::method_with_amapt method_with_amapt; typedef std::map entry_mapt; entry_mapt entry_map; procedure_local_cfg_baset() {} - void operator()(const address_mapt& amap) + void operator()(const method_with_amapt& args) { + const auto& amap=args.second; for(const auto& inst : amap) { // Map instruction PCs onto node indices: @@ -44,19 +45,21 @@ struct procedure_local_cfg_baset< for(auto succ : inst.second.successors) this->add_edge(entry_map.at(inst.first), entry_map.at(succ)); } + // Add edges declared in the exception table, which don't figure + // in the address map successors/predecessors as yet. } - unsigned get_first_node(const address_mapt& amap) const + unsigned get_first_node(const method_with_amapt& args) const { - return amap.begin()->first; + return args.second.begin()->first; } - unsigned get_last_node(const address_mapt& amap) const + unsigned get_last_node(const method_with_amapt& args) const { - return (--amap.end())->first; + return (--args.second.end())->first; } - unsigned nodes_empty(const address_mapt& amap) const + unsigned nodes_empty(const method_with_amapt& args) const { - return amap.empty(); + return args.second.empty(); } }; @@ -744,7 +747,8 @@ void java_bytecode_convert_methodt::setup_local_variables( { // Compute CFG dominator tree java_cfg_dominatorst dominator_analysis; - dominator_analysis(amap); + method_with_amapt dominator_args(m,amap); + dominator_analysis(dominator_args); // Find out which local variable table entries should be merged: // Wrap each entry so we have somewhere to record live ranges with holes: From 974ee14f839ec32b8d472d468bda4619da16b483 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 23 Sep 2016 12:05:50 +0100 Subject: [PATCH 027/166] Add exception edges to the CFG for dominator computation --- .../java_local_variable_table.cpp | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index ad3590342ad..e04df343a80 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -32,6 +32,7 @@ struct procedure_local_cfg_baset< void operator()(const method_with_amapt& args) { + const auto &method=args.first; const auto& amap=args.second; for(const auto& inst : amap) { @@ -47,6 +48,29 @@ struct procedure_local_cfg_baset< } // Add edges declared in the exception table, which don't figure // in the address map successors/predecessors as yet. + for(const auto& table_entry : method.exception_table) + { + auto findit=amap.find(table_entry.start_pc); + assert(findit!=amap.end() && + "Exception table entry doesn't point to an instruction?"); + for(; findit->firstsecond; + if(thisinst.successors.size()==1 && + *thisinst.successors.begin()==succit->first) + { + this->add_edge( + entry_map.at(findit->first), + entry_map.at(table_entry.handler_pc)); + } + } + } } unsigned get_first_node(const method_with_amapt& args) const From bcbb13a1b525c7628d3b08a400939ea92b7be312 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 23 Jan 2017 16:38:45 +0000 Subject: [PATCH 028/166] Style fixes for local variable table --- .../java_local_variable_table.cpp | 89 ++++++++++--------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index e04df343a80..dd9e8eee4d1 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -30,25 +30,26 @@ struct procedure_local_cfg_baset< procedure_local_cfg_baset() {} - void operator()(const method_with_amapt& args) + void operator()(const method_with_amapt &args) { const auto &method=args.first; - const auto& amap=args.second; - for(const auto& inst : amap) + const auto &amap=args.second; + for(const auto &inst : amap) { // Map instruction PCs onto node indices: entry_map[inst.first]=this->add_node(); // Map back: (*this)[entry_map[inst.first]].PC=inst.first; } - for(const auto& inst : amap) + // Add edges declared in the address map: + for(const auto &inst : amap) { for(auto succ : inst.second.successors) this->add_edge(entry_map.at(inst.first), entry_map.at(succ)); } - // Add edges declared in the exception table, which don't figure - // in the address map successors/predecessors as yet. - for(const auto& table_entry : method.exception_table) + // Next, add edges declared in the exception table, which + // don't figure in the address map successors/predecessors as yet: + for(const auto &table_entry : method.exception_table) { auto findit=amap.find(table_entry.start_pc); assert(findit!=amap.end() && @@ -61,9 +62,9 @@ struct procedure_local_cfg_baset< ++succit; if(succit==amap.end()) continue; - const auto& thisinst=findit->second; + const auto &thisinst=findit->second; if(thisinst.successors.size()==1 && - *thisinst.successors.begin()==succit->first) + thisinst.successors.back()==succit->first) { this->add_edge( entry_map.at(findit->first), @@ -73,15 +74,15 @@ struct procedure_local_cfg_baset< } } - unsigned get_first_node(const method_with_amapt& args) const + unsigned get_first_node(const method_with_amapt &args) const { return args.second.begin()->first; } - unsigned get_last_node(const method_with_amapt& args) const + unsigned get_last_node(const method_with_amapt &args) const { return (--args.second.end())->first; } - unsigned nodes_empty(const method_with_amapt& args) const + unsigned nodes_empty(const method_with_amapt &args) const { return args.second.empty(); } @@ -102,8 +103,8 @@ typedef java_bytecode_convert_methodt::java_cfg_dominatorst // Comparators for local variables: static bool lt_index( - const local_variable_with_holest& a, - const local_variable_with_holest& b) + const local_variable_with_holest &a, + const local_variable_with_holest &b) { return a.var.index& result) { if(!result.insert(start).second) @@ -183,7 +184,7 @@ Function: is_store_to_slot \*******************************************************************/ static bool is_store_to_slot( - const java_bytecode_convert_methodt::instructiont& inst, + const java_bytecode_convert_methodt::instructiont &inst, unsigned slotidx) { const std::string prevstatement=id2string(inst.statement); @@ -194,7 +195,7 @@ static bool is_store_to_slot( if(inst.args.size()==1) { // Store with an argument: - const auto& arg=inst.args[0]; + const auto &arg=inst.args[0]; storeslot=id2string(to_constant_expr(arg).get_value()); } else @@ -222,7 +223,7 @@ Function: maybe_add_hole \*******************************************************************/ static void maybe_add_hole( - local_variable_with_holest& var, + local_variable_with_holest &var, unsigned from, unsigned to) { @@ -298,9 +299,9 @@ static void populate_predecessor_map( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, const std::vector& live_variable_at_address, - const address_mapt& amap, - predecessor_mapt& predecessor_map, - message_handlert& msg_handler) + const address_mapt &amap, + predecessor_mapt &predecessor_map, + message_handlert &msg_handler) { messaget msg(msg_handler); for(auto it=firstvar, itend=varlimit; it!=itend; ++it) @@ -412,7 +413,7 @@ Function: get_common_dominator static unsigned get_common_dominator( const std::set& merge_vars, - const java_cfg_dominatorst& dominator_analysis) + const java_cfg_dominatorst &dominator_analysis) { assert(!merge_vars.empty()); @@ -426,9 +427,9 @@ static unsigned get_common_dominator( std::vector candidate_dominators; for(auto v : merge_vars) { - const auto& dominator_nodeidx= + const auto &dominator_nodeidx= dominator_analysis.cfg.entry_map.at(v->var.start_pc); - const auto& this_var_doms= + const auto &this_var_doms= dominator_analysis.cfg[dominator_nodeidx].dominators; for(const auto this_var_dom : this_var_doms) if(this_var_dom<=first_pc) @@ -478,7 +479,7 @@ Function: populate_live_range_holes \*******************************************************************/ static void populate_live_range_holes( - local_variable_with_holest& merge_into, + local_variable_with_holest &merge_into, const std::set& merge_vars, unsigned expanded_live_range_start) { @@ -516,10 +517,10 @@ Function: merge_variable_table_entries \*******************************************************************/ static void merge_variable_table_entries( - local_variable_with_holest& merge_into, + local_variable_with_holest &merge_into, const std::set& merge_vars, - const java_cfg_dominatorst& dominator_analysis, - std::ostream& debug_out) + const java_cfg_dominatorst &dominator_analysis, + std::ostream &debug_out) { // Because we need a lexically-scoped declaration, // we must have the merged variable @@ -554,7 +555,7 @@ static void merge_variable_table_entries( #endif // Nuke the now-subsumed var-table entries: - for(auto& v : merge_vars) + for(auto &v : merge_vars) if(v!=&merge_into) v->var.length=0; } @@ -584,8 +585,8 @@ Function: find_initialisers_for_slot void java_bytecode_convert_methodt::find_initialisers_for_slot( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, - const address_mapt& amap, - const java_cfg_dominatorst& dominator_analysis) + const address_mapt &amap, + const java_cfg_dominatorst &dominator_analysis) { // Build a simple map from instruction PC to the variable // live in this slot at that PC, and a map from each variable @@ -609,7 +610,7 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( // Now merge vartable entries according to the predecessor_map: // Take the transitive closure of the predecessor map: - for(auto& kv : predecessor_map) + for(auto &kv : predecessor_map) { std::set closed_preds; gather_transitive_predecessors(kv.first, predecessor_map, closed_preds); @@ -636,7 +637,7 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( if(findit==predecessor_map.end()) continue; - const auto& merge_vars=findit->second; + const auto &merge_vars=findit->second; assert(merge_vars.size()>=2); merge_variable_table_entries( @@ -665,8 +666,8 @@ Function: walk_to_next_index \*******************************************************************/ static void walk_to_next_index( - local_variable_table_with_holest::iterator& it1, - local_variable_table_with_holest::iterator& it2, + local_variable_table_with_holest::iterator &it1, + local_variable_table_with_holest::iterator &it2, local_variable_table_with_holest::iterator itend) { if(it2==itend) @@ -698,9 +699,9 @@ Function: find_initialisers \*******************************************************************/ void java_bytecode_convert_methodt::find_initialisers( - local_variable_table_with_holest& vars, - const address_mapt& amap, - const java_cfg_dominatorst& dominator_analysis) + local_variable_table_with_holest &vars, + const address_mapt &amap, + const java_cfg_dominatorst &dominator_analysis) { // Sort table entries by local slot index: std::sort(vars.begin(), vars.end(), lt_index); @@ -766,18 +767,18 @@ Function: setup_local_variables \*******************************************************************/ void java_bytecode_convert_methodt::setup_local_variables( - const methodt& m, - const address_mapt& amap) + const methodt &m, + const address_mapt &amap) { // Compute CFG dominator tree java_cfg_dominatorst dominator_analysis; - method_with_amapt dominator_args(m,amap); + method_with_amapt dominator_args(m, amap); dominator_analysis(dominator_args); // Find out which local variable table entries should be merged: // Wrap each entry so we have somewhere to record live ranges with holes: std::vector vars_with_holes; - for(const auto& v : m.local_variable_table) + for(const auto &v : m.local_variable_table) vars_with_holes.push_back({v, {}}); // Merge variable records: From 031001b3d32272ddf9c254875561b83b332d9081 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 23 Jan 2017 17:32:38 +0000 Subject: [PATCH 029/166] Make JAR/zip support optional in regression tests With cbmc-java regression tests enabled by default, the absence of optional JAR/zip file support should not cause regression tests to fail. --- regression/cbmc-java/jar-file1/test.desc | 4 ++-- regression/cbmc-java/jar-file2/test.desc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/regression/cbmc-java/jar-file1/test.desc b/regression/cbmc-java/jar-file1/test.desc index 0203b47faa3..b50d83b8645 100644 --- a/regression/cbmc-java/jar-file1/test.desc +++ b/regression/cbmc-java/jar-file1/test.desc @@ -1,8 +1,8 @@ CORE some_jar.jar -^EXIT=0$ +^EXIT=\(0\|6\)$ ^SIGNAL=0$ -^VERIFICATION SUCCESSFUL$ +^\(VERIFICATION SUCCESSFUL\|No support for reading JAR files\)$ -- ^warning: ignoring diff --git a/regression/cbmc-java/jar-file2/test.desc b/regression/cbmc-java/jar-file2/test.desc index a40daf9fb5f..fb9e05dad2c 100644 --- a/regression/cbmc-java/jar-file2/test.desc +++ b/regression/cbmc-java/jar-file2/test.desc @@ -1,8 +1,8 @@ CORE jar-file2.jar --main-class some_class -^EXIT=10$ +^EXIT=\(10\|6\)$ ^SIGNAL=0$ -^VERIFICATION FAILED$ +^\(VERIFICATION FAILED\|No support for reading JAR files\)$ -- ^warning: ignoring From 017d854c35c7c0842161a6638e8b448e8ce895e0 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 23 Jan 2017 17:14:01 +0000 Subject: [PATCH 030/166] fixup! Consistently resize instead of just reserving in codet classes --- src/analyses/flow_insensitive_analysis.cpp | 7 +++---- src/cpp/cpp_typecheck_compound_type.cpp | 5 +---- src/goto-instrument/goto_program2code.cpp | 2 +- src/goto-programs/goto_convert.cpp | 2 +- src/goto-programs/goto_convert_functions.cpp | 7 +++---- src/goto-programs/goto_convert_new_switch_case.cpp | 2 +- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/analyses/flow_insensitive_analysis.cpp b/src/analyses/flow_insensitive_analysis.cpp index b2dbb5fe930..0f9e15991f0 100644 --- a/src/analyses/flow_insensitive_analysis.cpp +++ b/src/analyses/flow_insensitive_analysis.cpp @@ -341,15 +341,14 @@ bool flow_insensitive_analysis_baset::do_function_call( goto_programt temp; + exprt rhs=side_effect_expr_nondett(code.lhs().type()); + goto_programt::targett r=temp.add_instruction(); r->make_return(); - r->code=code_returnt(); + r->code=code_returnt(rhs); r->function=f_it->first; r->location_number=0; - exprt rhs=side_effect_expr_nondett(code.lhs().type()); - r->code.move_to_operands(rhs); - goto_programt::targett t=temp.add_instruction(END_FUNCTION); t->code.set(ID_identifier, code.function()); t->function=f_it->first; diff --git a/src/cpp/cpp_typecheck_compound_type.cpp b/src/cpp/cpp_typecheck_compound_type.cpp index f05e0ef321b..83dea257569 100644 --- a/src/cpp/cpp_typecheck_compound_type.cpp +++ b/src/cpp/cpp_typecheck_compound_type.cpp @@ -692,10 +692,7 @@ void cpp_typecheckt::typecheck_compound_declarator( namespacet(symbol_table).lookup(args[i].get(ID_C_identifier)).symbol_expr()); } - code_returnt code_return; - code_return.return_value() = expr_call; - - func_symb.value = code_return; + func_symb.value=code_returnt(expr_call); } else { diff --git a/src/goto-instrument/goto_program2code.cpp b/src/goto-instrument/goto_program2code.cpp index e1698675af4..e5434201198 100644 --- a/src/goto-instrument/goto_program2code.cpp +++ b/src/goto-instrument/goto_program2code.cpp @@ -556,7 +556,7 @@ goto_programt::const_targett goto_program2codet::convert_return( goto_programt::const_targett upper_bound, codet &dest) { - code_returnt ret=to_code_return(target->code); + const code_returnt &ret=to_code_return(target->code); // add return instruction unless original code was missing a return if(!ret.has_return_value() || diff --git a/src/goto-programs/goto_convert.cpp b/src/goto-programs/goto_convert.cpp index b4f4385a314..c3f413a8600 100644 --- a/src/goto-programs/goto_convert.cpp +++ b/src/goto-programs/goto_convert.cpp @@ -1622,7 +1622,7 @@ void goto_convertt::convert_return( // remove void-typed return value if(!result_is_used) - new_code.operands().resize(0); + new_code.return_value().make_nil(); } if(targets.has_return_value) diff --git a/src/goto-programs/goto_convert_functions.cpp b/src/goto-programs/goto_convert_functions.cpp index c4ec6ea43c7..8a92d50445c 100644 --- a/src/goto-programs/goto_convert_functions.cpp +++ b/src/goto-programs/goto_convert_functions.cpp @@ -186,13 +186,12 @@ void goto_convert_functionst::add_return( #endif + side_effect_expr_nondett rhs(f.type.return_type()); + goto_programt::targett t=f.body.add_instruction(); t->make_return(); - t->code=code_returnt(); + t->code=code_returnt(rhs); t->source_location=source_location; - - side_effect_expr_nondett rhs(f.type.return_type()); - t->code.move_to_operands(rhs); } /*******************************************************************\ diff --git a/src/goto-programs/goto_convert_new_switch_case.cpp b/src/goto-programs/goto_convert_new_switch_case.cpp index bc6ebcc05b6..83b82b034c8 100644 --- a/src/goto-programs/goto_convert_new_switch_case.cpp +++ b/src/goto-programs/goto_convert_new_switch_case.cpp @@ -1508,7 +1508,7 @@ void goto_convertt::convert_return( // remove void-typed return value if(!result_is_used) - new_code.operands().resize(0); + new_code.return_value().make_nil(); } if(targets.has_return_value) From 60a1fb2262e124c26e82523856b16cba912f8b9b Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 31 Aug 2016 09:24:54 +0100 Subject: [PATCH 031/166] Don't reference CPROVER_memory from Java code. Fixes #197. goto-symex's value-set analysis can reach the conclusion that an integer may be cast to a pointer, and so generate a reference to the __CPROVER_memory symbol. This is invalid in Java however, since the symbol is not defined and of course Java cannot express dereferencing a non-pointer type. This change disables generation of __CPROVER_memory references when a Java-typed entry point is found. I couldn't provide a test case against master at this time however because the examples in both of the above bugs now succeed against master, presumably because value-set analysis has been improved and is harder to confuse into introducing a pointer-to-int cast. --- src/cbmc/bmc.cpp | 7 +++++++ src/goto-symex/goto_symex.h | 3 +++ src/goto-symex/symex_dereference.cpp | 5 +++-- src/pointer-analysis/value_set_dereference.cpp | 8 +++++++- src/pointer-analysis/value_set_dereference.h | 7 +++++-- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/cbmc/bmc.cpp b/src/cbmc/bmc.cpp index f3b3c43b375..c320a22328c 100644 --- a/src/cbmc/bmc.cpp +++ b/src/cbmc/bmc.cpp @@ -16,6 +16,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include @@ -431,6 +432,12 @@ safety_checkert::resultt bmct::run( symex.set_message_handler(get_message_handler()); symex.options=options; + { + const symbolt *init_symbol; + if(!ns.lookup(CPROVER_PREFIX "initialize", init_symbol)) + symex.mode=init_symbol->mode; + } + status() << "Starting Bounded Model Checking" << eom; symex.last_source_location.make_nil(); diff --git a/src/goto-symex/goto_symex.h b/src/goto-symex/goto_symex.h index 067f8ae0097..4002a580e3a 100644 --- a/src/goto-symex/goto_symex.h +++ b/src/goto-symex/goto_symex.h @@ -49,6 +49,7 @@ class goto_symext remaining_vccs(0), constant_propagation(true), new_symbol_table(_new_symbol_table), + mode(), ns(_ns), target(_target), atomic_section_counter(0), @@ -95,6 +96,8 @@ class goto_symext optionst options; symbol_tablet &new_symbol_table; + irep_idt mode; + protected: const namespacet &ns; symex_targett ⌖ diff --git a/src/goto-symex/symex_dereference.cpp b/src/goto-symex/symex_dereference.cpp index f2f0176ec68..81e99e99fa9 100644 --- a/src/goto-symex/symex_dereference.cpp +++ b/src/goto-symex/symex_dereference.cpp @@ -295,8 +295,9 @@ void goto_symext::dereference_rec( ns, new_symbol_table, options, - symex_dereference_state); - + symex_dereference_state, + mode); + // std::cout << "**** " << from_expr(ns, "", tmp1) << std::endl; exprt tmp2=dereference.dereference( tmp1, guard, write?value_set_dereferencet::WRITE:value_set_dereferencet::READ); diff --git a/src/pointer-analysis/value_set_dereference.cpp b/src/pointer-analysis/value_set_dereference.cpp index e19110a1c93..685b88ee746 100644 --- a/src/pointer-analysis/value_set_dereference.cpp +++ b/src/pointer-analysis/value_set_dereference.cpp @@ -452,7 +452,13 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( // This is stuff like *((char *)5). // This is turned into an access to __CPROVER_memory[...]. - const symbolt &memory_symbol=ns.lookup(CPROVER_PREFIX "memory"); + if(language_mode==ID_java) + { + result.value=nil_exprt(); + return result; + } + + const symbolt &memory_symbol=ns.lookup(CPROVER_PREFIX "memory"); exprt symbol_expr=symbol_exprt(memory_symbol.name, memory_symbol.type); exprt pointer_offset=unary_exprt( diff --git a/src/pointer-analysis/value_set_dereference.h b/src/pointer-analysis/value_set_dereference.h index 60daefd8d4d..dc09df07c6c 100644 --- a/src/pointer-analysis/value_set_dereference.h +++ b/src/pointer-analysis/value_set_dereference.h @@ -37,11 +37,13 @@ class value_set_dereferencet const namespacet &_ns, symbol_tablet &_new_symbol_table, const optionst &_options, - dereference_callbackt &_dereference_callback): + dereference_callbackt &_dereference_callback, + const irep_idt _language_mode = irep_idt()): ns(_ns), new_symbol_table(_new_symbol_table), options(_options), - dereference_callback(_dereference_callback) + dereference_callback(_dereference_callback), + language_mode(_language_mode) { } virtual ~value_set_dereferencet() { } @@ -78,6 +80,7 @@ class value_set_dereferencet symbol_tablet &new_symbol_table; const optionst &options; dereference_callbackt &dereference_callback; + const irep_idt language_mode; static unsigned invalid_counter; bool dereference_type_compare( From aff699d5764b954ca75ee1c4481b1977877d7436 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 5 Dec 2016 14:39:54 +0000 Subject: [PATCH 032/166] Make symex language mode symbol clearer 'mode' replaced by 'language_mode', a field containing ID_java or similar to denote the source language in use if known. --- src/cbmc/bmc.cpp | 2 +- src/goto-symex/goto_symex.h | 6 ++++-- src/goto-symex/symex_dereference.cpp | 2 +- src/pointer-analysis/value_set_dereference.cpp | 2 +- src/pointer-analysis/value_set_dereference.h | 4 +++- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/cbmc/bmc.cpp b/src/cbmc/bmc.cpp index c320a22328c..68d2b068bb6 100644 --- a/src/cbmc/bmc.cpp +++ b/src/cbmc/bmc.cpp @@ -435,7 +435,7 @@ safety_checkert::resultt bmct::run( { const symbolt *init_symbol; if(!ns.lookup(CPROVER_PREFIX "initialize", init_symbol)) - symex.mode=init_symbol->mode; + symex.language_mode=init_symbol->mode; } status() << "Starting Bounded Model Checking" << eom; diff --git a/src/goto-symex/goto_symex.h b/src/goto-symex/goto_symex.h index 4002a580e3a..d3e162b7925 100644 --- a/src/goto-symex/goto_symex.h +++ b/src/goto-symex/goto_symex.h @@ -49,7 +49,7 @@ class goto_symext remaining_vccs(0), constant_propagation(true), new_symbol_table(_new_symbol_table), - mode(), + language_mode(), ns(_ns), target(_target), atomic_section_counter(0), @@ -96,7 +96,9 @@ class goto_symext optionst options; symbol_tablet &new_symbol_table; - irep_idt mode; + /// language_mode: ID_java, ID_C or another language identifier + /// if we know the source language in use, irep_idt() otherwise. + irep_idt language_mode; protected: const namespacet &ns; diff --git a/src/goto-symex/symex_dereference.cpp b/src/goto-symex/symex_dereference.cpp index 81e99e99fa9..dbe5e9aed3c 100644 --- a/src/goto-symex/symex_dereference.cpp +++ b/src/goto-symex/symex_dereference.cpp @@ -296,7 +296,7 @@ void goto_symext::dereference_rec( new_symbol_table, options, symex_dereference_state, - mode); + language_mode); // std::cout << "**** " << from_expr(ns, "", tmp1) << std::endl; exprt tmp2=dereference.dereference( diff --git a/src/pointer-analysis/value_set_dereference.cpp b/src/pointer-analysis/value_set_dereference.cpp index 685b88ee746..d9e8af80fc2 100644 --- a/src/pointer-analysis/value_set_dereference.cpp +++ b/src/pointer-analysis/value_set_dereference.cpp @@ -458,7 +458,7 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( return result; } - const symbolt &memory_symbol=ns.lookup(CPROVER_PREFIX "memory"); + const symbolt &memory_symbol=ns.lookup(CPROVER_PREFIX "memory"); exprt symbol_expr=symbol_exprt(memory_symbol.name, memory_symbol.type); exprt pointer_offset=unary_exprt( diff --git a/src/pointer-analysis/value_set_dereference.h b/src/pointer-analysis/value_set_dereference.h index dc09df07c6c..b1dbd0e1357 100644 --- a/src/pointer-analysis/value_set_dereference.h +++ b/src/pointer-analysis/value_set_dereference.h @@ -38,7 +38,7 @@ class value_set_dereferencet symbol_tablet &_new_symbol_table, const optionst &_options, dereference_callbackt &_dereference_callback, - const irep_idt _language_mode = irep_idt()): + const irep_idt _language_mode=irep_idt()): ns(_ns), new_symbol_table(_new_symbol_table), options(_options), @@ -80,6 +80,8 @@ class value_set_dereferencet symbol_tablet &new_symbol_table; const optionst &options; dereference_callbackt &dereference_callback; + /// language_mode: ID_java, ID_C or another language identifier + /// if we know the source language in use, irep_idt() otherwise. const irep_idt language_mode; static unsigned invalid_counter; From 02933094dcf25067a75a333732e41f7330c445b4 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 5 Dec 2016 15:57:12 +0000 Subject: [PATCH 033/166] Add comment that goto_program_dereference doesn't specify language mode Explicitly pass ID_nil instead of silently leaving the language uninitialised as before. --- src/pointer-analysis/goto_program_dereference.h | 6 +++++- src/pointer-analysis/value_set_dereference.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pointer-analysis/goto_program_dereference.h b/src/pointer-analysis/goto_program_dereference.h index cd2b3c977f3..ef7feac9a11 100644 --- a/src/pointer-analysis/goto_program_dereference.h +++ b/src/pointer-analysis/goto_program_dereference.h @@ -19,6 +19,10 @@ Author: Daniel Kroening, kroening@kroening.com class goto_program_dereferencet:protected dereference_callbackt { public: + // Note: this currently doesn't specify a source language + // for the final argument to value_set_dereferencet. + // This means that language-inappropriate values such as + // (struct A*)some_integer_value in Java, may be returned. goto_program_dereferencet( const namespacet &_ns, symbol_tablet &_new_symbol_table, @@ -27,7 +31,7 @@ class goto_program_dereferencet:protected dereference_callbackt options(_options), ns(_ns), value_sets(_value_sets), - dereference(_ns, _new_symbol_table, _options, *this) { } + dereference(_ns, _new_symbol_table, _options, *this, ID_nil) { } void dereference_program( goto_programt &goto_program, diff --git a/src/pointer-analysis/value_set_dereference.h b/src/pointer-analysis/value_set_dereference.h index b1dbd0e1357..d797d37a23d 100644 --- a/src/pointer-analysis/value_set_dereference.h +++ b/src/pointer-analysis/value_set_dereference.h @@ -38,7 +38,7 @@ class value_set_dereferencet symbol_tablet &_new_symbol_table, const optionst &_options, dereference_callbackt &_dereference_callback, - const irep_idt _language_mode=irep_idt()): + const irep_idt _language_mode): ns(_ns), new_symbol_table(_new_symbol_table), options(_options), From 0c8aedc0ef3ee7736acb57036a736eef27e0c953 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 23 Aug 2016 09:04:22 +0100 Subject: [PATCH 034/166] Don't use potentially-invalid downcasts to read an object's clsid if possible By using a pointer with a type that corresponds to a real object (at least in Java, where a virtual call against a method of type X guarantees that the instance parameter has at least that type), we make it less likely that a byte-extract opcode is used to retrieve the class-id field. --- .../remove_virtual_functions.cpp | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index a0d9f551c2e..0198527bd06 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -170,28 +170,39 @@ void remove_virtual_functionst::remove_virtual_function( goto_programt new_code_calls; goto_programt new_code_gotos; + // Get a pointer from which we can extract a clsid. + // If it's already a pointer to an object of some sort, just use it; + // if it's void* then use the parent of all possible candidates, + // which by the nature of get_functions happens to be the last candidate. + + exprt this_expr=code.arguments()[0]; + assert(this_expr.type().id()==ID_pointer && + "Non-pointer this-arg in remove-virtuals?"); + const auto& points_to=this_expr.type().subtype(); + if(points_to==empty_typet()) + { + symbol_typet symbol_type(functions.back().class_id); + this_expr=typecast_exprt(this_expr, pointer_typet(symbol_type)); + } + exprt deref=dereference_exprt(this_expr, this_expr.type().subtype()); + exprt c_id2=build_class_identifier(deref); + for(const auto &fun : functions) { // call function goto_programt::targett t1=new_code_calls.add_instruction(); t1->make_function_call(code); - to_code_function_call(t1->code).function()=fun.symbol_expr; + auto& newcall=to_code_function_call(t1->code); + newcall.function()=fun.symbol_expr; + pointer_typet need_type(symbol_typet(fun.class_id)); + if(newcall.arguments()[0].type()!=need_type) + newcall.arguments()[0].make_typecast(need_type); // goto final goto_programt::targett t3=new_code_calls.add_instruction(); t3->make_goto(t_final, true_exprt()); - exprt this_expr=code.arguments()[0]; - if(this_expr.type().id()!=ID_pointer || - this_expr.type().id()!=ID_struct) - { - symbol_typet symbol_type(fun.class_id); - this_expr=typecast_exprt(this_expr, pointer_typet(symbol_type)); - } - - exprt deref=dereference_exprt(this_expr, this_expr.type().subtype()); exprt c_id1=constant_exprt(fun.class_id, string_typet()); - exprt c_id2=build_class_identifier(deref); goto_programt::targett t4=new_code_gotos.add_instruction(); t4->make_goto(t1, equal_exprt(c_id1, c_id2)); From 96b386f81d1dcfbed869a4eb7031486b9d5fca6d Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 9 Sep 2016 15:00:39 +0100 Subject: [PATCH 035/166] Include child types when creating a virtual function dispatch tree Previously if A had a subtype B which did *not* override a particular function, instances of B would run the default (least-derived) version of the function instead of A's version. --- .../remove_virtual_functions.cpp | 91 +++++++++++++------ 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index 0198527bd06..0f11bcc0111 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -49,6 +49,8 @@ class remove_virtual_functionst typedef std::vector functionst; void get_functions(const exprt &, functionst &); + void get_child_functions_rec(const irep_idt &, const symbol_exprt &, + const irep_idt &, functionst &); exprt get_method(const irep_idt &class_id, const irep_idt &component_name); exprt build_class_identifier(const exprt &); @@ -189,14 +191,22 @@ void remove_virtual_functionst::remove_virtual_function( for(const auto &fun : functions) { - // call function goto_programt::targett t1=new_code_calls.add_instruction(); - t1->make_function_call(code); - auto& newcall=to_code_function_call(t1->code); - newcall.function()=fun.symbol_expr; - pointer_typet need_type(symbol_typet(fun.class_id)); - if(newcall.arguments()[0].type()!=need_type) - newcall.arguments()[0].make_typecast(need_type); + if(fun.symbol_expr.get_identifier()!=irep_idt()) + { + // call function + t1->make_function_call(code); + auto& newcall=to_code_function_call(t1->code); + newcall.function()=fun.symbol_expr; + pointer_typet need_type(symbol_typet(fun.symbol_expr.get(ID_C_class))); + if(newcall.arguments()[0].type()!=need_type) + newcall.arguments()[0].make_typecast(need_type); + } + else + { + // No definition for this type; shouldn't be possible... + t1->make_assertion(false_exprt()); + } // goto final goto_programt::targett t3=new_code_calls.add_instruction(); @@ -235,6 +245,35 @@ void remove_virtual_functionst::remove_virtual_function( target->make_skip(); } +void remove_virtual_functionst::get_child_functions_rec( + const irep_idt &this_id, + const symbol_exprt &last_method_defn, + const irep_idt &component_name, + functionst &functions) +{ + auto findit=class_hierarchy.class_map.find(this_id); + if(findit==class_hierarchy.class_map.end()) + return; + + for(const auto & child : findit->second.children) + { + exprt method=get_method(child, component_name); + functiont function; + function.class_id=child; + if(method.is_not_nil()) + { + function.symbol_expr=to_symbol_expr(method); + function.symbol_expr.set(ID_C_class, child); + } + else { + function.symbol_expr=last_method_defn; + } + functions.push_back(function); + + get_child_functions_rec(child,function.symbol_expr,component_name,functions); + } +} + /*******************************************************************\ Function: remove_virtual_functionst::get_functions @@ -254,23 +293,7 @@ void remove_virtual_functionst::get_functions( const irep_idt class_id=function.get(ID_C_class); const irep_idt component_name=function.get(ID_component_name); assert(!class_id.empty()); - - // iterate over all children, transitively - std::vector children= - class_hierarchy.get_children_trans(class_id); - - for(const auto &child : children) - { - exprt method=get_method(child, component_name); - if(method.is_not_nil()) - { - functiont function; - function.class_id=child; - function.symbol_expr=to_symbol_expr(method); - function.symbol_expr.set(ID_C_class, child); - functions.push_back(function); - } - } + functiont root_function; // Start from current class, go to parents until something // is found. @@ -280,11 +303,9 @@ void remove_virtual_functionst::get_functions( exprt method=get_method(c, component_name); if(method.is_not_nil()) { - functiont function; - function.class_id=c; - function.symbol_expr=to_symbol_expr(method); - function.symbol_expr.set(ID_C_class, c); - functions.push_back(function); + root_function.class_id=c; + root_function.symbol_expr=to_symbol_expr(method); + root_function.symbol_expr.set(ID_C_class, c); break; // abort } @@ -294,6 +315,18 @@ void remove_virtual_functionst::get_functions( if(parents.empty()) break; c=parents.front(); } + + if(root_function.class_id==irep_idt()) + { + // No definition here; this is an abstract function. + root_function.class_id=class_id; + } + + // iterate over all children, transitively + get_child_functions_rec(class_id,root_function.symbol_expr,component_name,functions); + + functions.push_back(root_function); + } /*******************************************************************\ From 1062f5c08bc75f82647f8b2b2913035fbaa804ec Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 9 Sep 2016 15:08:50 +0100 Subject: [PATCH 036/166] Call least-derived virtual function for unknown clsid Previously this would fall through to the first child when e.g. dispatching against a stub type with unknown class hierarchy position, which might assume the `this` pointer to have a more-derived type than it actually does. --- src/goto-programs/remove_virtual_functions.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index 0f11bcc0111..33ae7554c72 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -189,6 +189,7 @@ void remove_virtual_functionst::remove_virtual_function( exprt deref=dereference_exprt(this_expr, this_expr.type().subtype()); exprt c_id2=build_class_identifier(deref); + goto_programt::targett last_function; for(const auto &fun : functions) { goto_programt::targett t1=new_code_calls.add_instruction(); @@ -208,6 +209,8 @@ void remove_virtual_functionst::remove_virtual_function( t1->make_assertion(false_exprt()); } + last_function=t1; + // goto final goto_programt::targett t3=new_code_calls.add_instruction(); t3->make_goto(t_final, true_exprt()); @@ -218,6 +221,11 @@ void remove_virtual_functionst::remove_virtual_function( t4->make_goto(t1, equal_exprt(c_id1, c_id2)); } + // In any other case (most likely a stub class) call the most basic + // version of the method we know to exist: + goto_programt::targett fallthrough=new_code_gotos.add_instruction(); + fallthrough->make_goto(last_function); + goto_programt new_code; // patch them all together From e73226ce4335f93b13746fbb083ae9ab73ff4f1f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 14 Dec 2016 10:39:24 +0000 Subject: [PATCH 037/166] Add test for virtual dispatch against child type --- regression/cbmc-java/virtual6/A.class | Bin 0 -> 485 bytes regression/cbmc-java/virtual6/A.java | 40 ++++++++++++++++++++++++ regression/cbmc-java/virtual6/B.class | Bin 0 -> 211 bytes regression/cbmc-java/virtual6/C.class | Bin 0 -> 161 bytes regression/cbmc-java/virtual6/test.desc | 8 +++++ 5 files changed, 48 insertions(+) create mode 100644 regression/cbmc-java/virtual6/A.class create mode 100644 regression/cbmc-java/virtual6/A.java create mode 100644 regression/cbmc-java/virtual6/B.class create mode 100644 regression/cbmc-java/virtual6/C.class create mode 100644 regression/cbmc-java/virtual6/test.desc diff --git a/regression/cbmc-java/virtual6/A.class b/regression/cbmc-java/virtual6/A.class new file mode 100644 index 0000000000000000000000000000000000000000..7fae215b0ebab4360f1f89f106e47a69ae2a3e44 GIT binary patch literal 485 zcmYjMO-lk%6g_V~b=0&pbNq67Sn6qFYBbRv-1p(v0^S$wrfLh$X z5zy+xdsiTS>G^JJGU&LYYp2uaMmz+R1}Ou_^9jXbhs1d~MW9J?F)V!a{^vHJ%fmdK62D3nb)ax$pRo<*QE5?T)d@fMI?FP(dw3SfiW@ zL_ySdW)Saen1Iy?mI^!Sv6s{=QBoD{jrBiI=aj%QtK>~-We_jsQ0`_>n{#MHy)}nH zG^<+fmDkwfkq%Nb``2&mR`n@jd$O9gR@H6&1EE_PObLROm>kR>A|_~OGhl_?KJBYW m;t(kuBaKr^o+FPHveVEOsF+BaNSRpG^&hC5Xq*mo*M0#`3p=m? literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/virtual6/A.java b/regression/cbmc-java/virtual6/A.java new file mode 100644 index 00000000000..a98dc88009d --- /dev/null +++ b/regression/cbmc-java/virtual6/A.java @@ -0,0 +1,40 @@ + +public class A { + + int f() { + return 1; + } + + public void main(int unknown) { + + A a = new A(); + B b = new B(); + C c = new C(); + A callee; + switch(unknown) { + case 1: + callee = a; + break; + case 2: + callee = b; + break; + default: + callee = c; + break; + } + + callee.f(); + + } + +} + +class B extends A { + + int f() { + return 2; + } + +} + +class C extends B {} diff --git a/regression/cbmc-java/virtual6/B.class b/regression/cbmc-java/virtual6/B.class new file mode 100644 index 0000000000000000000000000000000000000000..f810a84fbd64e185c69209a22ec1df9725e8978c GIT binary patch literal 211 zcmYj~y$ZrW5QJy*t1+5h5CS%8VPz>o6a+zR6#GO^IMD=x@u_UA1PdR)hZ5(kT-cr2 z*$?*pdA83qi0h zs&c31+QeQmJf_z)gaen*l${`k#TTY5HZLGZ*P#m49Xud+8iCL0{lb{8hC01L+f;*E O?v3-G>v9Xs1&uFVcNr4^ literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/virtual6/C.class b/regression/cbmc-java/virtual6/C.class new file mode 100644 index 0000000000000000000000000000000000000000..026d126c765345716244e6ad698d0b022ab65ddc GIT binary patch literal 161 zcmX^0Z`VEs1_l!bUM>b^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBFZ=BSsISeD4cz{0@F$iV0f#7+zf3`{_SL4Xm6 lfiggv4akxO(jXC5t?dkq8^O}-K#~nCr~xE7fIKD!P5_BH7V!W8 literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/virtual6/test.desc b/regression/cbmc-java/virtual6/test.desc new file mode 100644 index 00000000000..8432c7b2303 --- /dev/null +++ b/regression/cbmc-java/virtual6/test.desc @@ -0,0 +1,8 @@ +CORE +A.class +--function A.main --show-goto-functions +^EXIT=0$ +^SIGNAL=0$ +IF "java::C".*THEN GOTO +IF "java::B".*THEN GOTO +IF "java::A".*THEN GOTO From 5e774da84e66a40323a640e8da9e14f3d4b03197 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 4 Jan 2017 12:58:00 +0000 Subject: [PATCH 038/166] Style and documentation fixes --- .../remove_virtual_functions.cpp | 70 ++++++++++++++----- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index 33ae7554c72..4da7d62631b 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -7,6 +7,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ #include +#include #include "class_hierarchy.h" #include "remove_virtual_functions.h" @@ -43,15 +44,23 @@ class remove_virtual_functionst class functiont { public: + functiont() {} + explicit functiont(const irep_idt& _class_id) : + class_id(_class_id) + {} + symbol_exprt symbol_expr; irep_idt class_id; }; typedef std::vector functionst; void get_functions(const exprt &, functionst &); - void get_child_functions_rec(const irep_idt &, const symbol_exprt &, - const irep_idt &, functionst &); - exprt get_method(const irep_idt &class_id, const irep_idt &component_name); + void get_child_functions_rec( + const irep_idt &, const symbol_exprt &, + const irep_idt &, functionst &) const; + exprt get_method( + const irep_idt &class_id, + const irep_idt &component_name) const; exprt build_class_identifier(const exprt &); }; @@ -180,7 +189,7 @@ void remove_virtual_functionst::remove_virtual_function( exprt this_expr=code.arguments()[0]; assert(this_expr.type().id()==ID_pointer && "Non-pointer this-arg in remove-virtuals?"); - const auto& points_to=this_expr.type().subtype(); + const auto &points_to=this_expr.type().subtype(); if(points_to==empty_typet()) { symbol_typet symbol_type(functions.back().class_id); @@ -193,14 +202,14 @@ void remove_virtual_functionst::remove_virtual_function( for(const auto &fun : functions) { goto_programt::targett t1=new_code_calls.add_instruction(); - if(fun.symbol_expr.get_identifier()!=irep_idt()) + if(!fun.symbol_expr.get_identifier().empty()) { // call function t1->make_function_call(code); - auto& newcall=to_code_function_call(t1->code); + auto &newcall=to_code_function_call(t1->code); newcall.function()=fun.symbol_expr; pointer_typet need_type(symbol_typet(fun.symbol_expr.get(ID_C_class))); - if(newcall.arguments()[0].type()!=need_type) + if(!type_eq(newcall.arguments()[0].type(), need_type, ns)) newcall.arguments()[0].make_typecast(need_type); } else @@ -253,11 +262,33 @@ void remove_virtual_functionst::remove_virtual_function( target->make_skip(); } +/*******************************************************************\ + +Function: remove_virtual_functionst::get_child_functions_rec + + Inputs: `this_id`: class name + `last_method_defn`: the most-derived parent of `this_id` + to define the requested function + `component_name`: name of the function searched for + + Outputs: `functions` is assigned a list of {class name, function symbol} + pairs indicating that if `this` is of the given class, then the + call will target the given function. Thus if A <: B <: C and A + and C provide overrides of `f` (but B does not), + get_child_functions_rec("C", C.f, "f") -> [{"C", C.f}, + {"B", C.f}, + {"A", A.f}] + + Purpose: Used by get_functions to track the most-derived parent that + provides an override of a given function. + +\*******************************************************************/ + void remove_virtual_functionst::get_child_functions_rec( const irep_idt &this_id, const symbol_exprt &last_method_defn, const irep_idt &component_name, - functionst &functions) + functionst &functions) const { auto findit=class_hierarchy.class_map.find(this_id); if(findit==class_hierarchy.class_map.end()) @@ -266,19 +297,23 @@ void remove_virtual_functionst::get_child_functions_rec( for(const auto & child : findit->second.children) { exprt method=get_method(child, component_name); - functiont function; - function.class_id=child; + functiont function(child); if(method.is_not_nil()) { function.symbol_expr=to_symbol_expr(method); function.symbol_expr.set(ID_C_class, child); } - else { + else + { function.symbol_expr=last_method_defn; } functions.push_back(function); - get_child_functions_rec(child,function.symbol_expr,component_name,functions); + get_child_functions_rec( + child, + function.symbol_expr, + component_name, + functions); } } @@ -324,17 +359,20 @@ void remove_virtual_functionst::get_functions( c=parents.front(); } - if(root_function.class_id==irep_idt()) + if(root_function.class_id.empty()) { // No definition here; this is an abstract function. root_function.class_id=class_id; } // iterate over all children, transitively - get_child_functions_rec(class_id,root_function.symbol_expr,component_name,functions); + get_child_functions_rec( + class_id, + root_function.symbol_expr, + component_name, + functions); functions.push_back(root_function); - } /*******************************************************************\ @@ -351,7 +389,7 @@ Function: remove_virtual_functionst::get_method exprt remove_virtual_functionst::get_method( const irep_idt &class_id, - const irep_idt &component_name) + const irep_idt &component_name) const { irep_idt id=id2string(class_id)+"."+ id2string(component_name); From 6fb9cf20402c579eddbe154d536c48c3fc802791 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 16 Jan 2017 08:19:26 -0500 Subject: [PATCH 039/166] fixup! wmm/musketeer: Use wmm_grapht::node_indext instead of unsigned --- src/musketeer/fence_inserter.cpp | 12 ++++---- src/musketeer/graph_visitor.cpp | 52 +++++++++++++++++++++++--------- src/musketeer/graph_visitor.h | 36 ++++++++++++++-------- 3 files changed, 66 insertions(+), 34 deletions(-) diff --git a/src/musketeer/fence_inserter.cpp b/src/musketeer/fence_inserter.cpp index 815ae57f44a..5b00949d11b 100644 --- a/src/musketeer/fence_inserter.cpp +++ b/src/musketeer/fence_inserter.cpp @@ -147,7 +147,7 @@ void fence_insertert::preprocess() e_c_it!=e_i->end(); ++e_c_it) { - std::set pt_set; + std::set pt_set; assert(map_to_e.find(*e_c_it) != map_to_e.end()); const_graph_visitor.PT(map_to_e.find(*e_c_it)->second, pt_set); } @@ -165,7 +165,7 @@ void fence_insertert::preprocess() e_nc_it!=e_i->end(); ++e_nc_it) { - std::set pt_set; + std::set pt_set; assert(map_to_e.find(*e_nc_it) != map_to_e.end()); const_graph_visitor.PT(map_to_e.find(*e_nc_it)->second, pt_set); } @@ -183,7 +183,7 @@ void fence_insertert::preprocess() e_nc_it!=e_i->end(); ++e_nc_it) { - std::set pt_set; + std::set pt_set; assert(map_to_e.find(*e_nc_it) != map_to_e.end()); const_graph_visitor.PT(map_to_e.find(*e_nc_it)->second, pt_set); } @@ -201,7 +201,7 @@ void fence_insertert::preprocess() e_nc_it!=e_i->end(); ++e_nc_it) { - std::set pt_set; + std::set pt_set; assert(map_to_e.find(*e_nc_it) != map_to_e.end()); const_graph_visitor.PT(map_to_e.find(*e_nc_it)->second, pt_set); } @@ -221,13 +221,13 @@ void fence_insertert::preprocess() e_c_it!=e_i->end(); ++e_c_it) { - std::set ct_set; + std::set ct_set; assert( invisible_var.map_to_e.find(*e_c_it) != invisible_var.map_to_e.end()); const_graph_visitor.CT(invisible_var.map_to_e.find(*e_c_it)->second, ct_set); - std::set ct_not_powr_set; + std::set ct_not_powr_set; const_graph_visitor.CT_not_powr( invisible_var.map_to_e.find(*e_c_it)->second, ct_not_powr_set); } diff --git a/src/musketeer/graph_visitor.cpp b/src/musketeer/graph_visitor.cpp index 010d063e9f6..e503a65170d 100644 --- a/src/musketeer/graph_visitor.cpp +++ b/src/musketeer/graph_visitor.cpp @@ -29,7 +29,7 @@ void const_graph_visitort::graph_explore( event_idt next, event_idt end, std::list &old_path, - std::set &edges) + std::set &edges) { if(next == end) { /* inserts all the pos collected from old_path in edges */ @@ -75,8 +75,11 @@ void const_graph_visitort::graph_explore( \*******************************************************************/ -void const_graph_visitort::const_graph_explore(event_grapht& egraph, event_idt next, - event_idt end, std::list& old_path) +void const_graph_visitort::const_graph_explore( + event_grapht& egraph, + event_idt next, + event_idt end, + std::list& old_path) { if(next == end) { /* inserts all the pos collected from old_path in edges */ @@ -122,8 +125,12 @@ void const_graph_visitort::const_graph_explore(event_grapht& egraph, event_idt n \*******************************************************************/ -void const_graph_visitort::graph_explore_BC(event_grapht& egraph, event_idt next, - std::list& old_path, std::set& edges, bool porw) +void const_graph_visitort::graph_explore_BC( + event_grapht& egraph, + event_idt next, + std::list& old_path, + std::set& edges, + bool porw) { /* TODO: restricts to C_1 U ... U C_n for perf improvement */ assert(old_path.size() > 0); @@ -187,8 +194,10 @@ void const_graph_visitort::graph_explore_BC(event_grapht& egraph, event_idt next \*******************************************************************/ -void const_graph_visitort::const_graph_explore_BC(event_grapht& egraph, - event_idt next, std::list& old_path) +void const_graph_visitort::const_graph_explore_BC( + event_grapht& egraph, + event_idt next, + std::list& old_path) { /* TODO: restricts to C_1 U ... U C_n */ assert(old_path.size() > 0); @@ -250,8 +259,12 @@ void const_graph_visitort::const_graph_explore_BC(event_grapht& egraph, \*******************************************************************/ -void const_graph_visitort::graph_explore_AC(event_grapht& egraph, event_idt next, - std::list& old_path, std::set& edges, bool porw) +void const_graph_visitort::graph_explore_AC( + event_grapht& egraph, + event_idt next, + std::list& old_path, + std::set& edges, + bool porw) { /* TODO: restricts to C_1 U ... U C_n */ assert(old_path.size() > 0); @@ -315,8 +328,10 @@ void const_graph_visitort::graph_explore_AC(event_grapht& egraph, event_idt next \*******************************************************************/ -void const_graph_visitort::const_graph_explore_AC(event_grapht& egraph, - event_idt next, std::list& old_path) +void const_graph_visitort::const_graph_explore_AC( + event_grapht& egraph, + event_idt next, + std::list& old_path) { /* TODO: restricts to C_1 U ... U C_n */ assert(old_path.size() > 0); @@ -379,7 +394,10 @@ void const_graph_visitort::const_graph_explore_AC(event_grapht& egraph, \*******************************************************************/ -void const_graph_visitort::PT(const edget& e, std::set& edges) { +void const_graph_visitort::PT( + const edget& e, + std::set& edges) +{ visited_nodes.clear(); // if(!e.is_po) /* e is in po^+\po */ is_po is a flag set manually, do not @@ -430,7 +448,10 @@ void const_graph_visitort::PT(const edget& e, std::set& edges) { \*******************************************************************/ -void const_graph_visitort::CT(const edget& edge, std::set& edges) { +void const_graph_visitort::CT( + const edget& edge, + std::set& edges) +{ event_grapht& egraph=fence_inserter.instrumenter.egraph; /* the edge can be in the reversed order (back-edge) */ @@ -484,8 +505,9 @@ void const_graph_visitort::CT(const edget& edge, std::set& edges) { \*******************************************************************/ -void const_graph_visitort::CT_not_powr(const edget& edge, - std::set& edges) +void const_graph_visitort::CT_not_powr( + const edget& edge, + std::set& edges) { event_grapht& egraph=fence_inserter.instrumenter.egraph; diff --git a/src/musketeer/graph_visitor.h b/src/musketeer/graph_visitor.h index 210bb68d913..c75004d01d3 100644 --- a/src/musketeer/graph_visitor.h +++ b/src/musketeer/graph_visitor.h @@ -26,26 +26,36 @@ class const_graph_visitort public: /* computes the PT (btwn), CT (cml) and IT (cntrl) */ - void PT(const edget &e, std::set &edges); - void CT(const edget &e, std::set &edges); - void CT_not_powr(const edget &e, std::set &edges); - void IT(const edget &e, std::set &edges); + void PT(const edget& e, std::set& edges); + void CT(const edget& e, std::set& edges); + void CT_not_powr(const edget& e, std::set &edges); + void IT(const edget& e, std::set& edges); void const_graph_explore( - event_grapht &graph, event_idt next, event_idt end, - std::list &old_path); + event_grapht& graph, + event_idt next, + event_idt end, + std::list& old_path); void graph_explore(event_grapht& graph, event_idt next, event_idt end, - std::list &old_path, std::set &edges); + std::list& old_path, std::set& edges); void graph_explore_BC(event_grapht& egraph, event_idt next, - std::list& old_path, std::set& edges, bool porw); + std::list& old_path, std::set& edges, bool porw); void graph_explore_AC(event_grapht& egraph, event_idt next, - std::list& old_path, std::set& edges, bool porw); - void graph_explore_BC(event_grapht& egraph, event_idt next, - std::list& old_path, std::set& edges) { + std::list& old_path, std::set& edges, bool porw); + void graph_explore_BC( + event_grapht& egraph, event_idt next, + std::list& old_path, + std::set& edges) + { graph_explore_BC(egraph, next, old_path, edges, false); } - void graph_explore_AC(event_grapht& egraph, event_idt next, - std::list& old_path, std::set& edges) { + + void graph_explore_AC( + event_grapht& egraph, + event_idt next, + std::list& old_path, + std::set& edges) + { graph_explore_AC(egraph, next, old_path, edges, false); } From d15e106a5a4074d7db75049e95c7491cc2286f76 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 17 Jan 2017 19:24:43 -0500 Subject: [PATCH 040/166] cegis uses labels for marking instructions Compilation should not fail on seemingly unused labels. --- src/cegis/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cegis/Makefile b/src/cegis/Makefile index 6547bec6890..95c5abbb2a9 100644 --- a/src/cegis/Makefile +++ b/src/cegis/Makefile @@ -129,6 +129,8 @@ LIBS = $(DLFCN_LINKFLAGS) CLEANFILES = cegis$(EXEEXT) +CP_CXXFLAGS += -Wno-unused-label + all: cegis$(EXEEXT) ifneq ($(wildcard ../java_bytecode/Makefile),) From 5b4f2ace15e8ff74655b39a065cbc45ca1c86869 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 17 Jan 2017 19:25:35 -0500 Subject: [PATCH 041/166] std::string::c_str() is non-const on Mac OS Linking had been failing. The code has been simplified instead of handing the compiler a meta-programming exercise. --- src/cegis/cegis-util/cbmc_runner.cpp | 42 ++++++---------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/src/cegis/cegis-util/cbmc_runner.cpp b/src/cegis/cegis-util/cbmc_runner.cpp index b2b3c564366..995ad34c355 100644 --- a/src/cegis/cegis-util/cbmc_runner.cpp +++ b/src/cegis/cegis-util/cbmc_runner.cpp @@ -1,6 +1,3 @@ -#include -#include - #include #include @@ -43,43 +40,20 @@ bool is_gcc() return configt::ansi_ct::flavourt::GCC == config.ansi_c.mode; } -std::vector get_args() -{ - std::vector result= { "cbmc", "--stop-on-fail" }; - if (is_gcc()) result.push_back("--gcc"); - return result; -} - -std::vector get_argv(const std::vector &args) +int argc() { - std::vector result; - std::transform(args.begin(), args.end(), std::back_inserter(result), - std::mem_fun_ref(&std::string::c_str)); - return result; + return is_gcc()?3:2; } -class args_providert +const char **argv() { - const std::vector args; - std::vector arg_ref; -public: - args_providert() : - args(get_args()), arg_ref(get_argv(args)) - { - } + static const char* n_gcc[]={"cbmc", "--stop-on-fail", 0}; + static const char* w_gcc[]={"cbmc", "--stop-on-fail", "--gcc", 0}; - int argc() - { - return arg_ref.size(); - } - - const char * *argv() - { - return arg_ref.data(); - } -}; + return is_gcc()?w_gcc:n_gcc; +} -class cbmc_runnert: public args_providert, public cbmc_parse_optionst +class cbmc_runnert:public cbmc_parse_optionst { const symbol_tablet &st; const goto_functionst &gf; From a2d858562246d6adf366291af2add569c966e367 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 17 Jan 2017 19:27:57 -0500 Subject: [PATCH 042/166] cegis: remove unused variables and namespace-local functions --- src/cegis/learn/insert_counterexample.cpp | 1 - .../constraint/constraint_factory.cpp | 1 - .../cegis_processor_body_factory.cpp | 46 ------------------- .../instructionset/create_cegis_processor.cpp | 11 ----- .../learn/instrument_counterexamples.cpp | 2 - .../learn/refactor_candidate_printer.cpp | 1 - .../refactor/nullobject/nullable_analysis.cpp | 1 - 7 files changed, 63 deletions(-) diff --git a/src/cegis/learn/insert_counterexample.cpp b/src/cegis/learn/insert_counterexample.cpp index 1acab8b20c5..c34663ddcfd 100644 --- a/src/cegis/learn/insert_counterexample.cpp +++ b/src/cegis/learn/insert_counterexample.cpp @@ -139,7 +139,6 @@ void add_array_declarations(symbol_tablet &st, goto_functionst &gf, const constant_exprt sz_expr(from_integer(ces.size(), sz_type)); const array_valuest array_values(get_array_values(ces)); const labelled_counterexamplest::value_type &prototype=ces.front(); - goto_programt &body=get_entry_body(gf); goto_programt::targett pos=std::prev(begin); for (const labelled_counterexamplest::value_type::value_type &value : prototype) { diff --git a/src/cegis/refactor/constraint/constraint_factory.cpp b/src/cegis/refactor/constraint/constraint_factory.cpp index 0013948ce60..843312ee8e7 100644 --- a/src/cegis/refactor/constraint/constraint_factory.cpp +++ b/src/cegis/refactor/constraint/constraint_factory.cpp @@ -110,7 +110,6 @@ const goto_ranget &get_second_range(const refactor_programt::sketcht &sketch) void make_skip(const goto_programt::targett first, const goto_programt::targett last) { - const auto op(std::mem_fun_ref(&goto_programt::instructiont::make_skip)); std::for_each(first, last, [](goto_programt::instructiont &instr) { if(!instr.is_decl()) instr.make_skip();}); } diff --git a/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp b/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp index 6035112abbb..d383f263418 100644 --- a/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp +++ b/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp @@ -214,49 +214,6 @@ class body_factoryt finalise_conditional_instr_gotos(); } }; - -bool is_forward_goto(const goto_programt::instructiont &instr) -{ - return instr.is_goto() && !instr.is_backwards_goto(); -} - -void remove_singleton_switch_cases(goto_programt &body) -{ - body.compute_location_numbers(); - goto_programt::instructionst &instrs=body.instructions; - const goto_programt::targett end(instrs.end()); - for (goto_programt::targett pos=instrs.begin(); pos != end; ++pos) - { - if (!is_forward_goto(*pos)) continue; - const auto pred(std::mem_fun_ref(&goto_programt::instructiont::is_skip)); - const goto_programt::targett tail=std::find_if(pos, end, pred); - assert(end != tail); - if (pos->get_target() == tail) instrs.erase(pos); - pos=tail; - } -} - -void remove_goto_next(goto_programt &body) -{ - body.compute_location_numbers(); - goto_programt::instructionst &instrs=body.instructions; - for (goto_programt::targett pos=instrs.begin(); pos != instrs.end(); ++pos) - if (is_forward_goto(*pos) && pos->get_target() == std::next(pos)) - pos=instrs.erase(pos); -} - -void remove_skips(goto_programt::instructionst &instrs) -{ - const goto_programt::targett first(instrs.begin()); - const goto_programt::targett last(instrs.end()); - for (goto_programt::targett pos=first; pos != last; ++pos) - { - if (!pos->is_skip()) continue; - const goto_programt::targett successor(std::next(pos)); - move_labels(instrs, pos, successor); - pos=instrs.erase(pos); - } -} } void generate_processor_body(symbol_tablet &st, goto_programt &body, @@ -272,9 +229,6 @@ void generate_processor_body(symbol_tablet &st, goto_programt &body, factory.finish_instruction_loop(); } body.add_instruction(goto_program_instruction_typet::END_FUNCTION); - //remove_singleton_switch_cases(body); - //remove_goto_next(body); - //remove_skips(body.instructions); body.compute_loop_numbers(); body.update(); } diff --git a/src/cegis/refactor/instructionset/create_cegis_processor.cpp b/src/cegis/refactor/instructionset/create_cegis_processor.cpp index 6f8b4103ecc..611a719d655 100644 --- a/src/cegis/refactor/instructionset/create_cegis_processor.cpp +++ b/src/cegis/refactor/instructionset/create_cegis_processor.cpp @@ -31,7 +31,6 @@ class type_collectort: public const_expr_visitort virtual void operator()(const exprt &expr) { const typet &type=expr.type(); - const irep_idt &type_id=type.id(); if (ID_code != type.id() && !is_empty(type)) types.insert(expr.type()); } }; @@ -131,21 +130,11 @@ symbol_typet create_instruction_type(symbol_tablet &st, return symbol_typet(instr_type_name); } -const mp_integer get_width(const typet &type) -{ - const irep_idt &id_width=type.get(ID_width); - assert(!id_width.empty()); - return string2integer(id2string(id_width)); -} - code_typet create_func_type(const symbol_tablet &st, const symbol_typet &instruction_type, const std::string &func_name) { code_typet code_type; code_type.return_type()=empty_typet(); - const typet &followed_type=namespacet(st).follow(instruction_type); - const struct_union_typet &struct_type=to_struct_union_type(followed_type); - const struct_union_typet::componentst &comps=struct_type.components(); const pointer_typet instr_ref_type(instruction_type); code_typet::parametert prog(instr_ref_type); const char * const prog_base_name=CEGIS_PROC_PROGRAM_PARAM_ID; diff --git a/src/cegis/refactor/learn/instrument_counterexamples.cpp b/src/cegis/refactor/learn/instrument_counterexamples.cpp index 713b0ef0f94..3e16568cce7 100644 --- a/src/cegis/refactor/learn/instrument_counterexamples.cpp +++ b/src/cegis/refactor/learn/instrument_counterexamples.cpp @@ -49,7 +49,6 @@ void create_ce_arrays(symbol_tablet &st, goto_functionst &gf, const constant_exprt sz_expr(from_integer(ces.size(), sz_type)); const array_valuest array_values(get_array_values(ces)); const labelled_counterexamplest::value_type &prototype=ces.front(); - goto_programt &body=get_body(gf, CPROVER_INIT); for (const labelled_counterexamplest::value_type::value_type &value : prototype) { const labelled_assignmentst::value_type::first_type loc_id=value.first; @@ -121,7 +120,6 @@ void assign_ce_values(symbol_tablet &st, goto_functionst &gf, { for (const refactor_programt::counterexample_locationst::value_type ce_loc : ce_locs) { - const std::string &func=id2string(ce_loc.first); for (goto_programt::targett pos : ce_loc.second) { const irep_idt &label=get_counterexample_marker(pos); diff --git a/src/cegis/refactor/learn/refactor_candidate_printer.cpp b/src/cegis/refactor/learn/refactor_candidate_printer.cpp index ea5bc63dd8f..6012c2724ee 100644 --- a/src/cegis/refactor/learn/refactor_candidate_printer.cpp +++ b/src/cegis/refactor/learn/refactor_candidate_printer.cpp @@ -38,7 +38,6 @@ void print_instr(messaget::mstreamt &os, const namespacet &ns, for (; first != last; ++first) body.output_instruction(ns, func_name, oss, first); std::string result(oss.str()); - struct_exprt::operandst::const_iterator it=std::next(ops.begin()); for (size_t i=1; i < ops.size(); ++i) { std::string nd("*__CPROVER_cegis_variable_array_double[(program + i)->op_"); diff --git a/src/cegis/refactor/nullobject/nullable_analysis.cpp b/src/cegis/refactor/nullobject/nullable_analysis.cpp index 0a439cc5dd0..12f33c092af 100644 --- a/src/cegis/refactor/nullobject/nullable_analysis.cpp +++ b/src/cegis/refactor/nullobject/nullable_analysis.cpp @@ -86,7 +86,6 @@ cegis_operand_datat get_operand_signature(const symbol_tablet &st, // TODO: Add global vars cegis_operand_datat result; const code_typet &code_type=to_code_type(st.lookup(method).type); - const typet &return_type=code_type.return_type(); const std::string ret_val_name(get_return_value_name(method)); if (st.has_symbol(ret_val_name)) result[st.lookup(ret_val_name).type]=1; for (const code_typet::parameterst::value_type ¶m : code_type.parameters()) From 18e15797ba98edcf5ac01d6339d4379f956d69fb Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 24 Jan 2017 15:13:44 +0000 Subject: [PATCH 043/166] Make unused return value explicit in source ... and hide it from the compiler. --- src/cegis/jsa/learn/extract_candidate.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cegis/jsa/learn/extract_candidate.cpp b/src/cegis/jsa/learn/extract_candidate.cpp index 89890f6e907..bc054fc94fd 100644 --- a/src/cegis/jsa/learn/extract_candidate.cpp +++ b/src/cegis/jsa/learn/extract_candidate.cpp @@ -19,8 +19,9 @@ inline bool is_integer(const std::string & s) { if (s.empty() || (!isdigit(s[0]) && s[0] != '-' && s[0] != '+')) return false; char *p; - strtol(s.c_str(), &p, 10); - return *p == 0; + long result=strtol(s.c_str(), &p, 10); + (void)result; // unused as just used for testing string format + return *p==0; } bool is_prog_name(const std::string &var_name, const std::string &prefix) From 1c74b6b6f8c8ab915ac2631eec4e814d414ff9a8 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Wed, 25 Jan 2017 13:01:19 +0000 Subject: [PATCH 044/166] cegis: uniform copyright headers, added missing ones --- src/cegis/cegis-util/cbmc_runner.cpp | 9 +++++++++ src/cegis/cegis-util/cbmc_runner.h | 2 +- src/cegis/cegis-util/constant_width.cpp | 9 +++++++++ src/cegis/cegis-util/constant_width.h | 2 +- src/cegis/cegis-util/counterexample_vars.cpp | 9 +++++++++ src/cegis/cegis-util/counterexample_vars.h | 2 +- src/cegis/cegis-util/goto_range.h | 8 ++++---- src/cegis/cegis-util/inline_user_program.cpp | 9 +++++++++ src/cegis/cegis-util/inline_user_program.h | 2 +- src/cegis/cegis-util/instruction_iterator.cpp | 9 +++++++++ src/cegis/cegis-util/instruction_iterator.h | 10 +++++----- src/cegis/cegis-util/irep_pipe.cpp | 9 +++++++++ src/cegis/cegis-util/irep_pipe.h | 8 ++++---- src/cegis/cegis-util/iterator_helper.h | 8 ++++---- src/cegis/cegis-util/labelled_assignments.h | 2 +- src/cegis/cegis-util/module_helper.cpp | 9 +++++++++ src/cegis/cegis-util/module_helper.h | 2 +- src/cegis/cegis-util/program_helper.cpp | 9 +++++++++ src/cegis/cegis-util/program_helper.h | 8 ++++---- src/cegis/cegis-util/string_helper.cpp | 9 +++++++++ src/cegis/cegis-util/string_helper.h | 2 +- src/cegis/cegis-util/task_pool.cpp | 9 +++++++++ src/cegis/cegis-util/task_pool.h | 8 ++++---- src/cegis/cegis-util/temporary_output_block.cpp | 9 +++++++++ src/cegis/cegis-util/temporary_output_block.h | 2 +- src/cegis/cegis-util/type_helper.cpp | 9 +++++++++ src/cegis/cegis-util/type_helper.h | 10 +++++----- src/cegis/constant/add_constant.cpp | 9 +++++++++ src/cegis/constant/add_constant.h | 2 +- .../constant/default_cegis_constant_strategy.cpp | 9 +++++++++ .../constant/default_cegis_constant_strategy.h | 8 ++++---- src/cegis/constant/literals_collector.cpp | 9 +++++++++ src/cegis/constant/literals_collector.h | 2 +- src/cegis/control/facade/control_runner.cpp | 9 +++++++++ src/cegis/control/facade/control_runner.h | 8 ++++---- src/cegis/control/learn/control_symex_learn.h | 8 ++++---- src/cegis/control/learn/nondet_solution.cpp | 9 +++++++++ src/cegis/control/learn/nondet_solution.h | 8 ++++---- src/cegis/control/learn/print_control_solution.cpp | 9 +++++++++ src/cegis/control/learn/print_control_solution.h | 8 ++++---- .../learn/rational_solution_configuration.cpp | 9 +++++++++ .../learn/rational_solution_configuration.h | 8 ++++---- .../learn/vector_solution_configuration.cpp | 9 +++++++++ .../control/learn/vector_solution_configuration.h | 8 ++++---- src/cegis/control/options/control_program.cpp | 9 +++++++++ src/cegis/control/options/control_program.h | 8 ++++---- .../preprocessing/control_preprocessing.cpp | 9 +++++++++ .../control/preprocessing/control_preprocessing.h | 2 +- .../preprocessing/propagate_controller_sizes.cpp | 9 +++++++++ .../preprocessing/propagate_controller_sizes.h | 8 ++++---- .../control/simplify/remove_unused_elements.cpp | 9 +++++++++ .../control/simplify/remove_unused_elements.h | 2 +- src/cegis/control/value/control_counterexample.h | 2 +- src/cegis/control/value/control_solution.h | 8 ++++---- src/cegis/control/value/control_types.cpp | 9 +++++++++ src/cegis/control/value/control_types.h | 8 ++++---- src/cegis/control/value/control_vars.h | 8 ++++---- .../control/value/control_vector_solution.cpp | 9 +++++++++ src/cegis/control/value/control_vector_solution.h | 8 ++++---- src/cegis/control/value/float_helper.cpp | 9 +++++++++ src/cegis/control/value/float_helper.h | 8 ++++---- src/cegis/control/verify/control_symex_verify.h | 8 ++++---- src/cegis/control/verify/insert_solution.cpp | 9 +++++++++ src/cegis/control/verify/insert_solution.h | 9 ++++----- src/cegis/control/verify/zero_solutions.cpp | 9 +++++++++ src/cegis/control/verify/zero_solutions.h | 8 ++++---- .../constraint/danger_constraint_factory.cpp | 9 +++++++++ .../danger/constraint/danger_constraint_factory.h | 8 ++++---- src/cegis/danger/facade/danger_runner.cpp | 9 +++++++++ src/cegis/danger/facade/danger_runner.h | 2 +- .../danger/genetic/dynamic_danger_test_runner.cpp | 9 +++++++++ .../danger/genetic/dynamic_danger_test_runner.h | 8 ++++---- src/cegis/danger/meta/literals.h | 8 ++++---- src/cegis/danger/meta/meta_variable_names.cpp | 9 +++++++++ src/cegis/danger/meta/meta_variable_names.h | 8 ++++---- src/cegis/danger/options/danger_program.cpp | 9 +++++++++ src/cegis/danger/options/danger_program.h | 8 ++++---- .../options/danger_program_genetic_settings.h | 8 ++++---- .../danger/options/danger_program_printer.cpp | 9 +++++++++ src/cegis/danger/options/danger_program_printer.h | 8 ++++---- .../add_ranking_and_skolem_variables.cpp | 9 +++++++++ .../preprocess/add_ranking_and_skolem_variables.h | 8 ++++---- .../danger/preprocess/danger_preprocessing.cpp | 9 +++++++++ src/cegis/danger/preprocess/danger_preprocessing.h | 8 ++++---- .../danger/preprocess/store_nondet_choices.cpp | 9 +++++++++ src/cegis/danger/preprocess/store_nondet_choices.h | 8 ++++---- .../danger/symex/fitness/danger_fitness_config.cpp | 9 +++++++++ .../danger/symex/fitness/danger_fitness_config.h | 8 ++++---- .../danger/symex/learn/add_programs_to_learn.cpp | 9 +++++++++ .../danger/symex/learn/add_programs_to_learn.h | 8 ++++---- src/cegis/danger/symex/learn/add_variable_refs.cpp | 9 +++++++++ src/cegis/danger/symex/learn/add_variable_refs.h | 8 ++++---- .../danger/symex/learn/add_x0_placeholders.cpp | 9 +++++++++ src/cegis/danger/symex/learn/add_x0_placeholders.h | 2 +- .../danger/symex/learn/danger_learn_config.cpp | 9 +++++++++ src/cegis/danger/symex/learn/danger_learn_config.h | 8 ++++---- .../symex/learn/encoded_danger_learn_config.cpp | 9 +++++++++ .../symex/learn/encoded_danger_learn_config.h | 8 ++++---- src/cegis/danger/symex/learn/read_x0.cpp | 9 +++++++++ src/cegis/danger/symex/learn/read_x0.h | 8 ++++---- src/cegis/danger/symex/learn/solution_factory.cpp | 9 +++++++++ src/cegis/danger/symex/learn/solution_factory.h | 8 ++++---- .../danger/symex/verify/danger_verify_config.cpp | 9 +++++++++ .../danger/symex/verify/danger_verify_config.h | 2 +- src/cegis/danger/symex/verify/insert_candidate.cpp | 9 +++++++++ src/cegis/danger/symex/verify/insert_candidate.h | 2 +- .../symex/verify/parallel_danger_verifier.cpp | 9 +++++++++ .../danger/symex/verify/parallel_danger_verifier.h | 8 ++++---- .../symex/verify/parallel_danger_verify_task.cpp | 9 +++++++++ .../symex/verify/parallel_danger_verify_task.h | 8 ++++---- .../symex/verify/restrict_counterexamples.cpp | 9 +++++++++ .../danger/symex/verify/restrict_counterexamples.h | 8 ++++---- src/cegis/danger/value/danger_goto_solution.h | 8 ++++---- src/cegis/facade/cegis.h | 2 +- src/cegis/facade/runner_helper.h | 2 +- src/cegis/genetic/concrete_test_runner.cpp | 9 +++++++++ src/cegis/genetic/concrete_test_runner.h | 8 ++++---- src/cegis/genetic/dynamic_test_runner_helper.cpp | 9 +++++++++ src/cegis/genetic/dynamic_test_runner_helper.h | 8 ++++---- src/cegis/genetic/family_selection.h | 2 +- src/cegis/genetic/ga_learn.h | 2 +- src/cegis/genetic/genetic_constant_strategy.cpp | 9 +++++++++ src/cegis/genetic/genetic_constant_strategy.h | 8 ++++---- src/cegis/genetic/genetic_preprocessing.h | 8 ++++---- src/cegis/genetic/genetic_settings.cpp | 9 +++++++++ src/cegis/genetic/genetic_settings.h | 2 +- src/cegis/genetic/instruction_set_info_factory.cpp | 9 +++++++++ src/cegis/genetic/instruction_set_info_factory.h | 2 +- src/cegis/genetic/lazy_fitness.h | 8 ++++---- src/cegis/genetic/lazy_genetic_settings.h | 14 ++++++++------ src/cegis/genetic/learn_preprocess_seed.h | 2 +- src/cegis/genetic/match_select.cpp | 9 +++++++++ src/cegis/genetic/match_select.h | 10 +++++----- .../program_individual_test_runner_helper.cpp | 9 +++++++++ .../program_individual_test_runner_helper.h | 10 +++++----- src/cegis/genetic/random_cross.cpp | 9 +++++++++ src/cegis/genetic/random_cross.h | 8 ++++---- src/cegis/genetic/random_individual.cpp | 9 +++++++++ src/cegis/genetic/random_individual.h | 8 ++++---- src/cegis/genetic/random_mutate.cpp | 9 +++++++++ src/cegis/genetic/random_mutate.h | 8 ++++---- src/cegis/genetic/serialise_individual.cpp | 9 +++++++++ src/cegis/genetic/serialise_individual.h | 10 +++++----- src/cegis/genetic/symex_test_runner.h | 8 ++++---- src/cegis/genetic/tournament_select.cpp | 9 +++++++++ src/cegis/genetic/tournament_select.h | 8 ++++---- src/cegis/instructions/instruction_set_factory.cpp | 9 +++++++++ src/cegis/instructions/instruction_set_factory.h | 8 ++++---- src/cegis/instrument/cegis_library.cpp | 9 +++++++++ src/cegis/instrument/cegis_library.h | 2 +- src/cegis/instrument/find_cprover_initialize.cpp | 9 +++++++++ src/cegis/instrument/find_cprover_initialize.h | 8 ++++---- src/cegis/instrument/instrument_var_ops.cpp | 9 +++++++++ src/cegis/instrument/instrument_var_ops.h | 8 ++++---- src/cegis/instrument/literals.h | 8 ++++---- src/cegis/instrument/meta_variables.cpp | 9 +++++++++ src/cegis/instrument/meta_variables.h | 8 ++++---- src/cegis/invariant/constant/add_constant.cpp | 9 +++++++++ src/cegis/invariant/constant/add_constant.h | 2 +- src/cegis/invariant/constant/constant_strategy.h | 2 +- .../constant/default_constant_strategy.cpp | 9 +++++++++ .../invariant/constant/default_constant_strategy.h | 2 +- .../constant/literals_constant_strategy.cpp | 9 +++++++++ .../constant/literals_constant_strategy.h | 2 +- .../fitness/concrete_fitness_source_provider.cpp | 9 +++++++++ .../fitness/concrete_fitness_source_provider.h | 8 ++++---- src/cegis/invariant/meta/meta_variable_names.cpp | 9 +++++++++ src/cegis/invariant/meta/meta_variable_names.h | 8 ++++---- src/cegis/invariant/options/invariant_program.cpp | 9 +++++++++ src/cegis/invariant/options/invariant_program.h | 8 ++++---- src/cegis/invariant/options/target_copy_helper.cpp | 9 +++++++++ src/cegis/invariant/options/target_copy_helper.h | 8 ++++---- .../add_invariants_and_temp_variables.cpp | 9 +++++++++ .../preprocess/add_invariants_and_temp_variables.h | 8 ++++---- .../preprocess/remove_loops_and_assertion.cpp | 9 +++++++++ .../preprocess/remove_loops_and_assertion.h | 8 ++++---- .../invariant/symex/learn/add_counterexamples.cpp | 9 +++++++++ .../invariant/symex/learn/add_counterexamples.h | 8 ++++---- .../learn/add_invariant_programs_to_learn.cpp | 9 +++++++++ .../symex/learn/add_invariant_programs_to_learn.h | 8 ++++---- .../invariant/symex/learn/instrument_vars.cpp | 9 +++++++++ src/cegis/invariant/symex/learn/instrument_vars.h | 8 ++++---- .../symex/learn/invariant_body_provider.h | 10 +++++----- .../invariant/symex/learn/replace_operators.cpp | 9 +++++++++ .../invariant/symex/learn/replace_operators.h | 8 ++++---- .../symex/verify/extract_counterexample.cpp | 9 +++++++++ .../symex/verify/extract_counterexample.h | 8 ++++---- .../invariant/symex/verify/insert_constraint.cpp | 9 +++++++++ .../invariant/symex/verify/insert_constraint.h | 8 ++++---- .../invariant/symex/verify/insert_program.cpp | 9 +++++++++ src/cegis/invariant/symex/verify/insert_program.h | 2 +- src/cegis/invariant/util/copy_instructions.cpp | 9 +++++++++ src/cegis/invariant/util/copy_instructions.h | 8 ++++---- .../util/invariant_constraint_variables.cpp | 9 +++++++++ .../util/invariant_constraint_variables.h | 8 ++++---- .../invariant/util/invariant_program_helper.cpp | 9 +++++++++ .../invariant/util/invariant_program_helper.h | 8 ++++---- .../jsa/constraint/jsa_constraint_factory.cpp | 9 +++++++++ src/cegis/jsa/constraint/jsa_constraint_factory.h | 2 +- src/cegis/jsa/converters/counterexample.cpp | 9 +++++++++ src/cegis/jsa/converters/counterexample.h | 2 +- src/cegis/jsa/converters/replace_operators.cpp | 9 +++++++++ src/cegis/jsa/converters/replace_operators.h | 2 +- src/cegis/jsa/converters/solution.cpp | 9 +++++++++ src/cegis/jsa/converters/solution.h | 2 +- .../jsa/converters/translate_to_goto_program.cpp | 9 +++++++++ .../jsa/converters/translate_to_goto_program.h | 2 +- src/cegis/jsa/facade/jsa_runner.cpp | 9 +++++++++ src/cegis/jsa/facade/jsa_runner.h | 2 +- src/cegis/jsa/genetic/dynamic_jsa_test_runner.cpp | 9 +++++++++ src/cegis/jsa/genetic/dynamic_jsa_test_runner.h | 2 +- src/cegis/jsa/genetic/jsa_genetic_convert.cpp | 9 +++++++++ src/cegis/jsa/genetic/jsa_genetic_convert.h | 2 +- src/cegis/jsa/genetic/jsa_paragon_wrapper.cpp | 9 +++++++++ src/cegis/jsa/genetic/jsa_paragon_wrapper.h | 8 ++++---- src/cegis/jsa/genetic/jsa_random.cpp | 9 +++++++++ src/cegis/jsa/genetic/jsa_random.h | 10 +++++----- src/cegis/jsa/genetic/jsa_serialiser.cpp | 9 +++++++++ src/cegis/jsa/genetic/jsa_serialiser.h | 2 +- src/cegis/jsa/genetic/jsa_source_provider.cpp | 9 +++++++++ src/cegis/jsa/genetic/jsa_source_provider.h | 8 ++++---- src/cegis/jsa/genetic/random_jsa_cross.cpp | 9 +++++++++ src/cegis/jsa/genetic/random_jsa_cross.h | 2 +- src/cegis/jsa/genetic/random_jsa_mutate.cpp | 9 +++++++++ src/cegis/jsa/genetic/random_jsa_mutate.h | 2 +- src/cegis/jsa/genetic/solution_helper.cpp | 9 +++++++++ src/cegis/jsa/genetic/solution_helper.h | 8 ++++---- src/cegis/jsa/instrument/jsa_meta_data.cpp | 9 +++++++++ src/cegis/jsa/instrument/jsa_meta_data.h | 2 +- src/cegis/jsa/instrument/temps_helper.cpp | 9 +++++++++ src/cegis/jsa/instrument/temps_helper.h | 2 +- src/cegis/jsa/learn/execute_jsa_programs.cpp | 9 +++++++++ src/cegis/jsa/learn/execute_jsa_programs.h | 2 +- src/cegis/jsa/learn/extract_candidate.cpp | 9 +++++++++ src/cegis/jsa/learn/extract_candidate.h | 2 +- src/cegis/jsa/learn/insert_counterexample.cpp | 9 +++++++++ src/cegis/jsa/learn/insert_counterexample.h | 2 +- .../jsa/learn/insert_predicates_and_queries.cpp | 9 +++++++++ .../jsa/learn/insert_predicates_and_queries.h | 2 +- src/cegis/jsa/learn/instrument_pred_ops.cpp | 9 +++++++++ src/cegis/jsa/learn/instrument_pred_ops.h | 2 +- src/cegis/jsa/learn/jsa_symex_learn.cpp | 9 +++++++++ src/cegis/jsa/learn/jsa_symex_learn.h | 2 +- src/cegis/jsa/options/jsa_program.cpp | 9 +++++++++ src/cegis/jsa/options/jsa_program.h | 2 +- src/cegis/jsa/options/jsa_program_info.cpp | 9 +++++++++ src/cegis/jsa/options/jsa_program_info.h | 10 +++++----- .../add_constraint_meta_variables.cpp | 9 +++++++++ .../preprocessing/add_constraint_meta_variables.h | 2 +- .../jsa/preprocessing/add_synthesis_library.cpp | 9 +++++++++ .../jsa/preprocessing/add_synthesis_library.h | 2 +- src/cegis/jsa/preprocessing/clone_heap.cpp | 9 +++++++++ src/cegis/jsa/preprocessing/clone_heap.h | 2 +- src/cegis/jsa/preprocessing/collect_variables.cpp | 9 +++++++++ src/cegis/jsa/preprocessing/collect_variables.h | 2 +- .../jsa/preprocessing/create_temp_variables.cpp | 9 +++++++++ .../jsa/preprocessing/create_temp_variables.h | 2 +- .../default_jsa_constant_strategy.cpp | 9 +++++++++ .../preprocessing/default_jsa_constant_strategy.h | 8 ++++---- .../jsa/preprocessing/inline_user_program.cpp | 9 +++++++++ src/cegis/jsa/preprocessing/inline_user_program.h | 2 +- src/cegis/jsa/preprocessing/jsa_preprocessing.cpp | 9 +++++++++ src/cegis/jsa/preprocessing/jsa_preprocessing.h | 2 +- src/cegis/jsa/preprocessing/remove_loop.cpp | 9 +++++++++ src/cegis/jsa/preprocessing/remove_loop.h | 2 +- src/cegis/jsa/value/default_solution.cpp | 9 +++++++++ src/cegis/jsa/value/default_solution.h | 2 +- src/cegis/jsa/value/jsa_counterexample.h | 2 +- src/cegis/jsa/value/jsa_counterexample_printer.cpp | 9 +++++++++ src/cegis/jsa/value/jsa_counterexample_printer.h | 2 +- src/cegis/jsa/value/jsa_genetic_counterexample.h | 2 +- src/cegis/jsa/value/jsa_genetic_solution.h | 2 +- src/cegis/jsa/value/jsa_genetic_synthesis.h | 9 +++++++++ src/cegis/jsa/value/jsa_solution.cpp | 9 +++++++++ src/cegis/jsa/value/jsa_solution.h | 2 +- src/cegis/jsa/value/jsa_solution_printer.cpp | 9 +++++++++ src/cegis/jsa/value/jsa_solution_printer.h | 2 +- src/cegis/jsa/value/jsa_types.cpp | 9 +++++++++ src/cegis/jsa/value/jsa_types.h | 2 +- src/cegis/jsa/value/pred_ops.h | 2 +- src/cegis/jsa/verify/extract_counterexample.cpp | 9 +++++++++ src/cegis/jsa/verify/extract_counterexample.h | 2 +- src/cegis/jsa/verify/insert_solution.cpp | 9 +++++++++ src/cegis/jsa/verify/insert_solution.h | 2 +- src/cegis/jsa/verify/jsa_symex_verify.cpp | 9 +++++++++ src/cegis/jsa/verify/jsa_symex_verify.h | 2 +- src/cegis/jsa/verify/renondet_inputs.cpp | 9 +++++++++ src/cegis/jsa/verify/renondet_inputs.h | 2 +- src/cegis/learn/concurrent_learn.h | 8 ++++---- src/cegis/learn/constraint_helper.cpp | 9 +++++++++ src/cegis/learn/constraint_helper.h | 10 +++++----- src/cegis/learn/insert_counterexample.cpp | 9 +++++++++ src/cegis/learn/insert_counterexample.h | 2 +- src/cegis/options/parameters.h | 10 +++++----- .../refactor/constraint/constraint_factory.cpp | 9 +++++++++ src/cegis/refactor/constraint/constraint_factory.h | 10 +++++----- .../refactor/environment/instrument_state_vars.cpp | 9 +++++++++ .../refactor/environment/instrument_state_vars.h | 10 +++++----- src/cegis/refactor/facade/refactor_runner.cpp | 9 +++++++++ src/cegis/refactor/facade/refactor_runner.h | 10 +++++----- .../instructionset/cegis_instruction_factory.cpp | 9 +++++++++ .../instructionset/cegis_instruction_factory.h | 2 +- .../cegis_processor_body_factory.cpp | 9 +++++++++ .../instructionset/cegis_processor_body_factory.h | 10 +++++----- .../instructionset/create_cegis_processor.cpp | 9 +++++++++ .../instructionset/create_cegis_processor.h | 10 +++++----- .../instructionset/execute_cegis_program.cpp | 9 +++++++++ .../instructionset/execute_cegis_program.h | 8 ++++---- .../instructionset/instruction_description.cpp | 9 +++++++++ .../instructionset/instruction_description.h | 2 +- src/cegis/refactor/instructionset/operand_data.h | 2 +- .../refactor/instructionset/processor_symbols.cpp | 9 +++++++++ .../refactor/instructionset/processor_symbols.h | 8 ++++---- .../refactor/instructionset/processor_types.cpp | 9 +++++++++ .../refactor/instructionset/processor_types.h | 8 ++++---- .../refactor/learn/instrument_counterexamples.cpp | 9 +++++++++ .../refactor/learn/instrument_counterexamples.h | 8 ++++---- .../refactor/learn/refactor_candidate_printer.cpp | 9 +++++++++ .../refactor/learn/refactor_candidate_printer.h | 8 ++++---- src/cegis/refactor/learn/refactor_symex_learn.cpp | 9 +++++++++ src/cegis/refactor/learn/refactor_symex_learn.h | 8 ++++---- .../refactor/nullobject/nullable_analysis.cpp | 9 +++++++++ src/cegis/refactor/nullobject/nullable_analysis.h | 8 ++++---- src/cegis/refactor/nullobject/range_collector.cpp | 9 +++++++++ src/cegis/refactor/nullobject/range_collector.h | 10 +++++----- src/cegis/refactor/options/refactor_program.cpp | 9 +++++++++ src/cegis/refactor/options/refactor_program.h | 8 ++++---- src/cegis/refactor/options/refactoring_type.cpp | 9 +++++++++ src/cegis/refactor/options/refactoring_type.h | 10 +++++----- .../preprocessing/collect_counterexamples.cpp | 9 +++++++++ .../preprocessing/collect_counterexamples.h | 10 +++++----- .../preprocessing/refactor_preprocessing.cpp | 9 +++++++++ .../preprocessing/refactor_preprocessing.h | 10 +++++----- src/cegis/refactor/value/refactor_counterexample.h | 2 +- src/cegis/refactor/value/refactor_solution.h | 10 +++++----- .../refactor/verify/refactor_symex_verify.cpp | 9 +++++++++ src/cegis/refactor/verify/refactor_symex_verify.h | 8 ++++---- .../constraint/safety_constraint_factory.cpp | 9 +++++++++ .../safety/constraint/safety_constraint_factory.h | 8 ++++---- src/cegis/safety/facade/safety_runner.cpp | 9 +++++++++ src/cegis/safety/facade/safety_runner.h | 2 +- .../safety/genetic/dynamic_safety_test_runner.cpp | 9 +++++++++ .../safety/genetic/dynamic_safety_test_runner.h | 8 ++++---- src/cegis/safety/meta/meta_variable_names.cpp | 9 +++++++++ src/cegis/safety/meta/meta_variable_names.h | 8 ++++---- src/cegis/safety/options/safety_program.cpp | 9 +++++++++ src/cegis/safety/options/safety_program.h | 8 ++++---- .../options/safety_program_genetic_settings.h | 8 ++++---- .../safety/options/safety_program_printer.cpp | 9 +++++++++ src/cegis/safety/options/safety_program_printer.h | 8 ++++---- .../safety/preprocessing/safety_preprocessing.cpp | 9 +++++++++ .../safety/preprocessing/safety_preprocessing.h | 8 ++++---- .../safety/symex/fitness/safety_fitness_config.cpp | 9 +++++++++ .../safety/symex/fitness/safety_fitness_config.h | 8 ++++---- .../safety/symex/learn/add_counterexamples.cpp | 9 +++++++++ src/cegis/safety/symex/learn/add_counterexamples.h | 8 ++++---- src/cegis/safety/symex/learn/add_variable_refs.cpp | 9 +++++++++ src/cegis/safety/symex/learn/add_variable_refs.h | 9 +++++++++ .../symex/learn/encoded_safety_learn_config.cpp | 9 +++++++++ .../symex/learn/encoded_safety_learn_config.h | 8 ++++---- .../safety/symex/learn/safety_learn_config.cpp | 9 +++++++++ src/cegis/safety/symex/learn/safety_learn_config.h | 8 ++++---- src/cegis/safety/symex/learn/solution_factory.cpp | 9 +++++++++ src/cegis/safety/symex/learn/solution_factory.h | 8 ++++---- src/cegis/safety/symex/verify/insert_candidate.cpp | 9 +++++++++ src/cegis/safety/symex/verify/insert_candidate.h | 2 +- .../safety/symex/verify/safety_verify_config.cpp | 9 +++++++++ .../safety/symex/verify/safety_verify_config.h | 2 +- .../individual_to_safety_solution_deserialiser.cpp | 9 +++++++++ .../individual_to_safety_solution_deserialiser.h | 8 ++++---- src/cegis/safety/value/safety_goto_ce.cpp | 9 +++++++++ src/cegis/safety/value/safety_goto_ce.h | 8 ++++---- src/cegis/safety/value/safety_goto_solution.h | 8 ++++---- src/cegis/seed/literals_seed.cpp | 9 +++++++++ src/cegis/seed/literals_seed.h | 2 +- src/cegis/seed/null_seed.h | 2 +- src/cegis/statistics/cegis_statistics_wrapper.h | 2 +- src/cegis/symex/cegis_symex_learn.h | 10 +++++----- src/cegis/symex/cegis_symex_verify.h | 2 +- src/cegis/value/assignments_printer.cpp | 9 +++++++++ src/cegis/value/assignments_printer.h | 2 +- src/cegis/value/program_individual.h | 2 +- .../value/program_individual_serialisation.cpp | 9 +++++++++ src/cegis/value/program_individual_serialisation.h | 8 ++++---- src/cegis/wordsize/limited_wordsize_verify.h | 10 +++++----- src/cegis/wordsize/restrict_bv_size.cpp | 9 +++++++++ src/cegis/wordsize/restrict_bv_size.h | 2 +- 387 files changed, 2191 insertions(+), 615 deletions(-) diff --git a/src/cegis/cegis-util/cbmc_runner.cpp b/src/cegis/cegis-util/cbmc_runner.cpp index 995ad34c355..58739658ab1 100644 --- a/src/cegis/cegis-util/cbmc_runner.cpp +++ b/src/cegis/cegis-util/cbmc_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/cegis-util/cbmc_runner.h b/src/cegis/cegis-util/cbmc_runner.h index 6317ca444c2..364be5ca2a5 100644 --- a/src/cegis/cegis-util/cbmc_runner.h +++ b/src/cegis/cegis-util/cbmc_runner.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/cegis-util/constant_width.cpp b/src/cegis/cegis-util/constant_width.cpp index 3ee1a74faf6..4f951e35694 100644 --- a/src/cegis/cegis-util/constant_width.cpp +++ b/src/cegis/cegis-util/constant_width.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include "constant_width.h" diff --git a/src/cegis/cegis-util/constant_width.h b/src/cegis/cegis-util/constant_width.h index 0e53b29a20e..94effe58964 100644 --- a/src/cegis/cegis-util/constant_width.h +++ b/src/cegis/cegis-util/constant_width.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/cegis-util/counterexample_vars.cpp b/src/cegis/cegis-util/counterexample_vars.cpp index b130324cdf0..f0593f7f486 100644 --- a/src/cegis/cegis-util/counterexample_vars.cpp +++ b/src/cegis/cegis-util/counterexample_vars.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/cegis-util/counterexample_vars.h b/src/cegis/cegis-util/counterexample_vars.h index b0e68f4f91c..9604c63b346 100644 --- a/src/cegis/cegis-util/counterexample_vars.h +++ b/src/cegis/cegis-util/counterexample_vars.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/cegis-util/goto_range.h b/src/cegis/cegis-util/goto_range.h index a34685336cf..be17f1cdba0 100644 --- a/src/cegis/cegis-util/goto_range.h +++ b/src/cegis/cegis-util/goto_range.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/cegis-util/inline_user_program.cpp b/src/cegis/cegis-util/inline_user_program.cpp index 11fb3d92bb7..8a34803d62f 100644 --- a/src/cegis/cegis-util/inline_user_program.cpp +++ b/src/cegis/cegis-util/inline_user_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/cegis-util/inline_user_program.h b/src/cegis/cegis-util/inline_user_program.h index 41a4b332e0a..4bcc9a0c2c2 100644 --- a/src/cegis/cegis-util/inline_user_program.h +++ b/src/cegis/cegis-util/inline_user_program.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/cegis-util/instruction_iterator.cpp b/src/cegis/cegis-util/instruction_iterator.cpp index 6b8d5df5fd3..f6dbaca1eda 100644 --- a/src/cegis/cegis-util/instruction_iterator.cpp +++ b/src/cegis/cegis-util/instruction_iterator.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include namespace diff --git a/src/cegis/cegis-util/instruction_iterator.h b/src/cegis/cegis-util/instruction_iterator.h index 94044e3cfc3..40b289f88e9 100644 --- a/src/cegis/cegis-util/instruction_iterator.h +++ b/src/cegis/cegis-util/instruction_iterator.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_CEGIS_UTIL_INSTRUCTION_ITERATOR_H #define CPROVER_CEGIS_CEGIS_UTIL_INSTRUCTION_ITERATOR_H diff --git a/src/cegis/cegis-util/irep_pipe.cpp b/src/cegis/cegis-util/irep_pipe.cpp index 3a309e9e048..40300014409 100644 --- a/src/cegis/cegis-util/irep_pipe.cpp +++ b/src/cegis/cegis-util/irep_pipe.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/cegis-util/irep_pipe.h b/src/cegis/cegis-util/irep_pipe.h index f35980d2cc3..aa74b31c760 100644 --- a/src/cegis/cegis-util/irep_pipe.h +++ b/src/cegis/cegis-util/irep_pipe.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/cegis-util/iterator_helper.h b/src/cegis/cegis-util/iterator_helper.h index cc92868ba13..bbd7369cd33 100644 --- a/src/cegis/cegis-util/iterator_helper.h +++ b/src/cegis/cegis-util/iterator_helper.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/cegis-util/labelled_assignments.h b/src/cegis/cegis-util/labelled_assignments.h index fbe98008b01..1784731b4f0 100644 --- a/src/cegis/cegis-util/labelled_assignments.h +++ b/src/cegis/cegis-util/labelled_assignments.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/cegis-util/module_helper.cpp b/src/cegis/cegis-util/module_helper.cpp index 14e2f4fe2be..b4fd6e0157a 100644 --- a/src/cegis/cegis-util/module_helper.cpp +++ b/src/cegis/cegis-util/module_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #ifdef _WIN32 #include #else diff --git a/src/cegis/cegis-util/module_helper.h b/src/cegis/cegis-util/module_helper.h index ad5283f099b..6c7413c78b0 100644 --- a/src/cegis/cegis-util/module_helper.h +++ b/src/cegis/cegis-util/module_helper.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/cegis-util/program_helper.cpp b/src/cegis/cegis-util/program_helper.cpp index c50eb0e8c90..673510d8b04 100644 --- a/src/cegis/cegis-util/program_helper.cpp +++ b/src/cegis/cegis-util/program_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/cegis-util/program_helper.h b/src/cegis/cegis-util/program_helper.h index f6e1249cf7d..b2476d228a6 100644 --- a/src/cegis/cegis-util/program_helper.h +++ b/src/cegis/cegis-util/program_helper.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/cegis-util/string_helper.cpp b/src/cegis/cegis-util/string_helper.cpp index 5486acfa81a..883550d0c90 100644 --- a/src/cegis/cegis-util/string_helper.cpp +++ b/src/cegis/cegis-util/string_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/cegis-util/string_helper.h b/src/cegis/cegis-util/string_helper.h index 26c987d08c8..3aedc93f68b 100644 --- a/src/cegis/cegis-util/string_helper.h +++ b/src/cegis/cegis-util/string_helper.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/cegis-util/task_pool.cpp b/src/cegis/cegis-util/task_pool.cpp index c5b9cef59f2..769dc49be79 100644 --- a/src/cegis/cegis-util/task_pool.cpp +++ b/src/cegis/cegis-util/task_pool.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #ifndef _WIN32 #include #include diff --git a/src/cegis/cegis-util/task_pool.h b/src/cegis/cegis-util/task_pool.h index 62b8266023f..d7c0dafc168 100644 --- a/src/cegis/cegis-util/task_pool.h +++ b/src/cegis/cegis-util/task_pool.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Util +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/cegis-util/temporary_output_block.cpp b/src/cegis/cegis-util/temporary_output_block.cpp index 07b3b122e88..d15641c6ca1 100644 --- a/src/cegis/cegis-util/temporary_output_block.cpp +++ b/src/cegis/cegis-util/temporary_output_block.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/cegis-util/temporary_output_block.h b/src/cegis/cegis-util/temporary_output_block.h index 20c7aa0a807..719cb0d1af1 100644 --- a/src/cegis/cegis-util/temporary_output_block.h +++ b/src/cegis/cegis-util/temporary_output_block.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/cegis-util/type_helper.cpp b/src/cegis/cegis-util/type_helper.cpp index c4b3266396d..b20ea9d08e6 100644 --- a/src/cegis/cegis-util/type_helper.cpp +++ b/src/cegis/cegis-util/type_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/cegis-util/type_helper.h b/src/cegis/cegis-util/type_helper.h index db86f15d57a..f8898d6344a 100644 --- a/src/cegis/cegis-util/type_helper.h +++ b/src/cegis/cegis-util/type_helper.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_CEGIS_UTIL_TYPE_HELPER_H #define CPROVER_CEGIS_CEGIS_UTIL_TYPE_HELPER_H diff --git a/src/cegis/constant/add_constant.cpp b/src/cegis/constant/add_constant.cpp index 4a2a762341f..29472aff5bc 100644 --- a/src/cegis/constant/add_constant.cpp +++ b/src/cegis/constant/add_constant.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/constant/add_constant.h b/src/cegis/constant/add_constant.h index 437a722ca53..5d61c80dde9 100644 --- a/src/cegis/constant/add_constant.h +++ b/src/cegis/constant/add_constant.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/constant/default_cegis_constant_strategy.cpp b/src/cegis/constant/default_cegis_constant_strategy.cpp index f7281a3cc7b..74fd4fac76a 100644 --- a/src/cegis/constant/default_cegis_constant_strategy.cpp +++ b/src/cegis/constant/default_cegis_constant_strategy.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/constant/default_cegis_constant_strategy.h b/src/cegis/constant/default_cegis_constant_strategy.h index ad952aaca76..2e687a1611e 100644 --- a/src/cegis/constant/default_cegis_constant_strategy.h +++ b/src/cegis/constant/default_cegis_constant_strategy.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/constant/literals_collector.cpp b/src/cegis/constant/literals_collector.cpp index 8ae3f85ba7f..7400815ef89 100644 --- a/src/cegis/constant/literals_collector.cpp +++ b/src/cegis/constant/literals_collector.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/constant/literals_collector.h b/src/cegis/constant/literals_collector.h index d25212f905e..85f12c19e99 100644 --- a/src/cegis/constant/literals_collector.h +++ b/src/cegis/constant/literals_collector.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/control/facade/control_runner.cpp b/src/cegis/control/facade/control_runner.cpp index 67621c5403d..8e6a2070dc6 100644 --- a/src/cegis/control/facade/control_runner.cpp +++ b/src/cegis/control/facade/control_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/facade/control_runner.h b/src/cegis/control/facade/control_runner.h index eb013720d56..f37974ec3ba 100644 --- a/src/cegis/control/facade/control_runner.h +++ b/src/cegis/control/facade/control_runner.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/learn/control_symex_learn.h b/src/cegis/control/learn/control_symex_learn.h index bedfb8e0203..0ec02f3c2b4 100644 --- a/src/cegis/control/learn/control_symex_learn.h +++ b/src/cegis/control/learn/control_symex_learn.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/learn/nondet_solution.cpp b/src/cegis/control/learn/nondet_solution.cpp index 0e4a8ce1718..7a7a4c710e5 100644 --- a/src/cegis/control/learn/nondet_solution.cpp +++ b/src/cegis/control/learn/nondet_solution.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/control/learn/nondet_solution.h b/src/cegis/control/learn/nondet_solution.h index e569373192e..9bdbcbb383e 100644 --- a/src/cegis/control/learn/nondet_solution.h +++ b/src/cegis/control/learn/nondet_solution.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/learn/print_control_solution.cpp b/src/cegis/control/learn/print_control_solution.cpp index b5a75264511..6b66990c7a5 100644 --- a/src/cegis/control/learn/print_control_solution.cpp +++ b/src/cegis/control/learn/print_control_solution.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/learn/print_control_solution.h b/src/cegis/control/learn/print_control_solution.h index 992321b8b15..2107dc16ad0 100644 --- a/src/cegis/control/learn/print_control_solution.h +++ b/src/cegis/control/learn/print_control_solution.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/learn/rational_solution_configuration.cpp b/src/cegis/control/learn/rational_solution_configuration.cpp index a1dc06b81d6..41fb7aa0cdc 100644 --- a/src/cegis/control/learn/rational_solution_configuration.cpp +++ b/src/cegis/control/learn/rational_solution_configuration.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/learn/rational_solution_configuration.h b/src/cegis/control/learn/rational_solution_configuration.h index 06dc3a78a51..407e8944141 100644 --- a/src/cegis/control/learn/rational_solution_configuration.h +++ b/src/cegis/control/learn/rational_solution_configuration.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/learn/vector_solution_configuration.cpp b/src/cegis/control/learn/vector_solution_configuration.cpp index fd7ee3c400d..5da8cdc3192 100644 --- a/src/cegis/control/learn/vector_solution_configuration.cpp +++ b/src/cegis/control/learn/vector_solution_configuration.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/learn/vector_solution_configuration.h b/src/cegis/control/learn/vector_solution_configuration.h index d720741f9f8..034ac38a876 100644 --- a/src/cegis/control/learn/vector_solution_configuration.h +++ b/src/cegis/control/learn/vector_solution_configuration.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/options/control_program.cpp b/src/cegis/control/options/control_program.cpp index 7f180d38d82..e8fd02460c2 100644 --- a/src/cegis/control/options/control_program.cpp +++ b/src/cegis/control/options/control_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/control/options/control_program.h b/src/cegis/control/options/control_program.h index ad8f99196b5..f8bab843305 100644 --- a/src/cegis/control/options/control_program.h +++ b/src/cegis/control/options/control_program.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/preprocessing/control_preprocessing.cpp b/src/cegis/control/preprocessing/control_preprocessing.cpp index b1067139a2c..d9b86289226 100644 --- a/src/cegis/control/preprocessing/control_preprocessing.cpp +++ b/src/cegis/control/preprocessing/control_preprocessing.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/preprocessing/control_preprocessing.h b/src/cegis/control/preprocessing/control_preprocessing.h index ff8601f19bb..3631a195003 100644 --- a/src/cegis/control/preprocessing/control_preprocessing.h +++ b/src/cegis/control/preprocessing/control_preprocessing.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/control/preprocessing/propagate_controller_sizes.cpp b/src/cegis/control/preprocessing/propagate_controller_sizes.cpp index c8373a9151c..48a1aece609 100644 --- a/src/cegis/control/preprocessing/propagate_controller_sizes.cpp +++ b/src/cegis/control/preprocessing/propagate_controller_sizes.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/preprocessing/propagate_controller_sizes.h b/src/cegis/control/preprocessing/propagate_controller_sizes.h index cb73f8f323d..0358270c62a 100644 --- a/src/cegis/control/preprocessing/propagate_controller_sizes.h +++ b/src/cegis/control/preprocessing/propagate_controller_sizes.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/simplify/remove_unused_elements.cpp b/src/cegis/control/simplify/remove_unused_elements.cpp index 7b5ed77ff2b..3bc35dd88cf 100644 --- a/src/cegis/control/simplify/remove_unused_elements.cpp +++ b/src/cegis/control/simplify/remove_unused_elements.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/simplify/remove_unused_elements.h b/src/cegis/control/simplify/remove_unused_elements.h index a02782b56da..ab0fdc0e151 100644 --- a/src/cegis/control/simplify/remove_unused_elements.h +++ b/src/cegis/control/simplify/remove_unused_elements.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/control/value/control_counterexample.h b/src/cegis/control/value/control_counterexample.h index 9b06c0ada6e..b09ce580997 100644 --- a/src/cegis/control/value/control_counterexample.h +++ b/src/cegis/control/value/control_counterexample.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/control/value/control_solution.h b/src/cegis/control/value/control_solution.h index c9791d066b1..3d135ebfd27 100644 --- a/src/cegis/control/value/control_solution.h +++ b/src/cegis/control/value/control_solution.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/value/control_types.cpp b/src/cegis/control/value/control_types.cpp index c38fcfa65cf..598ce3c8f75 100644 --- a/src/cegis/control/value/control_types.cpp +++ b/src/cegis/control/value/control_types.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/value/control_types.h b/src/cegis/control/value/control_types.h index eed77a48440..395c6f9218d 100644 --- a/src/cegis/control/value/control_types.h +++ b/src/cegis/control/value/control_types.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/value/control_vars.h b/src/cegis/control/value/control_vars.h index 3b8c8b94ec1..9a93729c788 100644 --- a/src/cegis/control/value/control_vars.h +++ b/src/cegis/control/value/control_vars.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/value/control_vector_solution.cpp b/src/cegis/control/value/control_vector_solution.cpp index 637104d8ab0..9ec0d622f88 100644 --- a/src/cegis/control/value/control_vector_solution.cpp +++ b/src/cegis/control/value/control_vector_solution.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include control_vector_solutiont::control_vector_solutiont() diff --git a/src/cegis/control/value/control_vector_solution.h b/src/cegis/control/value/control_vector_solution.h index a677bca8f8d..ec5d5de021a 100644 --- a/src/cegis/control/value/control_vector_solution.h +++ b/src/cegis/control/value/control_vector_solution.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/value/float_helper.cpp b/src/cegis/control/value/float_helper.cpp index 2ba17bbcc5c..39ac8fdbeb4 100644 --- a/src/cegis/control/value/float_helper.cpp +++ b/src/cegis/control/value/float_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/value/float_helper.h b/src/cegis/control/value/float_helper.h index 6a538317a5a..ee1a8652a31 100644 --- a/src/cegis/control/value/float_helper.h +++ b/src/cegis/control/value/float_helper.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/verify/control_symex_verify.h b/src/cegis/control/verify/control_symex_verify.h index b8039271d3b..e40f8dabce3 100644 --- a/src/cegis/control/verify/control_symex_verify.h +++ b/src/cegis/control/verify/control_symex_verify.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/control/verify/insert_solution.cpp b/src/cegis/control/verify/insert_solution.cpp index c447b182157..9c1fbe27642 100644 --- a/src/cegis/control/verify/insert_solution.cpp +++ b/src/cegis/control/verify/insert_solution.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/verify/insert_solution.h b/src/cegis/control/verify/insert_solution.h index 6215f0839ac..61e92c29d68 100644 --- a/src/cegis/control/verify/insert_solution.h +++ b/src/cegis/control/verify/insert_solution.h @@ -1,13 +1,12 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ - #ifndef CPROVER_CEGIS_CONTROL_VERIFY_INSERT_SOLUTION_H #define CPROVER_CEGIS_CONTROL_VERIFY_INSERT_SOLUTION_H diff --git a/src/cegis/control/verify/zero_solutions.cpp b/src/cegis/control/verify/zero_solutions.cpp index e5300638574..59468253271 100644 --- a/src/cegis/control/verify/zero_solutions.cpp +++ b/src/cegis/control/verify/zero_solutions.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/control/verify/zero_solutions.h b/src/cegis/control/verify/zero_solutions.h index 5dc3b617796..8e28c8767c4 100644 --- a/src/cegis/control/verify/zero_solutions.h +++ b/src/cegis/control/verify/zero_solutions.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/constraint/danger_constraint_factory.cpp b/src/cegis/danger/constraint/danger_constraint_factory.cpp index f158b1de807..5cea1a36dd2 100644 --- a/src/cegis/danger/constraint/danger_constraint_factory.cpp +++ b/src/cegis/danger/constraint/danger_constraint_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/danger/constraint/danger_constraint_factory.h b/src/cegis/danger/constraint/danger_constraint_factory.h index 860ed10f77c..140e397efb1 100644 --- a/src/cegis/danger/constraint/danger_constraint_factory.h +++ b/src/cegis/danger/constraint/danger_constraint_factory.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/facade/danger_runner.cpp b/src/cegis/danger/facade/danger_runner.cpp index 04722a22cbd..57ebc1f43e0 100644 --- a/src/cegis/danger/facade/danger_runner.cpp +++ b/src/cegis/danger/facade/danger_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/facade/danger_runner.h b/src/cegis/danger/facade/danger_runner.h index 1b6512eb264..b25579edfc0 100644 --- a/src/cegis/danger/facade/danger_runner.h +++ b/src/cegis/danger/facade/danger_runner.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/danger/genetic/dynamic_danger_test_runner.cpp b/src/cegis/danger/genetic/dynamic_danger_test_runner.cpp index 68b108281f8..ba874730b63 100644 --- a/src/cegis/danger/genetic/dynamic_danger_test_runner.cpp +++ b/src/cegis/danger/genetic/dynamic_danger_test_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/genetic/dynamic_danger_test_runner.h b/src/cegis/danger/genetic/dynamic_danger_test_runner.h index 5279099d0fb..ba0be5780a9 100644 --- a/src/cegis/danger/genetic/dynamic_danger_test_runner.h +++ b/src/cegis/danger/genetic/dynamic_danger_test_runner.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/meta/literals.h b/src/cegis/danger/meta/literals.h index b73a37ca971..f936d14b41b 100644 --- a/src/cegis/danger/meta/literals.h +++ b/src/cegis/danger/meta/literals.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/meta/meta_variable_names.cpp b/src/cegis/danger/meta/meta_variable_names.cpp index 83bad70b812..fff265aa752 100644 --- a/src/cegis/danger/meta/meta_variable_names.cpp +++ b/src/cegis/danger/meta/meta_variable_names.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/meta/meta_variable_names.h b/src/cegis/danger/meta/meta_variable_names.h index eb13216f5f6..6a36666713b 100644 --- a/src/cegis/danger/meta/meta_variable_names.h +++ b/src/cegis/danger/meta/meta_variable_names.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/options/danger_program.cpp b/src/cegis/danger/options/danger_program.cpp index 81110967d72..7b9e1d77dae 100644 --- a/src/cegis/danger/options/danger_program.cpp +++ b/src/cegis/danger/options/danger_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/options/danger_program.h b/src/cegis/danger/options/danger_program.h index a7024d89a34..96b350d3c7c 100644 --- a/src/cegis/danger/options/danger_program.h +++ b/src/cegis/danger/options/danger_program.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/options/danger_program_genetic_settings.h b/src/cegis/danger/options/danger_program_genetic_settings.h index 8fddcd52974..5f0b1e5c034 100644 --- a/src/cegis/danger/options/danger_program_genetic_settings.h +++ b/src/cegis/danger/options/danger_program_genetic_settings.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/options/danger_program_printer.cpp b/src/cegis/danger/options/danger_program_printer.cpp index ea1451da1d1..a889ad266df 100644 --- a/src/cegis/danger/options/danger_program_printer.cpp +++ b/src/cegis/danger/options/danger_program_printer.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/options/danger_program_printer.h b/src/cegis/danger/options/danger_program_printer.h index ae16b92fe08..3891f760374 100644 --- a/src/cegis/danger/options/danger_program_printer.h +++ b/src/cegis/danger/options/danger_program_printer.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/preprocess/add_ranking_and_skolem_variables.cpp b/src/cegis/danger/preprocess/add_ranking_and_skolem_variables.cpp index 597e6628e60..899a86bcc34 100644 --- a/src/cegis/danger/preprocess/add_ranking_and_skolem_variables.cpp +++ b/src/cegis/danger/preprocess/add_ranking_and_skolem_variables.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/preprocess/add_ranking_and_skolem_variables.h b/src/cegis/danger/preprocess/add_ranking_and_skolem_variables.h index 6097b181d90..e1cdfb47d1c 100644 --- a/src/cegis/danger/preprocess/add_ranking_and_skolem_variables.h +++ b/src/cegis/danger/preprocess/add_ranking_and_skolem_variables.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/preprocess/danger_preprocessing.cpp b/src/cegis/danger/preprocess/danger_preprocessing.cpp index 4a3d89f13d7..642ccffc713 100644 --- a/src/cegis/danger/preprocess/danger_preprocessing.cpp +++ b/src/cegis/danger/preprocess/danger_preprocessing.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/preprocess/danger_preprocessing.h b/src/cegis/danger/preprocess/danger_preprocessing.h index 816a3546160..b69ab0813b7 100644 --- a/src/cegis/danger/preprocess/danger_preprocessing.h +++ b/src/cegis/danger/preprocess/danger_preprocessing.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/preprocess/store_nondet_choices.cpp b/src/cegis/danger/preprocess/store_nondet_choices.cpp index d45f19b86ca..88246dd1bfa 100644 --- a/src/cegis/danger/preprocess/store_nondet_choices.cpp +++ b/src/cegis/danger/preprocess/store_nondet_choices.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/preprocess/store_nondet_choices.h b/src/cegis/danger/preprocess/store_nondet_choices.h index 1171096fbd3..b19a165c624 100644 --- a/src/cegis/danger/preprocess/store_nondet_choices.h +++ b/src/cegis/danger/preprocess/store_nondet_choices.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/fitness/danger_fitness_config.cpp b/src/cegis/danger/symex/fitness/danger_fitness_config.cpp index 86e59b9a3a7..2df293372be 100644 --- a/src/cegis/danger/symex/fitness/danger_fitness_config.cpp +++ b/src/cegis/danger/symex/fitness/danger_fitness_config.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/fitness/danger_fitness_config.h b/src/cegis/danger/symex/fitness/danger_fitness_config.h index ee474ba887f..d2fb750aa6c 100644 --- a/src/cegis/danger/symex/fitness/danger_fitness_config.h +++ b/src/cegis/danger/symex/fitness/danger_fitness_config.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/learn/add_programs_to_learn.cpp b/src/cegis/danger/symex/learn/add_programs_to_learn.cpp index dd1ca9db1d8..665ac91771e 100644 --- a/src/cegis/danger/symex/learn/add_programs_to_learn.cpp +++ b/src/cegis/danger/symex/learn/add_programs_to_learn.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/learn/add_programs_to_learn.h b/src/cegis/danger/symex/learn/add_programs_to_learn.h index d61fb6954ee..c8f1278c240 100644 --- a/src/cegis/danger/symex/learn/add_programs_to_learn.h +++ b/src/cegis/danger/symex/learn/add_programs_to_learn.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/learn/add_variable_refs.cpp b/src/cegis/danger/symex/learn/add_variable_refs.cpp index d6cfccbe6f6..412c92f1ac0 100644 --- a/src/cegis/danger/symex/learn/add_variable_refs.cpp +++ b/src/cegis/danger/symex/learn/add_variable_refs.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/learn/add_variable_refs.h b/src/cegis/danger/symex/learn/add_variable_refs.h index f980563a741..aa275c149dd 100644 --- a/src/cegis/danger/symex/learn/add_variable_refs.h +++ b/src/cegis/danger/symex/learn/add_variable_refs.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/learn/add_x0_placeholders.cpp b/src/cegis/danger/symex/learn/add_x0_placeholders.cpp index 1c62a0a5278..ebe7353d53c 100644 --- a/src/cegis/danger/symex/learn/add_x0_placeholders.cpp +++ b/src/cegis/danger/symex/learn/add_x0_placeholders.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/learn/add_x0_placeholders.h b/src/cegis/danger/symex/learn/add_x0_placeholders.h index 830746adbb2..f5ae6f3fbcf 100644 --- a/src/cegis/danger/symex/learn/add_x0_placeholders.h +++ b/src/cegis/danger/symex/learn/add_x0_placeholders.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/danger/symex/learn/danger_learn_config.cpp b/src/cegis/danger/symex/learn/danger_learn_config.cpp index 3e3999bef8e..159af723b91 100644 --- a/src/cegis/danger/symex/learn/danger_learn_config.cpp +++ b/src/cegis/danger/symex/learn/danger_learn_config.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/learn/danger_learn_config.h b/src/cegis/danger/symex/learn/danger_learn_config.h index 910402065aa..15be7ace25f 100644 --- a/src/cegis/danger/symex/learn/danger_learn_config.h +++ b/src/cegis/danger/symex/learn/danger_learn_config.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/learn/encoded_danger_learn_config.cpp b/src/cegis/danger/symex/learn/encoded_danger_learn_config.cpp index 2f5e9bff278..d9a995f3821 100644 --- a/src/cegis/danger/symex/learn/encoded_danger_learn_config.cpp +++ b/src/cegis/danger/symex/learn/encoded_danger_learn_config.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/learn/encoded_danger_learn_config.h b/src/cegis/danger/symex/learn/encoded_danger_learn_config.h index 8e9a2a1826d..f618b1c2f69 100644 --- a/src/cegis/danger/symex/learn/encoded_danger_learn_config.h +++ b/src/cegis/danger/symex/learn/encoded_danger_learn_config.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/learn/read_x0.cpp b/src/cegis/danger/symex/learn/read_x0.cpp index 825638fc51c..ba504cfa5b1 100644 --- a/src/cegis/danger/symex/learn/read_x0.cpp +++ b/src/cegis/danger/symex/learn/read_x0.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/learn/read_x0.h b/src/cegis/danger/symex/learn/read_x0.h index 433b1175c4b..b47620bac74 100644 --- a/src/cegis/danger/symex/learn/read_x0.h +++ b/src/cegis/danger/symex/learn/read_x0.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/learn/solution_factory.cpp b/src/cegis/danger/symex/learn/solution_factory.cpp index 02b02636d6b..ead676a3456 100644 --- a/src/cegis/danger/symex/learn/solution_factory.cpp +++ b/src/cegis/danger/symex/learn/solution_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/learn/solution_factory.h b/src/cegis/danger/symex/learn/solution_factory.h index f1cd177d2e6..c67b02c2826 100644 --- a/src/cegis/danger/symex/learn/solution_factory.h +++ b/src/cegis/danger/symex/learn/solution_factory.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/verify/danger_verify_config.cpp b/src/cegis/danger/symex/verify/danger_verify_config.cpp index 1f8b40ed9d5..c5bcf426212 100644 --- a/src/cegis/danger/symex/verify/danger_verify_config.cpp +++ b/src/cegis/danger/symex/verify/danger_verify_config.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/verify/danger_verify_config.h b/src/cegis/danger/symex/verify/danger_verify_config.h index 763804d5f69..70d8c79da83 100644 --- a/src/cegis/danger/symex/verify/danger_verify_config.h +++ b/src/cegis/danger/symex/verify/danger_verify_config.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/danger/symex/verify/insert_candidate.cpp b/src/cegis/danger/symex/verify/insert_candidate.cpp index 1acfe6b52d8..83bf1bbbc35 100644 --- a/src/cegis/danger/symex/verify/insert_candidate.cpp +++ b/src/cegis/danger/symex/verify/insert_candidate.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/verify/insert_candidate.h b/src/cegis/danger/symex/verify/insert_candidate.h index cd945f5a5d3..00014b5ddbc 100644 --- a/src/cegis/danger/symex/verify/insert_candidate.h +++ b/src/cegis/danger/symex/verify/insert_candidate.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/danger/symex/verify/parallel_danger_verifier.cpp b/src/cegis/danger/symex/verify/parallel_danger_verifier.cpp index 0cf3d5e6da5..ee57b71e9e9 100644 --- a/src/cegis/danger/symex/verify/parallel_danger_verifier.cpp +++ b/src/cegis/danger/symex/verify/parallel_danger_verifier.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #ifndef _WIN32 #include diff --git a/src/cegis/danger/symex/verify/parallel_danger_verifier.h b/src/cegis/danger/symex/verify/parallel_danger_verifier.h index 9a7c3c5841a..64f80ca17da 100644 --- a/src/cegis/danger/symex/verify/parallel_danger_verifier.h +++ b/src/cegis/danger/symex/verify/parallel_danger_verifier.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/verify/parallel_danger_verify_task.cpp b/src/cegis/danger/symex/verify/parallel_danger_verify_task.cpp index c077a3e4e30..187b72551cd 100644 --- a/src/cegis/danger/symex/verify/parallel_danger_verify_task.cpp +++ b/src/cegis/danger/symex/verify/parallel_danger_verify_task.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/verify/parallel_danger_verify_task.h b/src/cegis/danger/symex/verify/parallel_danger_verify_task.h index 524acc9b97e..4947826096b 100644 --- a/src/cegis/danger/symex/verify/parallel_danger_verify_task.h +++ b/src/cegis/danger/symex/verify/parallel_danger_verify_task.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/symex/verify/restrict_counterexamples.cpp b/src/cegis/danger/symex/verify/restrict_counterexamples.cpp index cb6ce99015c..886d8186895 100644 --- a/src/cegis/danger/symex/verify/restrict_counterexamples.cpp +++ b/src/cegis/danger/symex/verify/restrict_counterexamples.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/danger/symex/verify/restrict_counterexamples.h b/src/cegis/danger/symex/verify/restrict_counterexamples.h index d3667275017..1dcc09891ac 100644 --- a/src/cegis/danger/symex/verify/restrict_counterexamples.h +++ b/src/cegis/danger/symex/verify/restrict_counterexamples.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/danger/value/danger_goto_solution.h b/src/cegis/danger/value/danger_goto_solution.h index 24401681ed4..2f351979333 100644 --- a/src/cegis/danger/value/danger_goto_solution.h +++ b/src/cegis/danger/value/danger_goto_solution.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/facade/cegis.h b/src/cegis/facade/cegis.h index 6f783f942f0..027ffe1c386 100644 --- a/src/cegis/facade/cegis.h +++ b/src/cegis/facade/cegis.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/facade/runner_helper.h b/src/cegis/facade/runner_helper.h index 4a634e4b2eb..6b53c015b47 100644 --- a/src/cegis/facade/runner_helper.h +++ b/src/cegis/facade/runner_helper.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/genetic/concrete_test_runner.cpp b/src/cegis/genetic/concrete_test_runner.cpp index 290ebbcccf4..e529b798f70 100644 --- a/src/cegis/genetic/concrete_test_runner.cpp +++ b/src/cegis/genetic/concrete_test_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/genetic/concrete_test_runner.h b/src/cegis/genetic/concrete_test_runner.h index abf6da7076e..cb633130d77 100644 --- a/src/cegis/genetic/concrete_test_runner.h +++ b/src/cegis/genetic/concrete_test_runner.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/genetic/dynamic_test_runner_helper.cpp b/src/cegis/genetic/dynamic_test_runner_helper.cpp index d1461e9ca2f..f357b80b72d 100644 --- a/src/cegis/genetic/dynamic_test_runner_helper.cpp +++ b/src/cegis/genetic/dynamic_test_runner_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #if !defined(_WIN32) || defined(_HAVE_DLFCN) #include #endif diff --git a/src/cegis/genetic/dynamic_test_runner_helper.h b/src/cegis/genetic/dynamic_test_runner_helper.h index 50a3c3a09b4..74453d08768 100644 --- a/src/cegis/genetic/dynamic_test_runner_helper.h +++ b/src/cegis/genetic/dynamic_test_runner_helper.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/genetic/family_selection.h b/src/cegis/genetic/family_selection.h index 1afea9c0bd2..715fe2dfe2b 100644 --- a/src/cegis/genetic/family_selection.h +++ b/src/cegis/genetic/family_selection.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/genetic/ga_learn.h b/src/cegis/genetic/ga_learn.h index 379802f7eea..8ecb2376b88 100644 --- a/src/cegis/genetic/ga_learn.h +++ b/src/cegis/genetic/ga_learn.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/genetic/genetic_constant_strategy.cpp b/src/cegis/genetic/genetic_constant_strategy.cpp index cf3d3db8111..1e27f8faf00 100644 --- a/src/cegis/genetic/genetic_constant_strategy.cpp +++ b/src/cegis/genetic/genetic_constant_strategy.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/genetic/genetic_constant_strategy.h b/src/cegis/genetic/genetic_constant_strategy.h index e07175b55d4..12bfafaf31e 100644 --- a/src/cegis/genetic/genetic_constant_strategy.h +++ b/src/cegis/genetic/genetic_constant_strategy.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/genetic/genetic_preprocessing.h b/src/cegis/genetic/genetic_preprocessing.h index 1f893c1a78d..b0875c413af 100644 --- a/src/cegis/genetic/genetic_preprocessing.h +++ b/src/cegis/genetic/genetic_preprocessing.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/genetic/genetic_settings.cpp b/src/cegis/genetic/genetic_settings.cpp index cfcd0d6bf1f..0997c1ff693 100644 --- a/src/cegis/genetic/genetic_settings.cpp +++ b/src/cegis/genetic/genetic_settings.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include genetic_settingst::~genetic_settingst() diff --git a/src/cegis/genetic/genetic_settings.h b/src/cegis/genetic/genetic_settings.h index a1905ae8bb8..3eddd3ee225 100644 --- a/src/cegis/genetic/genetic_settings.h +++ b/src/cegis/genetic/genetic_settings.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/genetic/instruction_set_info_factory.cpp b/src/cegis/genetic/instruction_set_info_factory.cpp index 16d7cef5a4f..d9b1f06d7de 100644 --- a/src/cegis/genetic/instruction_set_info_factory.cpp +++ b/src/cegis/genetic/instruction_set_info_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/genetic/instruction_set_info_factory.h b/src/cegis/genetic/instruction_set_info_factory.h index ee62f785194..c9c109cb1dc 100644 --- a/src/cegis/genetic/instruction_set_info_factory.h +++ b/src/cegis/genetic/instruction_set_info_factory.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/genetic/lazy_fitness.h b/src/cegis/genetic/lazy_fitness.h index 350fe9796e4..6563d5d1a77 100644 --- a/src/cegis/genetic/lazy_fitness.h +++ b/src/cegis/genetic/lazy_fitness.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/genetic/lazy_genetic_settings.h b/src/cegis/genetic/lazy_genetic_settings.h index ec0c9279e73..1229ce85667 100644 --- a/src/cegis/genetic/lazy_genetic_settings.h +++ b/src/cegis/genetic/lazy_genetic_settings.h @@ -1,9 +1,11 @@ -/* - * lazy_genetic_settings.h - * - * Created on: 10 Jan 2016 - * Author: Pascal - */ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ #ifndef CPROVER_CEGIS_GENETIC_LAZY_GENETIC_SETTINGS_H #define CPROVER_CEGIS_GENETIC_LAZY_GENETIC_SETTINGS_H diff --git a/src/cegis/genetic/learn_preprocess_seed.h b/src/cegis/genetic/learn_preprocess_seed.h index 910103ed239..9bfac990f85 100644 --- a/src/cegis/genetic/learn_preprocess_seed.h +++ b/src/cegis/genetic/learn_preprocess_seed.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/genetic/match_select.cpp b/src/cegis/genetic/match_select.cpp index ff2a2809777..35e0cde1382 100644 --- a/src/cegis/genetic/match_select.cpp +++ b/src/cegis/genetic/match_select.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/genetic/match_select.h b/src/cegis/genetic/match_select.h index d6e60fdee5c..07e67df55aa 100644 --- a/src/cegis/genetic/match_select.h +++ b/src/cegis/genetic/match_select.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_GENETIC_MATCH_SELECT_H #define CPROVER_CEGIS_GENETIC_MATCH_SELECT_H diff --git a/src/cegis/genetic/program_individual_test_runner_helper.cpp b/src/cegis/genetic/program_individual_test_runner_helper.cpp index 0ea9532ec3e..ef8c42ad260 100644 --- a/src/cegis/genetic/program_individual_test_runner_helper.cpp +++ b/src/cegis/genetic/program_individual_test_runner_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/genetic/program_individual_test_runner_helper.h b/src/cegis/genetic/program_individual_test_runner_helper.h index bbd6cf6ed6b..a7f1c79b345 100644 --- a/src/cegis/genetic/program_individual_test_runner_helper.h +++ b/src/cegis/genetic/program_individual_test_runner_helper.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_GENETIC_PROGRAM_INDIVIDUAL_TEST_RUNNER_HELPER_H #define CPROVER_CEGIS_GENETIC_PROGRAM_INDIVIDUAL_TEST_RUNNER_HELPER_H diff --git a/src/cegis/genetic/random_cross.cpp b/src/cegis/genetic/random_cross.cpp index e4b18b1735e..6af2f9b9472 100644 --- a/src/cegis/genetic/random_cross.cpp +++ b/src/cegis/genetic/random_cross.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/genetic/random_cross.h b/src/cegis/genetic/random_cross.h index 32ad57bf8ac..840a674b72f 100644 --- a/src/cegis/genetic/random_cross.h +++ b/src/cegis/genetic/random_cross.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/genetic/random_individual.cpp b/src/cegis/genetic/random_individual.cpp index 555d88d7da5..d4fe319acab 100644 --- a/src/cegis/genetic/random_individual.cpp +++ b/src/cegis/genetic/random_individual.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/genetic/random_individual.h b/src/cegis/genetic/random_individual.h index 49b64db8881..cbaf28df4b2 100644 --- a/src/cegis/genetic/random_individual.h +++ b/src/cegis/genetic/random_individual.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/genetic/random_mutate.cpp b/src/cegis/genetic/random_mutate.cpp index 08af17a4633..71ef128d14f 100644 --- a/src/cegis/genetic/random_mutate.cpp +++ b/src/cegis/genetic/random_mutate.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/genetic/random_mutate.h b/src/cegis/genetic/random_mutate.h index 86c74c351db..f573bbe7bbe 100644 --- a/src/cegis/genetic/random_mutate.h +++ b/src/cegis/genetic/random_mutate.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/genetic/serialise_individual.cpp b/src/cegis/genetic/serialise_individual.cpp index 7387a54373a..f8655df986d 100644 --- a/src/cegis/genetic/serialise_individual.cpp +++ b/src/cegis/genetic/serialise_individual.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/genetic/serialise_individual.h b/src/cegis/genetic/serialise_individual.h index 58ca35ea0b5..fe921dd1b08 100644 --- a/src/cegis/genetic/serialise_individual.h +++ b/src/cegis/genetic/serialise_individual.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_GENETIC_SERIALISE_INDIVIDUAL_H #define CPROVER_CEGIS_GENETIC_SERIALISE_INDIVIDUAL_H diff --git a/src/cegis/genetic/symex_test_runner.h b/src/cegis/genetic/symex_test_runner.h index 54074632384..c96dd039684 100644 --- a/src/cegis/genetic/symex_test_runner.h +++ b/src/cegis/genetic/symex_test_runner.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/genetic/tournament_select.cpp b/src/cegis/genetic/tournament_select.cpp index 5dd4d2fb479..392c3f81f80 100644 --- a/src/cegis/genetic/tournament_select.cpp +++ b/src/cegis/genetic/tournament_select.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/genetic/tournament_select.h b/src/cegis/genetic/tournament_select.h index 283cc3b99da..e4ba07452b5 100644 --- a/src/cegis/genetic/tournament_select.h +++ b/src/cegis/genetic/tournament_select.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/instructions/instruction_set_factory.cpp b/src/cegis/instructions/instruction_set_factory.cpp index 45f60a5a995..fb9438f7e92 100644 --- a/src/cegis/instructions/instruction_set_factory.cpp +++ b/src/cegis/instructions/instruction_set_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/instructions/instruction_set_factory.h b/src/cegis/instructions/instruction_set_factory.h index 26c8d43c9d0..fd01c29229f 100644 --- a/src/cegis/instructions/instruction_set_factory.h +++ b/src/cegis/instructions/instruction_set_factory.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/instrument/cegis_library.cpp b/src/cegis/instrument/cegis_library.cpp index 48594376748..251849164a3 100644 --- a/src/cegis/instrument/cegis_library.cpp +++ b/src/cegis/instrument/cegis_library.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/instrument/cegis_library.h b/src/cegis/instrument/cegis_library.h index 06cfc6e08dc..d824159ace9 100644 --- a/src/cegis/instrument/cegis_library.h +++ b/src/cegis/instrument/cegis_library.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/instrument/find_cprover_initialize.cpp b/src/cegis/instrument/find_cprover_initialize.cpp index 8da4c4d0e80..658fd614002 100644 --- a/src/cegis/instrument/find_cprover_initialize.cpp +++ b/src/cegis/instrument/find_cprover_initialize.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/instrument/find_cprover_initialize.h b/src/cegis/instrument/find_cprover_initialize.h index de1ab0597e5..49c74e750ed 100644 --- a/src/cegis/instrument/find_cprover_initialize.h +++ b/src/cegis/instrument/find_cprover_initialize.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/instrument/instrument_var_ops.cpp b/src/cegis/instrument/instrument_var_ops.cpp index f5a6bc65f61..485476c944d 100644 --- a/src/cegis/instrument/instrument_var_ops.cpp +++ b/src/cegis/instrument/instrument_var_ops.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/instrument/instrument_var_ops.h b/src/cegis/instrument/instrument_var_ops.h index 688b65b2b56..256be2e1706 100644 --- a/src/cegis/instrument/instrument_var_ops.h +++ b/src/cegis/instrument/instrument_var_ops.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/instrument/literals.h b/src/cegis/instrument/literals.h index 1377946bc2c..ddc7eab7e30 100644 --- a/src/cegis/instrument/literals.h +++ b/src/cegis/instrument/literals.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/instrument/meta_variables.cpp b/src/cegis/instrument/meta_variables.cpp index 41e163d425f..83d48e70ecb 100644 --- a/src/cegis/instrument/meta_variables.cpp +++ b/src/cegis/instrument/meta_variables.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/instrument/meta_variables.h b/src/cegis/instrument/meta_variables.h index 00df2b5c15b..378f44bb055 100644 --- a/src/cegis/instrument/meta_variables.h +++ b/src/cegis/instrument/meta_variables.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/constant/add_constant.cpp b/src/cegis/invariant/constant/add_constant.cpp index fab9f2ebb4b..e64ff8f871f 100644 --- a/src/cegis/invariant/constant/add_constant.cpp +++ b/src/cegis/invariant/constant/add_constant.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/constant/add_constant.h b/src/cegis/invariant/constant/add_constant.h index 3c8d5af7c3d..272e8f152c9 100644 --- a/src/cegis/invariant/constant/add_constant.h +++ b/src/cegis/invariant/constant/add_constant.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/invariant/constant/constant_strategy.h b/src/cegis/invariant/constant/constant_strategy.h index e91b082bb66..0ba229066be 100644 --- a/src/cegis/invariant/constant/constant_strategy.h +++ b/src/cegis/invariant/constant/constant_strategy.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/invariant/constant/default_constant_strategy.cpp b/src/cegis/invariant/constant/default_constant_strategy.cpp index c6d58ab956f..36e12634a09 100644 --- a/src/cegis/invariant/constant/default_constant_strategy.cpp +++ b/src/cegis/invariant/constant/default_constant_strategy.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/constant/default_constant_strategy.h b/src/cegis/invariant/constant/default_constant_strategy.h index 342ef5f95d1..124d4eb81c7 100644 --- a/src/cegis/invariant/constant/default_constant_strategy.h +++ b/src/cegis/invariant/constant/default_constant_strategy.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/invariant/constant/literals_constant_strategy.cpp b/src/cegis/invariant/constant/literals_constant_strategy.cpp index ec12572494b..44d80d4d6f2 100644 --- a/src/cegis/invariant/constant/literals_constant_strategy.cpp +++ b/src/cegis/invariant/constant/literals_constant_strategy.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/constant/literals_constant_strategy.h b/src/cegis/invariant/constant/literals_constant_strategy.h index 90158f1466f..6b7f73564d3 100644 --- a/src/cegis/invariant/constant/literals_constant_strategy.h +++ b/src/cegis/invariant/constant/literals_constant_strategy.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/invariant/fitness/concrete_fitness_source_provider.cpp b/src/cegis/invariant/fitness/concrete_fitness_source_provider.cpp index c84b55aa9d2..28e41138cb3 100644 --- a/src/cegis/invariant/fitness/concrete_fitness_source_provider.cpp +++ b/src/cegis/invariant/fitness/concrete_fitness_source_provider.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/fitness/concrete_fitness_source_provider.h b/src/cegis/invariant/fitness/concrete_fitness_source_provider.h index 9fcbd69ec77..4176e2b685e 100644 --- a/src/cegis/invariant/fitness/concrete_fitness_source_provider.h +++ b/src/cegis/invariant/fitness/concrete_fitness_source_provider.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/meta/meta_variable_names.cpp b/src/cegis/invariant/meta/meta_variable_names.cpp index 3bfd885018c..be19ceb945b 100644 --- a/src/cegis/invariant/meta/meta_variable_names.cpp +++ b/src/cegis/invariant/meta/meta_variable_names.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/meta/meta_variable_names.h b/src/cegis/invariant/meta/meta_variable_names.h index 68169d27a47..683a5115ed1 100644 --- a/src/cegis/invariant/meta/meta_variable_names.h +++ b/src/cegis/invariant/meta/meta_variable_names.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/options/invariant_program.cpp b/src/cegis/invariant/options/invariant_program.cpp index f6fb89e50c9..c139a756baf 100644 --- a/src/cegis/invariant/options/invariant_program.cpp +++ b/src/cegis/invariant/options/invariant_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/options/invariant_program.h b/src/cegis/invariant/options/invariant_program.h index 1d79880269f..a87161a6292 100644 --- a/src/cegis/invariant/options/invariant_program.h +++ b/src/cegis/invariant/options/invariant_program.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/options/target_copy_helper.cpp b/src/cegis/invariant/options/target_copy_helper.cpp index 8cc28175b84..af0c209bb7c 100644 --- a/src/cegis/invariant/options/target_copy_helper.cpp +++ b/src/cegis/invariant/options/target_copy_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/invariant/options/target_copy_helper.h b/src/cegis/invariant/options/target_copy_helper.h index a09a5a431a8..c69aa677a6d 100644 --- a/src/cegis/invariant/options/target_copy_helper.h +++ b/src/cegis/invariant/options/target_copy_helper.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/preprocess/add_invariants_and_temp_variables.cpp b/src/cegis/invariant/preprocess/add_invariants_and_temp_variables.cpp index e8111388a2a..417a581ae3c 100644 --- a/src/cegis/invariant/preprocess/add_invariants_and_temp_variables.cpp +++ b/src/cegis/invariant/preprocess/add_invariants_and_temp_variables.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/preprocess/add_invariants_and_temp_variables.h b/src/cegis/invariant/preprocess/add_invariants_and_temp_variables.h index f34f6ec7ce8..4272953976f 100644 --- a/src/cegis/invariant/preprocess/add_invariants_and_temp_variables.h +++ b/src/cegis/invariant/preprocess/add_invariants_and_temp_variables.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/preprocess/remove_loops_and_assertion.cpp b/src/cegis/invariant/preprocess/remove_loops_and_assertion.cpp index 31e7f0687bd..60a34406bf8 100644 --- a/src/cegis/invariant/preprocess/remove_loops_and_assertion.cpp +++ b/src/cegis/invariant/preprocess/remove_loops_and_assertion.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/preprocess/remove_loops_and_assertion.h b/src/cegis/invariant/preprocess/remove_loops_and_assertion.h index 19367a29bb9..ac3bd191dcf 100644 --- a/src/cegis/invariant/preprocess/remove_loops_and_assertion.h +++ b/src/cegis/invariant/preprocess/remove_loops_and_assertion.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/symex/learn/add_counterexamples.cpp b/src/cegis/invariant/symex/learn/add_counterexamples.cpp index b975b3226f7..5359762a0c7 100644 --- a/src/cegis/invariant/symex/learn/add_counterexamples.cpp +++ b/src/cegis/invariant/symex/learn/add_counterexamples.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/symex/learn/add_counterexamples.h b/src/cegis/invariant/symex/learn/add_counterexamples.h index 008dc14f794..97a95560536 100644 --- a/src/cegis/invariant/symex/learn/add_counterexamples.h +++ b/src/cegis/invariant/symex/learn/add_counterexamples.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/symex/learn/add_invariant_programs_to_learn.cpp b/src/cegis/invariant/symex/learn/add_invariant_programs_to_learn.cpp index 35e78ab47f0..5ad3c8740d6 100644 --- a/src/cegis/invariant/symex/learn/add_invariant_programs_to_learn.cpp +++ b/src/cegis/invariant/symex/learn/add_invariant_programs_to_learn.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/symex/learn/add_invariant_programs_to_learn.h b/src/cegis/invariant/symex/learn/add_invariant_programs_to_learn.h index a4a69fd8277..cfbccfbca8c 100644 --- a/src/cegis/invariant/symex/learn/add_invariant_programs_to_learn.h +++ b/src/cegis/invariant/symex/learn/add_invariant_programs_to_learn.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/symex/learn/instrument_vars.cpp b/src/cegis/invariant/symex/learn/instrument_vars.cpp index ee099cb7a25..b6e43c68b25 100644 --- a/src/cegis/invariant/symex/learn/instrument_vars.cpp +++ b/src/cegis/invariant/symex/learn/instrument_vars.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/symex/learn/instrument_vars.h b/src/cegis/invariant/symex/learn/instrument_vars.h index b5a37acf96b..f2b963cb173 100644 --- a/src/cegis/invariant/symex/learn/instrument_vars.h +++ b/src/cegis/invariant/symex/learn/instrument_vars.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/symex/learn/invariant_body_provider.h b/src/cegis/invariant/symex/learn/invariant_body_provider.h index 04720832790..d58fea886fb 100644 --- a/src/cegis/invariant/symex/learn/invariant_body_provider.h +++ b/src/cegis/invariant/symex/learn/invariant_body_provider.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_INVARIANT_SYMEX_LEARN_INVARIANT_BODY_PROVIDER_H #define CPROVER_CEGIS_INVARIANT_SYMEX_LEARN_INVARIANT_BODY_PROVIDER_H diff --git a/src/cegis/invariant/symex/learn/replace_operators.cpp b/src/cegis/invariant/symex/learn/replace_operators.cpp index e46db87a394..b0031f0c327 100644 --- a/src/cegis/invariant/symex/learn/replace_operators.cpp +++ b/src/cegis/invariant/symex/learn/replace_operators.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/symex/learn/replace_operators.h b/src/cegis/invariant/symex/learn/replace_operators.h index 82c50952fa6..1668871c951 100644 --- a/src/cegis/invariant/symex/learn/replace_operators.h +++ b/src/cegis/invariant/symex/learn/replace_operators.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/symex/verify/extract_counterexample.cpp b/src/cegis/invariant/symex/verify/extract_counterexample.cpp index 1e6ca8b4afb..4a2d9cf211f 100644 --- a/src/cegis/invariant/symex/verify/extract_counterexample.cpp +++ b/src/cegis/invariant/symex/verify/extract_counterexample.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/symex/verify/extract_counterexample.h b/src/cegis/invariant/symex/verify/extract_counterexample.h index 7281314db26..70f480762a7 100644 --- a/src/cegis/invariant/symex/verify/extract_counterexample.h +++ b/src/cegis/invariant/symex/verify/extract_counterexample.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/symex/verify/insert_constraint.cpp b/src/cegis/invariant/symex/verify/insert_constraint.cpp index 454d82c03c5..0eb89c01e09 100644 --- a/src/cegis/invariant/symex/verify/insert_constraint.cpp +++ b/src/cegis/invariant/symex/verify/insert_constraint.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/symex/verify/insert_constraint.h b/src/cegis/invariant/symex/verify/insert_constraint.h index 139e629f44b..6c730f9cff0 100644 --- a/src/cegis/invariant/symex/verify/insert_constraint.h +++ b/src/cegis/invariant/symex/verify/insert_constraint.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/symex/verify/insert_program.cpp b/src/cegis/invariant/symex/verify/insert_program.cpp index 804b76cfdb8..9509141932b 100644 --- a/src/cegis/invariant/symex/verify/insert_program.cpp +++ b/src/cegis/invariant/symex/verify/insert_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/symex/verify/insert_program.h b/src/cegis/invariant/symex/verify/insert_program.h index eae08aea2a0..5a6ae8c3d65 100644 --- a/src/cegis/invariant/symex/verify/insert_program.h +++ b/src/cegis/invariant/symex/verify/insert_program.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/invariant/util/copy_instructions.cpp b/src/cegis/invariant/util/copy_instructions.cpp index 65a35cf98b9..b108a6dc389 100644 --- a/src/cegis/invariant/util/copy_instructions.cpp +++ b/src/cegis/invariant/util/copy_instructions.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/util/copy_instructions.h b/src/cegis/invariant/util/copy_instructions.h index 82687e6818c..3fcf7d5abaa 100644 --- a/src/cegis/invariant/util/copy_instructions.h +++ b/src/cegis/invariant/util/copy_instructions.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/util/invariant_constraint_variables.cpp b/src/cegis/invariant/util/invariant_constraint_variables.cpp index 8999048a99c..5c9a6fd69b7 100644 --- a/src/cegis/invariant/util/invariant_constraint_variables.cpp +++ b/src/cegis/invariant/util/invariant_constraint_variables.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/util/invariant_constraint_variables.h b/src/cegis/invariant/util/invariant_constraint_variables.h index 3c2c1a090ce..93efd59da0b 100644 --- a/src/cegis/invariant/util/invariant_constraint_variables.h +++ b/src/cegis/invariant/util/invariant_constraint_variables.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/invariant/util/invariant_program_helper.cpp b/src/cegis/invariant/util/invariant_program_helper.cpp index 2899a96ebea..616b612b41a 100644 --- a/src/cegis/invariant/util/invariant_program_helper.cpp +++ b/src/cegis/invariant/util/invariant_program_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/invariant/util/invariant_program_helper.h b/src/cegis/invariant/util/invariant_program_helper.h index c408a688d70..1af13d90fed 100644 --- a/src/cegis/invariant/util/invariant_program_helper.h +++ b/src/cegis/invariant/util/invariant_program_helper.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/jsa/constraint/jsa_constraint_factory.cpp b/src/cegis/jsa/constraint/jsa_constraint_factory.cpp index f24f799e95e..00b611f9d36 100644 --- a/src/cegis/jsa/constraint/jsa_constraint_factory.cpp +++ b/src/cegis/jsa/constraint/jsa_constraint_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/constraint/jsa_constraint_factory.h b/src/cegis/jsa/constraint/jsa_constraint_factory.h index 107a64e8505..f5c5fe48f9c 100644 --- a/src/cegis/jsa/constraint/jsa_constraint_factory.h +++ b/src/cegis/jsa/constraint/jsa_constraint_factory.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/converters/counterexample.cpp b/src/cegis/jsa/converters/counterexample.cpp index ef0f3b642a4..71e23f01754 100644 --- a/src/cegis/jsa/converters/counterexample.cpp +++ b/src/cegis/jsa/converters/counterexample.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/converters/counterexample.h b/src/cegis/jsa/converters/counterexample.h index db1669f834b..42a4e6fb13d 100644 --- a/src/cegis/jsa/converters/counterexample.h +++ b/src/cegis/jsa/converters/counterexample.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/converters/replace_operators.cpp b/src/cegis/jsa/converters/replace_operators.cpp index 370980a8845..9d6d8e99d3d 100644 --- a/src/cegis/jsa/converters/replace_operators.cpp +++ b/src/cegis/jsa/converters/replace_operators.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/converters/replace_operators.h b/src/cegis/jsa/converters/replace_operators.h index b3326aa0931..00ba51b4f29 100644 --- a/src/cegis/jsa/converters/replace_operators.h +++ b/src/cegis/jsa/converters/replace_operators.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/converters/solution.cpp b/src/cegis/jsa/converters/solution.cpp index 0b5465fb748..87b789057af 100644 --- a/src/cegis/jsa/converters/solution.cpp +++ b/src/cegis/jsa/converters/solution.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/converters/solution.h b/src/cegis/jsa/converters/solution.h index b21b4e3803a..d262f415477 100644 --- a/src/cegis/jsa/converters/solution.h +++ b/src/cegis/jsa/converters/solution.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/converters/translate_to_goto_program.cpp b/src/cegis/jsa/converters/translate_to_goto_program.cpp index 226b8be3f84..053933ccad8 100644 --- a/src/cegis/jsa/converters/translate_to_goto_program.cpp +++ b/src/cegis/jsa/converters/translate_to_goto_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/converters/translate_to_goto_program.h b/src/cegis/jsa/converters/translate_to_goto_program.h index 8846fd43079..bac64b05b73 100644 --- a/src/cegis/jsa/converters/translate_to_goto_program.h +++ b/src/cegis/jsa/converters/translate_to_goto_program.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/facade/jsa_runner.cpp b/src/cegis/jsa/facade/jsa_runner.cpp index 389679838eb..6b565758941 100644 --- a/src/cegis/jsa/facade/jsa_runner.cpp +++ b/src/cegis/jsa/facade/jsa_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/facade/jsa_runner.h b/src/cegis/jsa/facade/jsa_runner.h index efe6975c576..66e1e62456f 100644 --- a/src/cegis/jsa/facade/jsa_runner.h +++ b/src/cegis/jsa/facade/jsa_runner.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/genetic/dynamic_jsa_test_runner.cpp b/src/cegis/jsa/genetic/dynamic_jsa_test_runner.cpp index 4440a707b63..c0a03bb3684 100644 --- a/src/cegis/jsa/genetic/dynamic_jsa_test_runner.cpp +++ b/src/cegis/jsa/genetic/dynamic_jsa_test_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/genetic/dynamic_jsa_test_runner.h b/src/cegis/jsa/genetic/dynamic_jsa_test_runner.h index 77b8bd85f58..8990800a90b 100644 --- a/src/cegis/jsa/genetic/dynamic_jsa_test_runner.h +++ b/src/cegis/jsa/genetic/dynamic_jsa_test_runner.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/genetic/jsa_genetic_convert.cpp b/src/cegis/jsa/genetic/jsa_genetic_convert.cpp index cae118da3fd..4729430f2b3 100644 --- a/src/cegis/jsa/genetic/jsa_genetic_convert.cpp +++ b/src/cegis/jsa/genetic/jsa_genetic_convert.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/genetic/jsa_genetic_convert.h b/src/cegis/jsa/genetic/jsa_genetic_convert.h index f50107fcee5..45271ffeb87 100644 --- a/src/cegis/jsa/genetic/jsa_genetic_convert.h +++ b/src/cegis/jsa/genetic/jsa_genetic_convert.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/genetic/jsa_paragon_wrapper.cpp b/src/cegis/jsa/genetic/jsa_paragon_wrapper.cpp index 64508bb83d5..f682bb1e455 100644 --- a/src/cegis/jsa/genetic/jsa_paragon_wrapper.cpp +++ b/src/cegis/jsa/genetic/jsa_paragon_wrapper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/genetic/jsa_paragon_wrapper.h b/src/cegis/jsa/genetic/jsa_paragon_wrapper.h index 88c302f386f..f5094398b20 100644 --- a/src/cegis/jsa/genetic/jsa_paragon_wrapper.h +++ b/src/cegis/jsa/genetic/jsa_paragon_wrapper.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/jsa/genetic/jsa_random.cpp b/src/cegis/jsa/genetic/jsa_random.cpp index 09fea2ae2cf..087fc1efdec 100644 --- a/src/cegis/jsa/genetic/jsa_random.cpp +++ b/src/cegis/jsa/genetic/jsa_random.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/genetic/jsa_random.h b/src/cegis/jsa/genetic/jsa_random.h index 6ee282b6849..3bd1921bb9d 100644 --- a/src/cegis/jsa/genetic/jsa_random.h +++ b/src/cegis/jsa/genetic/jsa_random.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_JSA_GENETIC_JSA_RANDOM_H #define CPROVER_CEGIS_JSA_GENETIC_JSA_RANDOM_H diff --git a/src/cegis/jsa/genetic/jsa_serialiser.cpp b/src/cegis/jsa/genetic/jsa_serialiser.cpp index b75373822e9..4f948e6adf5 100644 --- a/src/cegis/jsa/genetic/jsa_serialiser.cpp +++ b/src/cegis/jsa/genetic/jsa_serialiser.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/genetic/jsa_serialiser.h b/src/cegis/jsa/genetic/jsa_serialiser.h index 46d7e9ae00e..48adbfa5e42 100644 --- a/src/cegis/jsa/genetic/jsa_serialiser.h +++ b/src/cegis/jsa/genetic/jsa_serialiser.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/genetic/jsa_source_provider.cpp b/src/cegis/jsa/genetic/jsa_source_provider.cpp index b66b10a765a..4984bfe1c9b 100644 --- a/src/cegis/jsa/genetic/jsa_source_provider.cpp +++ b/src/cegis/jsa/genetic/jsa_source_provider.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/genetic/jsa_source_provider.h b/src/cegis/jsa/genetic/jsa_source_provider.h index 1a8d6f096dc..cf7be6f543a 100644 --- a/src/cegis/jsa/genetic/jsa_source_provider.h +++ b/src/cegis/jsa/genetic/jsa_source_provider.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/jsa/genetic/random_jsa_cross.cpp b/src/cegis/jsa/genetic/random_jsa_cross.cpp index 35434dd3f84..88e1e5bc224 100644 --- a/src/cegis/jsa/genetic/random_jsa_cross.cpp +++ b/src/cegis/jsa/genetic/random_jsa_cross.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/genetic/random_jsa_cross.h b/src/cegis/jsa/genetic/random_jsa_cross.h index 7d27eebc443..dad01f21373 100644 --- a/src/cegis/jsa/genetic/random_jsa_cross.h +++ b/src/cegis/jsa/genetic/random_jsa_cross.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/genetic/random_jsa_mutate.cpp b/src/cegis/jsa/genetic/random_jsa_mutate.cpp index 838d5272ee9..0f9d9ddfd06 100644 --- a/src/cegis/jsa/genetic/random_jsa_mutate.cpp +++ b/src/cegis/jsa/genetic/random_jsa_mutate.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/genetic/random_jsa_mutate.h b/src/cegis/jsa/genetic/random_jsa_mutate.h index 9265b50d559..e931ae48319 100644 --- a/src/cegis/jsa/genetic/random_jsa_mutate.h +++ b/src/cegis/jsa/genetic/random_jsa_mutate.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/genetic/solution_helper.cpp b/src/cegis/jsa/genetic/solution_helper.cpp index c4c7d35ffb0..a4b206a9d73 100644 --- a/src/cegis/jsa/genetic/solution_helper.cpp +++ b/src/cegis/jsa/genetic/solution_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/genetic/solution_helper.h b/src/cegis/jsa/genetic/solution_helper.h index 6497bd000a8..e31538404e7 100644 --- a/src/cegis/jsa/genetic/solution_helper.h +++ b/src/cegis/jsa/genetic/solution_helper.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/jsa/instrument/jsa_meta_data.cpp b/src/cegis/jsa/instrument/jsa_meta_data.cpp index 0315b595287..a03412faec0 100644 --- a/src/cegis/jsa/instrument/jsa_meta_data.cpp +++ b/src/cegis/jsa/instrument/jsa_meta_data.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/instrument/jsa_meta_data.h b/src/cegis/jsa/instrument/jsa_meta_data.h index faacef24090..d5fbc8f69dc 100644 --- a/src/cegis/jsa/instrument/jsa_meta_data.h +++ b/src/cegis/jsa/instrument/jsa_meta_data.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/instrument/temps_helper.cpp b/src/cegis/jsa/instrument/temps_helper.cpp index a60e6b3c389..d70f9c5ef50 100644 --- a/src/cegis/jsa/instrument/temps_helper.cpp +++ b/src/cegis/jsa/instrument/temps_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/instrument/temps_helper.h b/src/cegis/jsa/instrument/temps_helper.h index 68f743bca7c..0bdb7401197 100644 --- a/src/cegis/jsa/instrument/temps_helper.h +++ b/src/cegis/jsa/instrument/temps_helper.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/learn/execute_jsa_programs.cpp b/src/cegis/jsa/learn/execute_jsa_programs.cpp index b417f8c8f2f..27fed92b3fc 100644 --- a/src/cegis/jsa/learn/execute_jsa_programs.cpp +++ b/src/cegis/jsa/learn/execute_jsa_programs.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/learn/execute_jsa_programs.h b/src/cegis/jsa/learn/execute_jsa_programs.h index fc3604e7419..9942f873be5 100644 --- a/src/cegis/jsa/learn/execute_jsa_programs.h +++ b/src/cegis/jsa/learn/execute_jsa_programs.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/learn/extract_candidate.cpp b/src/cegis/jsa/learn/extract_candidate.cpp index bc054fc94fd..1a1cf0768b1 100644 --- a/src/cegis/jsa/learn/extract_candidate.cpp +++ b/src/cegis/jsa/learn/extract_candidate.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/learn/extract_candidate.h b/src/cegis/jsa/learn/extract_candidate.h index 6a856b401cd..acfaa4461de 100644 --- a/src/cegis/jsa/learn/extract_candidate.h +++ b/src/cegis/jsa/learn/extract_candidate.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/learn/insert_counterexample.cpp b/src/cegis/jsa/learn/insert_counterexample.cpp index 162280a2a60..6d277d54e2a 100644 --- a/src/cegis/jsa/learn/insert_counterexample.cpp +++ b/src/cegis/jsa/learn/insert_counterexample.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/learn/insert_counterexample.h b/src/cegis/jsa/learn/insert_counterexample.h index 5d69439d850..19fab3cb363 100644 --- a/src/cegis/jsa/learn/insert_counterexample.h +++ b/src/cegis/jsa/learn/insert_counterexample.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/learn/insert_predicates_and_queries.cpp b/src/cegis/jsa/learn/insert_predicates_and_queries.cpp index fbc94dab88e..4aaf9e38cb5 100644 --- a/src/cegis/jsa/learn/insert_predicates_and_queries.cpp +++ b/src/cegis/jsa/learn/insert_predicates_and_queries.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/learn/insert_predicates_and_queries.h b/src/cegis/jsa/learn/insert_predicates_and_queries.h index 15dfd7483f5..fb6cb745400 100644 --- a/src/cegis/jsa/learn/insert_predicates_and_queries.h +++ b/src/cegis/jsa/learn/insert_predicates_and_queries.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/learn/instrument_pred_ops.cpp b/src/cegis/jsa/learn/instrument_pred_ops.cpp index 83f70aeecc2..9e001bdb34d 100644 --- a/src/cegis/jsa/learn/instrument_pred_ops.cpp +++ b/src/cegis/jsa/learn/instrument_pred_ops.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/learn/instrument_pred_ops.h b/src/cegis/jsa/learn/instrument_pred_ops.h index 9aae3ee0706..8188961bfa4 100644 --- a/src/cegis/jsa/learn/instrument_pred_ops.h +++ b/src/cegis/jsa/learn/instrument_pred_ops.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/learn/jsa_symex_learn.cpp b/src/cegis/jsa/learn/jsa_symex_learn.cpp index 05a9cc904b9..d44640e5006 100644 --- a/src/cegis/jsa/learn/jsa_symex_learn.cpp +++ b/src/cegis/jsa/learn/jsa_symex_learn.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/learn/jsa_symex_learn.h b/src/cegis/jsa/learn/jsa_symex_learn.h index 1c85adc4796..18de6d242e5 100644 --- a/src/cegis/jsa/learn/jsa_symex_learn.h +++ b/src/cegis/jsa/learn/jsa_symex_learn.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/options/jsa_program.cpp b/src/cegis/jsa/options/jsa_program.cpp index 5e42c14148b..d7d6cc8870e 100644 --- a/src/cegis/jsa/options/jsa_program.cpp +++ b/src/cegis/jsa/options/jsa_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/options/jsa_program.h b/src/cegis/jsa/options/jsa_program.h index 26c5a72fa76..c9f0001686d 100644 --- a/src/cegis/jsa/options/jsa_program.h +++ b/src/cegis/jsa/options/jsa_program.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/options/jsa_program_info.cpp b/src/cegis/jsa/options/jsa_program_info.cpp index 10b2f0be346..d2464b6fead 100644 --- a/src/cegis/jsa/options/jsa_program_info.cpp +++ b/src/cegis/jsa/options/jsa_program_info.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/options/jsa_program_info.h b/src/cegis/jsa/options/jsa_program_info.h index 626d37115ec..95df2352f25 100644 --- a/src/cegis/jsa/options/jsa_program_info.h +++ b/src/cegis/jsa/options/jsa_program_info.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_JSA_OPTIONS_JSA_PROGRAM_INFO_H #define CPROVER_CEGIS_JSA_OPTIONS_JSA_PROGRAM_INFO_H diff --git a/src/cegis/jsa/preprocessing/add_constraint_meta_variables.cpp b/src/cegis/jsa/preprocessing/add_constraint_meta_variables.cpp index 82a99dc0827..da4d98bf48e 100644 --- a/src/cegis/jsa/preprocessing/add_constraint_meta_variables.cpp +++ b/src/cegis/jsa/preprocessing/add_constraint_meta_variables.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/preprocessing/add_constraint_meta_variables.h b/src/cegis/jsa/preprocessing/add_constraint_meta_variables.h index c49e2991d2e..f9268c01bae 100644 --- a/src/cegis/jsa/preprocessing/add_constraint_meta_variables.h +++ b/src/cegis/jsa/preprocessing/add_constraint_meta_variables.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/preprocessing/add_synthesis_library.cpp b/src/cegis/jsa/preprocessing/add_synthesis_library.cpp index d12fa6b862e..f2e394c51ed 100644 --- a/src/cegis/jsa/preprocessing/add_synthesis_library.cpp +++ b/src/cegis/jsa/preprocessing/add_synthesis_library.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/preprocessing/add_synthesis_library.h b/src/cegis/jsa/preprocessing/add_synthesis_library.h index af8ee791346..95d50d000d5 100644 --- a/src/cegis/jsa/preprocessing/add_synthesis_library.h +++ b/src/cegis/jsa/preprocessing/add_synthesis_library.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/preprocessing/clone_heap.cpp b/src/cegis/jsa/preprocessing/clone_heap.cpp index 9c89848ecde..ce7247ad04e 100644 --- a/src/cegis/jsa/preprocessing/clone_heap.cpp +++ b/src/cegis/jsa/preprocessing/clone_heap.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/preprocessing/clone_heap.h b/src/cegis/jsa/preprocessing/clone_heap.h index 3f247c823d5..cad2c8360c7 100644 --- a/src/cegis/jsa/preprocessing/clone_heap.h +++ b/src/cegis/jsa/preprocessing/clone_heap.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/preprocessing/collect_variables.cpp b/src/cegis/jsa/preprocessing/collect_variables.cpp index 41c0883e809..56594713b7f 100644 --- a/src/cegis/jsa/preprocessing/collect_variables.cpp +++ b/src/cegis/jsa/preprocessing/collect_variables.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/preprocessing/collect_variables.h b/src/cegis/jsa/preprocessing/collect_variables.h index 0f306b8be64..434600639a4 100644 --- a/src/cegis/jsa/preprocessing/collect_variables.h +++ b/src/cegis/jsa/preprocessing/collect_variables.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/preprocessing/create_temp_variables.cpp b/src/cegis/jsa/preprocessing/create_temp_variables.cpp index 431687b03f1..4f142e7210e 100644 --- a/src/cegis/jsa/preprocessing/create_temp_variables.cpp +++ b/src/cegis/jsa/preprocessing/create_temp_variables.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/preprocessing/create_temp_variables.h b/src/cegis/jsa/preprocessing/create_temp_variables.h index c7ec14da0e9..a2024748a95 100644 --- a/src/cegis/jsa/preprocessing/create_temp_variables.h +++ b/src/cegis/jsa/preprocessing/create_temp_variables.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/preprocessing/default_jsa_constant_strategy.cpp b/src/cegis/jsa/preprocessing/default_jsa_constant_strategy.cpp index 7a25d41952b..01474a262a8 100644 --- a/src/cegis/jsa/preprocessing/default_jsa_constant_strategy.cpp +++ b/src/cegis/jsa/preprocessing/default_jsa_constant_strategy.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/preprocessing/default_jsa_constant_strategy.h b/src/cegis/jsa/preprocessing/default_jsa_constant_strategy.h index 3c42ce0289a..f6170ca01ba 100644 --- a/src/cegis/jsa/preprocessing/default_jsa_constant_strategy.h +++ b/src/cegis/jsa/preprocessing/default_jsa_constant_strategy.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/jsa/preprocessing/inline_user_program.cpp b/src/cegis/jsa/preprocessing/inline_user_program.cpp index 77e69359e27..e02f350a6d9 100644 --- a/src/cegis/jsa/preprocessing/inline_user_program.cpp +++ b/src/cegis/jsa/preprocessing/inline_user_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/preprocessing/inline_user_program.h b/src/cegis/jsa/preprocessing/inline_user_program.h index e9c60c75d07..6e732f321d8 100644 --- a/src/cegis/jsa/preprocessing/inline_user_program.h +++ b/src/cegis/jsa/preprocessing/inline_user_program.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/preprocessing/jsa_preprocessing.cpp b/src/cegis/jsa/preprocessing/jsa_preprocessing.cpp index 6176b0eb5a1..433f8a3ef38 100644 --- a/src/cegis/jsa/preprocessing/jsa_preprocessing.cpp +++ b/src/cegis/jsa/preprocessing/jsa_preprocessing.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/preprocessing/jsa_preprocessing.h b/src/cegis/jsa/preprocessing/jsa_preprocessing.h index 56706df86f5..0d9bf4d7ad9 100644 --- a/src/cegis/jsa/preprocessing/jsa_preprocessing.h +++ b/src/cegis/jsa/preprocessing/jsa_preprocessing.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/preprocessing/remove_loop.cpp b/src/cegis/jsa/preprocessing/remove_loop.cpp index 16289f4545f..9469133750c 100644 --- a/src/cegis/jsa/preprocessing/remove_loop.cpp +++ b/src/cegis/jsa/preprocessing/remove_loop.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/preprocessing/remove_loop.h b/src/cegis/jsa/preprocessing/remove_loop.h index 1d7a50ed94f..53c3138952f 100644 --- a/src/cegis/jsa/preprocessing/remove_loop.h +++ b/src/cegis/jsa/preprocessing/remove_loop.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/value/default_solution.cpp b/src/cegis/jsa/value/default_solution.cpp index 3497a719ba8..d11641546ac 100644 --- a/src/cegis/jsa/value/default_solution.cpp +++ b/src/cegis/jsa/value/default_solution.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/jsa/value/default_solution.h b/src/cegis/jsa/value/default_solution.h index cd144d09a0e..d8678ad23bc 100644 --- a/src/cegis/jsa/value/default_solution.h +++ b/src/cegis/jsa/value/default_solution.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/value/jsa_counterexample.h b/src/cegis/jsa/value/jsa_counterexample.h index c95c4355f5f..f16a6267039 100644 --- a/src/cegis/jsa/value/jsa_counterexample.h +++ b/src/cegis/jsa/value/jsa_counterexample.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/value/jsa_counterexample_printer.cpp b/src/cegis/jsa/value/jsa_counterexample_printer.cpp index 1545849f266..83c443a9d51 100644 --- a/src/cegis/jsa/value/jsa_counterexample_printer.cpp +++ b/src/cegis/jsa/value/jsa_counterexample_printer.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include void print_jsa_counterexample(messaget::mstreamt &os, diff --git a/src/cegis/jsa/value/jsa_counterexample_printer.h b/src/cegis/jsa/value/jsa_counterexample_printer.h index 12514946132..2ae1080a540 100644 --- a/src/cegis/jsa/value/jsa_counterexample_printer.h +++ b/src/cegis/jsa/value/jsa_counterexample_printer.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/value/jsa_genetic_counterexample.h b/src/cegis/jsa/value/jsa_genetic_counterexample.h index ecdf0de2faa..f984768566e 100644 --- a/src/cegis/jsa/value/jsa_genetic_counterexample.h +++ b/src/cegis/jsa/value/jsa_genetic_counterexample.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/value/jsa_genetic_solution.h b/src/cegis/jsa/value/jsa_genetic_solution.h index 1a76a6bdc7a..1f2a7d6e5ed 100644 --- a/src/cegis/jsa/value/jsa_genetic_solution.h +++ b/src/cegis/jsa/value/jsa_genetic_solution.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/value/jsa_genetic_synthesis.h b/src/cegis/jsa/value/jsa_genetic_synthesis.h index 6678b3b71f6..823f6dc9bf4 100644 --- a/src/cegis/jsa/value/jsa_genetic_synthesis.h +++ b/src/cegis/jsa/value/jsa_genetic_synthesis.h @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #ifndef CPROVER_CEGIS_JSA_VALUE_JSA_GENETIC_SYNTHESIS_H #define CPROVER_CEGIS_JSA_VALUE_JSA_GENETIC_SYNTHESIS_H diff --git a/src/cegis/jsa/value/jsa_solution.cpp b/src/cegis/jsa/value/jsa_solution.cpp index d58be7bc328..c1434ce66f7 100644 --- a/src/cegis/jsa/value/jsa_solution.cpp +++ b/src/cegis/jsa/value/jsa_solution.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/value/jsa_solution.h b/src/cegis/jsa/value/jsa_solution.h index 4ae3ba35bda..6a93f254f10 100644 --- a/src/cegis/jsa/value/jsa_solution.h +++ b/src/cegis/jsa/value/jsa_solution.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/value/jsa_solution_printer.cpp b/src/cegis/jsa/value/jsa_solution_printer.cpp index f3115f2cd91..f9c57297b8f 100644 --- a/src/cegis/jsa/value/jsa_solution_printer.cpp +++ b/src/cegis/jsa/value/jsa_solution_printer.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/value/jsa_solution_printer.h b/src/cegis/jsa/value/jsa_solution_printer.h index 32eae1d30d6..1dcf9632db7 100644 --- a/src/cegis/jsa/value/jsa_solution_printer.h +++ b/src/cegis/jsa/value/jsa_solution_printer.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/value/jsa_types.cpp b/src/cegis/jsa/value/jsa_types.cpp index ac2e7b48eb6..003d9361b04 100644 --- a/src/cegis/jsa/value/jsa_types.cpp +++ b/src/cegis/jsa/value/jsa_types.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/value/jsa_types.h b/src/cegis/jsa/value/jsa_types.h index 47ef22fe77f..a6f1aee52a5 100644 --- a/src/cegis/jsa/value/jsa_types.h +++ b/src/cegis/jsa/value/jsa_types.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/value/pred_ops.h b/src/cegis/jsa/value/pred_ops.h index 500c1ec5f7e..fa84df5fb59 100644 --- a/src/cegis/jsa/value/pred_ops.h +++ b/src/cegis/jsa/value/pred_ops.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/verify/extract_counterexample.cpp b/src/cegis/jsa/verify/extract_counterexample.cpp index fe3caa65eca..662dacdb6c9 100644 --- a/src/cegis/jsa/verify/extract_counterexample.cpp +++ b/src/cegis/jsa/verify/extract_counterexample.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/verify/extract_counterexample.h b/src/cegis/jsa/verify/extract_counterexample.h index 315d66d9e51..006ec48adb0 100644 --- a/src/cegis/jsa/verify/extract_counterexample.h +++ b/src/cegis/jsa/verify/extract_counterexample.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/verify/insert_solution.cpp b/src/cegis/jsa/verify/insert_solution.cpp index 373791042f7..0f577968837 100644 --- a/src/cegis/jsa/verify/insert_solution.cpp +++ b/src/cegis/jsa/verify/insert_solution.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/verify/insert_solution.h b/src/cegis/jsa/verify/insert_solution.h index 0c9c9e150ae..0d8822ea065 100644 --- a/src/cegis/jsa/verify/insert_solution.h +++ b/src/cegis/jsa/verify/insert_solution.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/verify/jsa_symex_verify.cpp b/src/cegis/jsa/verify/jsa_symex_verify.cpp index c00f50eacf3..f698a34810d 100644 --- a/src/cegis/jsa/verify/jsa_symex_verify.cpp +++ b/src/cegis/jsa/verify/jsa_symex_verify.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/verify/jsa_symex_verify.h b/src/cegis/jsa/verify/jsa_symex_verify.h index 952a694ae71..f07077b6743 100644 --- a/src/cegis/jsa/verify/jsa_symex_verify.h +++ b/src/cegis/jsa/verify/jsa_symex_verify.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/jsa/verify/renondet_inputs.cpp b/src/cegis/jsa/verify/renondet_inputs.cpp index 257fecf2cdb..d02de4a3039 100644 --- a/src/cegis/jsa/verify/renondet_inputs.cpp +++ b/src/cegis/jsa/verify/renondet_inputs.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/jsa/verify/renondet_inputs.h b/src/cegis/jsa/verify/renondet_inputs.h index 2484407d311..ffe987129df 100644 --- a/src/cegis/jsa/verify/renondet_inputs.h +++ b/src/cegis/jsa/verify/renondet_inputs.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/learn/concurrent_learn.h b/src/cegis/learn/concurrent_learn.h index 25b00838941..7e8c2f62b12 100644 --- a/src/cegis/learn/concurrent_learn.h +++ b/src/cegis/learn/concurrent_learn.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/learn/constraint_helper.cpp b/src/cegis/learn/constraint_helper.cpp index 33289624049..974cdafcb5c 100644 --- a/src/cegis/learn/constraint_helper.cpp +++ b/src/cegis/learn/constraint_helper.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/learn/constraint_helper.h b/src/cegis/learn/constraint_helper.h index 7be5dc210e2..ae084a2e545 100644 --- a/src/cegis/learn/constraint_helper.h +++ b/src/cegis/learn/constraint_helper.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_LEARN_CONSTRAINT_HELPER_H #define CPROVER_CEGIS_LEARN_CONSTRAINT_HELPER_H diff --git a/src/cegis/learn/insert_counterexample.cpp b/src/cegis/learn/insert_counterexample.cpp index c34663ddcfd..7c321db9128 100644 --- a/src/cegis/learn/insert_counterexample.cpp +++ b/src/cegis/learn/insert_counterexample.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/learn/insert_counterexample.h b/src/cegis/learn/insert_counterexample.h index d20d9f6809b..39382ceae5c 100644 --- a/src/cegis/learn/insert_counterexample.h +++ b/src/cegis/learn/insert_counterexample.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/options/parameters.h b/src/cegis/options/parameters.h index d97633f8272..bf9d6ee931d 100644 --- a/src/cegis/options/parameters.h +++ b/src/cegis/options/parameters.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_OPTIONS_PARAMETERS_H #define CPROVER_CEGIS_OPTIONS_PARAMETERS_H diff --git a/src/cegis/refactor/constraint/constraint_factory.cpp b/src/cegis/refactor/constraint/constraint_factory.cpp index 843312ee8e7..abe6d33e4fa 100644 --- a/src/cegis/refactor/constraint/constraint_factory.cpp +++ b/src/cegis/refactor/constraint/constraint_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/constraint/constraint_factory.h b/src/cegis/refactor/constraint/constraint_factory.h index ee25bdf1bed..a6c42be5661 100644 --- a/src/cegis/refactor/constraint/constraint_factory.h +++ b/src/cegis/refactor/constraint/constraint_factory.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_CONSTRAINT_CONSTRAINT_FACTORY_H #define CPROVER_CEGIS_REFACTOR_CONSTRAINT_CONSTRAINT_FACTORY_H diff --git a/src/cegis/refactor/environment/instrument_state_vars.cpp b/src/cegis/refactor/environment/instrument_state_vars.cpp index 7c6b6e3b5e0..6dc9d60869a 100644 --- a/src/cegis/refactor/environment/instrument_state_vars.cpp +++ b/src/cegis/refactor/environment/instrument_state_vars.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include namespace diff --git a/src/cegis/refactor/environment/instrument_state_vars.h b/src/cegis/refactor/environment/instrument_state_vars.h index 64cdea270f1..ee5cdd5679e 100644 --- a/src/cegis/refactor/environment/instrument_state_vars.h +++ b/src/cegis/refactor/environment/instrument_state_vars.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_ENVIRONMENT_INSTRUMENT_STATE_VARS_H #define CPROVER_CEGIS_REFACTOR_ENVIRONMENT_INSTRUMENT_STATE_VARS_H diff --git a/src/cegis/refactor/facade/refactor_runner.cpp b/src/cegis/refactor/facade/refactor_runner.cpp index ce9c5012cf9..3d4ed42ddc2 100644 --- a/src/cegis/refactor/facade/refactor_runner.cpp +++ b/src/cegis/refactor/facade/refactor_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/refactor/facade/refactor_runner.h b/src/cegis/refactor/facade/refactor_runner.h index f3ea91151db..b27073e3f0e 100644 --- a/src/cegis/refactor/facade/refactor_runner.h +++ b/src/cegis/refactor/facade/refactor_runner.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_FACADE_REFACTOR_RUNNER_H #define CPROVER_CEGIS_REFACTOR_FACADE_REFACTOR_RUNNER_H diff --git a/src/cegis/refactor/instructionset/cegis_instruction_factory.cpp b/src/cegis/refactor/instructionset/cegis_instruction_factory.cpp index 3d43531318d..c9d233dad1e 100644 --- a/src/cegis/refactor/instructionset/cegis_instruction_factory.cpp +++ b/src/cegis/refactor/instructionset/cegis_instruction_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/instructionset/cegis_instruction_factory.h b/src/cegis/refactor/instructionset/cegis_instruction_factory.h index 30bd64adb30..f5426c54cfb 100644 --- a/src/cegis/refactor/instructionset/cegis_instruction_factory.h +++ b/src/cegis/refactor/instructionset/cegis_instruction_factory.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp b/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp index d383f263418..567276dc536 100644 --- a/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp +++ b/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/instructionset/cegis_processor_body_factory.h b/src/cegis/refactor/instructionset/cegis_processor_body_factory.h index a208b794fcf..bd2b3e5470d 100644 --- a/src/cegis/refactor/instructionset/cegis_processor_body_factory.h +++ b/src/cegis/refactor/instructionset/cegis_processor_body_factory.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_INSTRUCTIONSET_CEGIS_PROCESSOR_BODY_FACTORY_H #define CPROVER_CEGIS_REFACTOR_INSTRUCTIONSET_CEGIS_PROCESSOR_BODY_FACTORY_H diff --git a/src/cegis/refactor/instructionset/create_cegis_processor.cpp b/src/cegis/refactor/instructionset/create_cegis_processor.cpp index 611a719d655..0a5871aef54 100644 --- a/src/cegis/refactor/instructionset/create_cegis_processor.cpp +++ b/src/cegis/refactor/instructionset/create_cegis_processor.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/refactor/instructionset/create_cegis_processor.h b/src/cegis/refactor/instructionset/create_cegis_processor.h index 50e5c5bbda8..7b4a1273f66 100644 --- a/src/cegis/refactor/instructionset/create_cegis_processor.h +++ b/src/cegis/refactor/instructionset/create_cegis_processor.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_INSTRUCTIONSET_CREATE_CEGIS_PROCESSOR_H #define CPROVER_CEGIS_REFACTOR_INSTRUCTIONSET_CREATE_CEGIS_PROCESSOR_H diff --git a/src/cegis/refactor/instructionset/execute_cegis_program.cpp b/src/cegis/refactor/instructionset/execute_cegis_program.cpp index 1244df9c4ef..347f550bde5 100644 --- a/src/cegis/refactor/instructionset/execute_cegis_program.cpp +++ b/src/cegis/refactor/instructionset/execute_cegis_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/refactor/instructionset/execute_cegis_program.h b/src/cegis/refactor/instructionset/execute_cegis_program.h index 999db14cc9c..bf3c9d1dc8c 100644 --- a/src/cegis/refactor/instructionset/execute_cegis_program.h +++ b/src/cegis/refactor/instructionset/execute_cegis_program.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/refactor/instructionset/instruction_description.cpp b/src/cegis/refactor/instructionset/instruction_description.cpp index 200c24e6496..ee063db4e6a 100644 --- a/src/cegis/refactor/instructionset/instruction_description.cpp +++ b/src/cegis/refactor/instructionset/instruction_description.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include instruction_descriptiont::instruction_descriptiont(const typest &signature, diff --git a/src/cegis/refactor/instructionset/instruction_description.h b/src/cegis/refactor/instructionset/instruction_description.h index 281e94ec4e2..00b08fcb0bb 100644 --- a/src/cegis/refactor/instructionset/instruction_description.h +++ b/src/cegis/refactor/instructionset/instruction_description.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/refactor/instructionset/operand_data.h b/src/cegis/refactor/instructionset/operand_data.h index 2e0f7870513..34339985649 100644 --- a/src/cegis/refactor/instructionset/operand_data.h +++ b/src/cegis/refactor/instructionset/operand_data.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/refactor/instructionset/processor_symbols.cpp b/src/cegis/refactor/instructionset/processor_symbols.cpp index 9fa981724e2..2a5fd442a66 100644 --- a/src/cegis/refactor/instructionset/processor_symbols.cpp +++ b/src/cegis/refactor/instructionset/processor_symbols.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/refactor/instructionset/processor_symbols.h b/src/cegis/refactor/instructionset/processor_symbols.h index ca34874c76a..cf6a0734ee7 100644 --- a/src/cegis/refactor/instructionset/processor_symbols.h +++ b/src/cegis/refactor/instructionset/processor_symbols.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/refactor/instructionset/processor_types.cpp b/src/cegis/refactor/instructionset/processor_types.cpp index 9dd1ec5c38a..af1c9d44c04 100644 --- a/src/cegis/refactor/instructionset/processor_types.cpp +++ b/src/cegis/refactor/instructionset/processor_types.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/instructionset/processor_types.h b/src/cegis/refactor/instructionset/processor_types.h index adfb10d63e8..b01e3cd860f 100644 --- a/src/cegis/refactor/instructionset/processor_types.h +++ b/src/cegis/refactor/instructionset/processor_types.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/refactor/learn/instrument_counterexamples.cpp b/src/cegis/refactor/learn/instrument_counterexamples.cpp index 3e16568cce7..58af6e51c03 100644 --- a/src/cegis/refactor/learn/instrument_counterexamples.cpp +++ b/src/cegis/refactor/learn/instrument_counterexamples.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/learn/instrument_counterexamples.h b/src/cegis/refactor/learn/instrument_counterexamples.h index 0f5734cb79a..45493db0a30 100644 --- a/src/cegis/refactor/learn/instrument_counterexamples.h +++ b/src/cegis/refactor/learn/instrument_counterexamples.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/refactor/learn/refactor_candidate_printer.cpp b/src/cegis/refactor/learn/refactor_candidate_printer.cpp index 6012c2724ee..44a88be1cd9 100644 --- a/src/cegis/refactor/learn/refactor_candidate_printer.cpp +++ b/src/cegis/refactor/learn/refactor_candidate_printer.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/learn/refactor_candidate_printer.h b/src/cegis/refactor/learn/refactor_candidate_printer.h index bbc36833498..53041c573fe 100644 --- a/src/cegis/refactor/learn/refactor_candidate_printer.h +++ b/src/cegis/refactor/learn/refactor_candidate_printer.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/refactor/learn/refactor_symex_learn.cpp b/src/cegis/refactor/learn/refactor_symex_learn.cpp index b8e42a4b02a..98d6cce1807 100644 --- a/src/cegis/refactor/learn/refactor_symex_learn.cpp +++ b/src/cegis/refactor/learn/refactor_symex_learn.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/learn/refactor_symex_learn.h b/src/cegis/refactor/learn/refactor_symex_learn.h index d335b2716be..dee68ce2afb 100644 --- a/src/cegis/refactor/learn/refactor_symex_learn.h +++ b/src/cegis/refactor/learn/refactor_symex_learn.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/refactor/nullobject/nullable_analysis.cpp b/src/cegis/refactor/nullobject/nullable_analysis.cpp index 12f33c092af..c961a007980 100644 --- a/src/cegis/refactor/nullobject/nullable_analysis.cpp +++ b/src/cegis/refactor/nullobject/nullable_analysis.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/nullobject/nullable_analysis.h b/src/cegis/refactor/nullobject/nullable_analysis.h index 65c2c3da754..7d2d6578e95 100644 --- a/src/cegis/refactor/nullobject/nullable_analysis.h +++ b/src/cegis/refactor/nullobject/nullable_analysis.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/refactor/nullobject/range_collector.cpp b/src/cegis/refactor/nullobject/range_collector.cpp index a9c43e1accd..01f76a5fdc0 100644 --- a/src/cegis/refactor/nullobject/range_collector.cpp +++ b/src/cegis/refactor/nullobject/range_collector.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/refactor/nullobject/range_collector.h b/src/cegis/refactor/nullobject/range_collector.h index f2c9780b1fb..fba93debae3 100644 --- a/src/cegis/refactor/nullobject/range_collector.h +++ b/src/cegis/refactor/nullobject/range_collector.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_NULLOBJECT_RANGE_COLLECTOR_H #define CPROVER_CEGIS_REFACTOR_NULLOBJECT_RANGE_COLLECTOR_H diff --git a/src/cegis/refactor/options/refactor_program.cpp b/src/cegis/refactor/options/refactor_program.cpp index 67ad7b053e7..c58f17d84a0 100644 --- a/src/cegis/refactor/options/refactor_program.cpp +++ b/src/cegis/refactor/options/refactor_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/refactor/options/refactor_program.h b/src/cegis/refactor/options/refactor_program.h index 35282d347b3..aa66f843bd3 100644 --- a/src/cegis/refactor/options/refactor_program.h +++ b/src/cegis/refactor/options/refactor_program.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/refactor/options/refactoring_type.cpp b/src/cegis/refactor/options/refactoring_type.cpp index 17f377871d1..101c8d6980d 100644 --- a/src/cegis/refactor/options/refactoring_type.cpp +++ b/src/cegis/refactor/options/refactoring_type.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/options/refactoring_type.h b/src/cegis/refactor/options/refactoring_type.h index 022affe60a4..189e97af520 100644 --- a/src/cegis/refactor/options/refactoring_type.h +++ b/src/cegis/refactor/options/refactoring_type.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_OPTIONS_REFACTORING_TYPE_H #define CPROVER_CEGIS_REFACTOR_OPTIONS_REFACTORING_TYPE_H diff --git a/src/cegis/refactor/preprocessing/collect_counterexamples.cpp b/src/cegis/refactor/preprocessing/collect_counterexamples.cpp index acdb42518cc..d9d7a5cd41f 100644 --- a/src/cegis/refactor/preprocessing/collect_counterexamples.cpp +++ b/src/cegis/refactor/preprocessing/collect_counterexamples.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/refactor/preprocessing/collect_counterexamples.h b/src/cegis/refactor/preprocessing/collect_counterexamples.h index cc0038bcf2c..5238f84c069 100644 --- a/src/cegis/refactor/preprocessing/collect_counterexamples.h +++ b/src/cegis/refactor/preprocessing/collect_counterexamples.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_PREPROCESSING_COLLECT_COUNTEREXAMPLES_H #define CPROVER_CEGIS_REFACTOR_PREPROCESSING_COLLECT_COUNTEREXAMPLES_H diff --git a/src/cegis/refactor/preprocessing/refactor_preprocessing.cpp b/src/cegis/refactor/preprocessing/refactor_preprocessing.cpp index 0b74082d54a..b5b6f3d0d5b 100644 --- a/src/cegis/refactor/preprocessing/refactor_preprocessing.cpp +++ b/src/cegis/refactor/preprocessing/refactor_preprocessing.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/preprocessing/refactor_preprocessing.h b/src/cegis/refactor/preprocessing/refactor_preprocessing.h index 155187dfea7..b3b3e86c6e3 100644 --- a/src/cegis/refactor/preprocessing/refactor_preprocessing.h +++ b/src/cegis/refactor/preprocessing/refactor_preprocessing.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_PREPROCESSING_REFACTOR_PREPROCESSING_H #define CPROVER_CEGIS_REFACTOR_PREPROCESSING_REFACTOR_PREPROCESSING_H diff --git a/src/cegis/refactor/value/refactor_counterexample.h b/src/cegis/refactor/value/refactor_counterexample.h index fe4a8344e65..fd1bf021e9c 100644 --- a/src/cegis/refactor/value/refactor_counterexample.h +++ b/src/cegis/refactor/value/refactor_counterexample.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/refactor/value/refactor_solution.h b/src/cegis/refactor/value/refactor_solution.h index 5cb538f5bfc..15e5c1e8963 100644 --- a/src/cegis/refactor/value/refactor_solution.h +++ b/src/cegis/refactor/value/refactor_solution.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_REFACTOR_VALUE_REFACTOR_SOLUTION_H #define CPROVER_CEGIS_REFACTOR_VALUE_REFACTOR_SOLUTION_H diff --git a/src/cegis/refactor/verify/refactor_symex_verify.cpp b/src/cegis/refactor/verify/refactor_symex_verify.cpp index 77dc78ca7b7..a65fba9f684 100644 --- a/src/cegis/refactor/verify/refactor_symex_verify.cpp +++ b/src/cegis/refactor/verify/refactor_symex_verify.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/refactor/verify/refactor_symex_verify.h b/src/cegis/refactor/verify/refactor_symex_verify.h index 65be9d7fdf8..c78efc5af07 100644 --- a/src/cegis/refactor/verify/refactor_symex_verify.h +++ b/src/cegis/refactor/verify/refactor_symex_verify.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/constraint/safety_constraint_factory.cpp b/src/cegis/safety/constraint/safety_constraint_factory.cpp index dd2c243a379..b05fc243d06 100644 --- a/src/cegis/safety/constraint/safety_constraint_factory.cpp +++ b/src/cegis/safety/constraint/safety_constraint_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/constraint/safety_constraint_factory.h b/src/cegis/safety/constraint/safety_constraint_factory.h index 07946afe437..b34922a97b1 100644 --- a/src/cegis/safety/constraint/safety_constraint_factory.h +++ b/src/cegis/safety/constraint/safety_constraint_factory.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/facade/safety_runner.cpp b/src/cegis/safety/facade/safety_runner.cpp index 2251d150b02..cf4656341c3 100644 --- a/src/cegis/safety/facade/safety_runner.cpp +++ b/src/cegis/safety/facade/safety_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/facade/safety_runner.h b/src/cegis/safety/facade/safety_runner.h index cb2801b1f85..cea2774c334 100644 --- a/src/cegis/safety/facade/safety_runner.h +++ b/src/cegis/safety/facade/safety_runner.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/safety/genetic/dynamic_safety_test_runner.cpp b/src/cegis/safety/genetic/dynamic_safety_test_runner.cpp index c7aa7ba0070..24a5f8df24a 100644 --- a/src/cegis/safety/genetic/dynamic_safety_test_runner.cpp +++ b/src/cegis/safety/genetic/dynamic_safety_test_runner.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/genetic/dynamic_safety_test_runner.h b/src/cegis/safety/genetic/dynamic_safety_test_runner.h index 499d8e659f4..bb696fb7a7e 100644 --- a/src/cegis/safety/genetic/dynamic_safety_test_runner.h +++ b/src/cegis/safety/genetic/dynamic_safety_test_runner.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/meta/meta_variable_names.cpp b/src/cegis/safety/meta/meta_variable_names.cpp index e8730af2c99..64be5eea8de 100644 --- a/src/cegis/safety/meta/meta_variable_names.cpp +++ b/src/cegis/safety/meta/meta_variable_names.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/meta/meta_variable_names.h b/src/cegis/safety/meta/meta_variable_names.h index 23f07df3b58..81b68f16242 100644 --- a/src/cegis/safety/meta/meta_variable_names.h +++ b/src/cegis/safety/meta/meta_variable_names.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/options/safety_program.cpp b/src/cegis/safety/options/safety_program.cpp index 9dcb2951bba..c7019b95aaf 100644 --- a/src/cegis/safety/options/safety_program.cpp +++ b/src/cegis/safety/options/safety_program.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/options/safety_program.h b/src/cegis/safety/options/safety_program.h index 70f85b5e10b..08b76f2ea09 100644 --- a/src/cegis/safety/options/safety_program.h +++ b/src/cegis/safety/options/safety_program.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/options/safety_program_genetic_settings.h b/src/cegis/safety/options/safety_program_genetic_settings.h index c1beb687c1d..81157207e4d 100644 --- a/src/cegis/safety/options/safety_program_genetic_settings.h +++ b/src/cegis/safety/options/safety_program_genetic_settings.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/options/safety_program_printer.cpp b/src/cegis/safety/options/safety_program_printer.cpp index 16ec26c6c46..efd3aa82699 100644 --- a/src/cegis/safety/options/safety_program_printer.cpp +++ b/src/cegis/safety/options/safety_program_printer.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/options/safety_program_printer.h b/src/cegis/safety/options/safety_program_printer.h index 6efcaf65225..39fff5e8251 100644 --- a/src/cegis/safety/options/safety_program_printer.h +++ b/src/cegis/safety/options/safety_program_printer.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/preprocessing/safety_preprocessing.cpp b/src/cegis/safety/preprocessing/safety_preprocessing.cpp index 269b217c707..de96e76096a 100644 --- a/src/cegis/safety/preprocessing/safety_preprocessing.cpp +++ b/src/cegis/safety/preprocessing/safety_preprocessing.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/preprocessing/safety_preprocessing.h b/src/cegis/safety/preprocessing/safety_preprocessing.h index 43a924a09c0..9f3251b8481 100644 --- a/src/cegis/safety/preprocessing/safety_preprocessing.h +++ b/src/cegis/safety/preprocessing/safety_preprocessing.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/symex/fitness/safety_fitness_config.cpp b/src/cegis/safety/symex/fitness/safety_fitness_config.cpp index 74d7530c85d..1622eb7010d 100644 --- a/src/cegis/safety/symex/fitness/safety_fitness_config.cpp +++ b/src/cegis/safety/symex/fitness/safety_fitness_config.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/safety/symex/fitness/safety_fitness_config.h b/src/cegis/safety/symex/fitness/safety_fitness_config.h index 2e30a984ae9..64fb8bb30f8 100644 --- a/src/cegis/safety/symex/fitness/safety_fitness_config.h +++ b/src/cegis/safety/symex/fitness/safety_fitness_config.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/symex/learn/add_counterexamples.cpp b/src/cegis/safety/symex/learn/add_counterexamples.cpp index 489c84ee832..8762c907aca 100644 --- a/src/cegis/safety/symex/learn/add_counterexamples.cpp +++ b/src/cegis/safety/symex/learn/add_counterexamples.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/symex/learn/add_counterexamples.h b/src/cegis/safety/symex/learn/add_counterexamples.h index eed757b2679..08dae224adb 100644 --- a/src/cegis/safety/symex/learn/add_counterexamples.h +++ b/src/cegis/safety/symex/learn/add_counterexamples.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/symex/learn/add_variable_refs.cpp b/src/cegis/safety/symex/learn/add_variable_refs.cpp index dd292a9527f..1cefa0d63ff 100644 --- a/src/cegis/safety/symex/learn/add_variable_refs.cpp +++ b/src/cegis/safety/symex/learn/add_variable_refs.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/safety/symex/learn/add_variable_refs.h b/src/cegis/safety/symex/learn/add_variable_refs.h index 147477b3606..51fc08a03f2 100644 --- a/src/cegis/safety/symex/learn/add_variable_refs.h +++ b/src/cegis/safety/symex/learn/add_variable_refs.h @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #ifndef CPROVER_CEGIS_SAFETY_SYMEX_LEARN_ADD_VARIABLE_REFS_H #define CPROVER_CEGIS_SAFETY_SYMEX_LEARN_ADD_VARIABLE_REFS_H diff --git a/src/cegis/safety/symex/learn/encoded_safety_learn_config.cpp b/src/cegis/safety/symex/learn/encoded_safety_learn_config.cpp index f140a11df0a..31c7b53f2a8 100644 --- a/src/cegis/safety/symex/learn/encoded_safety_learn_config.cpp +++ b/src/cegis/safety/symex/learn/encoded_safety_learn_config.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/safety/symex/learn/encoded_safety_learn_config.h b/src/cegis/safety/symex/learn/encoded_safety_learn_config.h index 68c6e697872..7aa502ad1f8 100644 --- a/src/cegis/safety/symex/learn/encoded_safety_learn_config.h +++ b/src/cegis/safety/symex/learn/encoded_safety_learn_config.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/symex/learn/safety_learn_config.cpp b/src/cegis/safety/symex/learn/safety_learn_config.cpp index 57b6ec6dec6..da2331cbda3 100644 --- a/src/cegis/safety/symex/learn/safety_learn_config.cpp +++ b/src/cegis/safety/symex/learn/safety_learn_config.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/symex/learn/safety_learn_config.h b/src/cegis/safety/symex/learn/safety_learn_config.h index c42ee3718ab..0d93d2a4e3b 100644 --- a/src/cegis/safety/symex/learn/safety_learn_config.h +++ b/src/cegis/safety/symex/learn/safety_learn_config.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/symex/learn/solution_factory.cpp b/src/cegis/safety/symex/learn/solution_factory.cpp index 5f4ef933455..f5c6e688aca 100644 --- a/src/cegis/safety/symex/learn/solution_factory.cpp +++ b/src/cegis/safety/symex/learn/solution_factory.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/safety/symex/learn/solution_factory.h b/src/cegis/safety/symex/learn/solution_factory.h index fd8b63d13c9..a3b52e5cf76 100644 --- a/src/cegis/safety/symex/learn/solution_factory.h +++ b/src/cegis/safety/symex/learn/solution_factory.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/symex/verify/insert_candidate.cpp b/src/cegis/safety/symex/verify/insert_candidate.cpp index 3bd088de4fc..8315a2a4903 100644 --- a/src/cegis/safety/symex/verify/insert_candidate.cpp +++ b/src/cegis/safety/symex/verify/insert_candidate.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/safety/symex/verify/insert_candidate.h b/src/cegis/safety/symex/verify/insert_candidate.h index 163b4960c7e..b1723872c65 100644 --- a/src/cegis/safety/symex/verify/insert_candidate.h +++ b/src/cegis/safety/symex/verify/insert_candidate.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/safety/symex/verify/safety_verify_config.cpp b/src/cegis/safety/symex/verify/safety_verify_config.cpp index 80972e41290..dc46bcc7123 100644 --- a/src/cegis/safety/symex/verify/safety_verify_config.cpp +++ b/src/cegis/safety/symex/verify/safety_verify_config.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/safety/symex/verify/safety_verify_config.h b/src/cegis/safety/symex/verify/safety_verify_config.h index 27259d6b6e5..bf64a69be37 100644 --- a/src/cegis/safety/symex/verify/safety_verify_config.h +++ b/src/cegis/safety/symex/verify/safety_verify_config.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/safety/value/individual_to_safety_solution_deserialiser.cpp b/src/cegis/safety/value/individual_to_safety_solution_deserialiser.cpp index a9624b72669..2cddeea2621 100644 --- a/src/cegis/safety/value/individual_to_safety_solution_deserialiser.cpp +++ b/src/cegis/safety/value/individual_to_safety_solution_deserialiser.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include #include diff --git a/src/cegis/safety/value/individual_to_safety_solution_deserialiser.h b/src/cegis/safety/value/individual_to_safety_solution_deserialiser.h index 1139b3bd5ec..5e4dce7ecee 100644 --- a/src/cegis/safety/value/individual_to_safety_solution_deserialiser.h +++ b/src/cegis/safety/value/individual_to_safety_solution_deserialiser.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/value/safety_goto_ce.cpp b/src/cegis/safety/value/safety_goto_ce.cpp index 5ce1cb45e2a..d97153cfeec 100644 --- a/src/cegis/safety/value/safety_goto_ce.cpp +++ b/src/cegis/safety/value/safety_goto_ce.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include bool safety_goto_cet::operator ==(const safety_goto_cet &other) const diff --git a/src/cegis/safety/value/safety_goto_ce.h b/src/cegis/safety/value/safety_goto_ce.h index dcf5b8cf779..6fc139b2346 100644 --- a/src/cegis/safety/value/safety_goto_ce.h +++ b/src/cegis/safety/value/safety_goto_ce.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/safety/value/safety_goto_solution.h b/src/cegis/safety/value/safety_goto_solution.h index c2e740c66ae..b6ef8734e96 100644 --- a/src/cegis/safety/value/safety_goto_solution.h +++ b/src/cegis/safety/value/safety_goto_solution.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/seed/literals_seed.cpp b/src/cegis/seed/literals_seed.cpp index daf942acc47..7e7c7b63639 100644 --- a/src/cegis/seed/literals_seed.cpp +++ b/src/cegis/seed/literals_seed.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/seed/literals_seed.h b/src/cegis/seed/literals_seed.h index 6690773860e..df57f12d1f8 100644 --- a/src/cegis/seed/literals_seed.h +++ b/src/cegis/seed/literals_seed.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/seed/null_seed.h b/src/cegis/seed/null_seed.h index 4fa095a25f3..a9d07acfdf5 100644 --- a/src/cegis/seed/null_seed.h +++ b/src/cegis/seed/null_seed.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/statistics/cegis_statistics_wrapper.h b/src/cegis/statistics/cegis_statistics_wrapper.h index 166074cbef4..6100c243a80 100644 --- a/src/cegis/statistics/cegis_statistics_wrapper.h +++ b/src/cegis/statistics/cegis_statistics_wrapper.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/symex/cegis_symex_learn.h b/src/cegis/symex/cegis_symex_learn.h index cd6a7ac69c7..a8f5b0c1bb8 100644 --- a/src/cegis/symex/cegis_symex_learn.h +++ b/src/cegis/symex/cegis_symex_learn.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_SYMEX_CEGIS_SYMEX_LEARN_H #define CPROVER_CEGIS_SYMEX_CEGIS_SYMEX_LEARN_H diff --git a/src/cegis/symex/cegis_symex_verify.h b/src/cegis/symex/cegis_symex_verify.h index 97c485a4e0d..7c862d7089f 100644 --- a/src/cegis/symex/cegis_symex_verify.h +++ b/src/cegis/symex/cegis_symex_verify.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/value/assignments_printer.cpp b/src/cegis/value/assignments_printer.cpp index a2a08a068b4..fa57d737a74 100644 --- a/src/cegis/value/assignments_printer.cpp +++ b/src/cegis/value/assignments_printer.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/value/assignments_printer.h b/src/cegis/value/assignments_printer.h index d4437c92e87..eda5f2d849a 100644 --- a/src/cegis/value/assignments_printer.h +++ b/src/cegis/value/assignments_printer.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/value/program_individual.h b/src/cegis/value/program_individual.h index e7dd1745afc..1139cdafd0b 100644 --- a/src/cegis/value/program_individual.h +++ b/src/cegis/value/program_individual.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis diff --git a/src/cegis/value/program_individual_serialisation.cpp b/src/cegis/value/program_individual_serialisation.cpp index e5a1223db21..4f72b6cc18c 100644 --- a/src/cegis/value/program_individual_serialisation.cpp +++ b/src/cegis/value/program_individual_serialisation.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/value/program_individual_serialisation.h b/src/cegis/value/program_individual_serialisation.h index 198578bb875..83429992a2b 100644 --- a/src/cegis/value/program_individual_serialisation.h +++ b/src/cegis/value/program_individual_serialisation.h @@ -1,9 +1,9 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk \*******************************************************************/ diff --git a/src/cegis/wordsize/limited_wordsize_verify.h b/src/cegis/wordsize/limited_wordsize_verify.h index 6bd6d1b4d51..bc9c3e78b70 100644 --- a/src/cegis/wordsize/limited_wordsize_verify.h +++ b/src/cegis/wordsize/limited_wordsize_verify.h @@ -1,11 +1,11 @@ -/******************************************************************* +/*******************************************************************\ - Module: Counterexample-Guided Inductive Synthesis +Module: Counterexample-Guided Inductive Synthesis - Author: Daniel Kroening, kroening@kroening.com - Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk - \*******************************************************************/ +\*******************************************************************/ #ifndef CPROVER_CEGIS_WORDSIZE_LIMITED_WORDSIZE_VERIFY_H #define CPROVER_CEGIS_WORDSIZE_LIMITED_WORDSIZE_VERIFY_H diff --git a/src/cegis/wordsize/restrict_bv_size.cpp b/src/cegis/wordsize/restrict_bv_size.cpp index d4b8f13dd39..8ca3a0791be 100644 --- a/src/cegis/wordsize/restrict_bv_size.cpp +++ b/src/cegis/wordsize/restrict_bv_size.cpp @@ -1,3 +1,12 @@ +/*******************************************************************\ + +Module: Counterexample-Guided Inductive Synthesis + +Author: Daniel Kroening, kroening@kroening.com + Pascal Kesseli, pascal.kesseli@cs.ox.ac.uk + +\*******************************************************************/ + #include #include diff --git a/src/cegis/wordsize/restrict_bv_size.h b/src/cegis/wordsize/restrict_bv_size.h index b3c2937c2ae..cdda0d7254b 100644 --- a/src/cegis/wordsize/restrict_bv_size.h +++ b/src/cegis/wordsize/restrict_bv_size.h @@ -1,4 +1,4 @@ -/******************************************************************* +/*******************************************************************\ Module: Counterexample-Guided Inductive Synthesis From 586345443248664858c308c8cd88be711b41951e Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Wed, 25 Jan 2017 13:02:00 +0000 Subject: [PATCH 045/166] cegis: fix include guards to match coding conventions --- src/cegis/cegis-util/goto_range.h | 5 +++++ src/cegis/control/learn/print_control_solution.h | 6 +++--- src/cegis/control/learn/rational_solution_configuration.h | 6 +++--- src/cegis/control/learn/vector_solution_configuration.h | 6 +++--- src/cegis/control/value/control_vector_solution.h | 6 +++--- src/cegis/control/verify/zero_solutions.h | 6 +++--- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/cegis/cegis-util/goto_range.h b/src/cegis/cegis-util/goto_range.h index be17f1cdba0..e34dd50579f 100644 --- a/src/cegis/cegis-util/goto_range.h +++ b/src/cegis/cegis-util/goto_range.h @@ -7,6 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#ifndef CPROVER_CEGIS_CEGIS_UTIL_GOTO_RANGE_H +#define CPROVER_CEGIS_CEGIS_UTIL_GOTO_RANGE_H + #include /** @@ -15,3 +18,5 @@ Author: Daniel Kroening, kroening@kroening.com * @details */ typedef std::pair goto_ranget; + +#endif // CPROVER_CEGIS_CEGIS_UTIL_GOTO_RANGE_H diff --git a/src/cegis/control/learn/print_control_solution.h b/src/cegis/control/learn/print_control_solution.h index 2107dc16ad0..a6f0bcab9ef 100644 --- a/src/cegis/control/learn/print_control_solution.h +++ b/src/cegis/control/learn/print_control_solution.h @@ -7,8 +7,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#ifndef CEGIS_CONTROL_LEARN_PRINT_CONTROL_SOLUTION_H_ -#define CEGIS_CONTROL_LEARN_PRINT_CONTROL_SOLUTION_H_ +#ifndef CPROVER_CEGIS_CONTROL_LEARN_PRINT_CONTROL_SOLUTION_H +#define CPROVER_CEGIS_CONTROL_LEARN_PRINT_CONTROL_SOLUTION_H #include #include @@ -30,4 +30,4 @@ void print_control_array( const char * name, const symbol_tablet &st); -#endif /* CEGIS_CONTROL_LEARN_PRINT_CONTROL_SOLUTION_H_ */ +#endif // CPROVER_CEGIS_CONTROL_LEARN_PRINT_CONTROL_SOLUTION_H diff --git a/src/cegis/control/learn/rational_solution_configuration.h b/src/cegis/control/learn/rational_solution_configuration.h index 407e8944141..f135c58578f 100644 --- a/src/cegis/control/learn/rational_solution_configuration.h +++ b/src/cegis/control/learn/rational_solution_configuration.h @@ -7,8 +7,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#ifndef CEGIS_CONTROL_LEARN_RATIONAL_SOLUTION_CONFIGURATION_H_ -#define CEGIS_CONTROL_LEARN_RATIONAL_SOLUTION_CONFIGURATION_H_ +#ifndef CPROVER_CEGIS_CONTROL_LEARN_RATIONAL_SOLUTION_CONFIGURATION_H +#define CPROVER_CEGIS_CONTROL_LEARN_RATIONAL_SOLUTION_CONFIGURATION_H #include @@ -71,4 +71,4 @@ class rational_solution_configurationt const symbol_tablet &st); }; -#endif /* CEGIS_CONTROL_LEARN_RATIONAL_SOLUTION_CONFIGURATION_H_ */ +#endif // CPROVER_CEGIS_CONTROL_LEARN_RATIONAL_SOLUTION_CONFIGURATION_H diff --git a/src/cegis/control/learn/vector_solution_configuration.h b/src/cegis/control/learn/vector_solution_configuration.h index 034ac38a876..d79aae04eed 100644 --- a/src/cegis/control/learn/vector_solution_configuration.h +++ b/src/cegis/control/learn/vector_solution_configuration.h @@ -7,8 +7,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#ifndef CEGIS_CONTROL_LEARN_VECTOR_SOLUTION_CONFIGURATION_H_ -#define CEGIS_CONTROL_LEARN_VECTOR_SOLUTION_CONFIGURATION_H_ +#ifndef CPROVER_CEGIS_CONTROL_LEARN_VECTOR_SOLUTION_CONFIGURATION_H +#define CPROVER_CEGIS_CONTROL_LEARN_VECTOR_SOLUTION_CONFIGURATION_H #include @@ -72,4 +72,4 @@ class vector_solution_configurationt const symbol_tablet &st); }; -#endif /* CEGIS_CONTROL_LEARN_VECTOR_SOLUTION_CONFIGURATION_H_ */ +#endif // CPROVER_CEGIS_CONTROL_LEARN_VECTOR_SOLUTION_CONFIGURATION_H diff --git a/src/cegis/control/value/control_vector_solution.h b/src/cegis/control/value/control_vector_solution.h index ec5d5de021a..6b118960711 100644 --- a/src/cegis/control/value/control_vector_solution.h +++ b/src/cegis/control/value/control_vector_solution.h @@ -7,8 +7,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#ifndef CEGIS_CONTROL_VALUE_CONTROL_VECTOR_SOLUTION_H_ -#define CEGIS_CONTROL_VALUE_CONTROL_VECTOR_SOLUTION_H_ +#ifndef CPROVER_CEGIS_CONTROL_VALUE_CONTROL_VECTOR_SOLUTION_H +#define CPROVER_CEGIS_CONTROL_VALUE_CONTROL_VECTOR_SOLUTION_H #include @@ -28,4 +28,4 @@ class control_vector_solutiont array_exprt K; }; -#endif /* CEGIS_CONTROL_VALUE_CONTROL_VECTOR_SOLUTION_H_ */ +#endif // CPROVER_CEGIS_CONTROL_VALUE_CONTROL_VECTOR_SOLUTION_H diff --git a/src/cegis/control/verify/zero_solutions.h b/src/cegis/control/verify/zero_solutions.h index 8e28c8767c4..b1e47dfa3ff 100644 --- a/src/cegis/control/verify/zero_solutions.h +++ b/src/cegis/control/verify/zero_solutions.h @@ -7,8 +7,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#ifndef CEGIS_CONTROL_VERIFY_ZERO_SOLUTIONS_H_ -#define CEGIS_CONTROL_VERIFY_ZERO_SOLUTIONS_H_ +#ifndef CPROVER_CEGIS_CONTROL_VERIFY_ZERO_SOLUTIONS_H +#define CPROVER_CEGIS_CONTROL_VERIFY_ZERO_SOLUTIONS_H /** * @brief @@ -77,4 +77,4 @@ class zero_vector_solutiont void operator()(class control_vector_solutiont &solution) const; }; -#endif /* CEGIS_CONTROL_VERIFY_ZERO_SOLUTIONS_H_ */ +#endif // CPROVER_CEGIS_CONTROL_VERIFY_ZERO_SOLUTIONS_H From fabac07cf7f4b7f67f4e6682658c5763276c830f Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 17 Jan 2017 19:52:13 -0500 Subject: [PATCH 046/166] clobber: update to current APIs --- src/clobber/clobber_parse_options.cpp | 120 +++++++------------------- src/clobber/clobber_parse_options.h | 2 + 2 files changed, 31 insertions(+), 91 deletions(-) diff --git a/src/clobber/clobber_parse_options.cpp b/src/clobber/clobber_parse_options.cpp index 4ed417014cd..bff5e163c4f 100644 --- a/src/clobber/clobber_parse_options.cpp +++ b/src/clobber/clobber_parse_options.cpp @@ -35,7 +35,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "clobber_parse_options.h" -#include "clobber_instrumenter.h" +// #include "clobber_instrumenter.h" /*******************************************************************\ @@ -51,7 +51,8 @@ Function: clobber_parse_optionst::clobber_parse_optionst clobber_parse_optionst::clobber_parse_optionst(int argc, const char **argv): parse_options_baset(CLOBBER_OPTIONS, argc, argv), - language_uit("CLOBBER " CBMC_VERSION, cmdline) + language_uit(cmdline, ui_message_handler), + ui_message_handler(cmdline, "CLOBBER " CBMC_VERSION) { } @@ -74,7 +75,7 @@ void clobber_parse_optionst::eval_verbosity() if(cmdline.isset("verbosity")) { - v=unsafe_string2int(cmdline.getval("verbosity")); + v=unsafe_string2int(cmdline.get_value("verbosity")); if(v<0) v=0; else if(v>10) @@ -105,10 +106,10 @@ void clobber_parse_optionst::get_command_line_options(optionst &options) } if(cmdline.isset("debug-level")) - options.set_option("debug-level", cmdline.getval("debug-level")); + options.set_option("debug-level", cmdline.get_value("debug-level")); if(cmdline.isset("unwindset")) - options.set_option("unwindset", cmdline.getval("unwindset")); + options.set_option("unwindset", cmdline.get_value("unwindset")); // all checks supported by goto_check GOTO_CHECK_PARSE_OPTIONS(cmdline, options); @@ -127,7 +128,7 @@ void clobber_parse_optionst::get_command_line_options(optionst &options) // magic error label if(cmdline.isset("error-label")) - options.set_option("error-label", cmdline.getval("error-label")); + options.set_option("error-label", cmdline.get_value("error-label")); } /*******************************************************************\ @@ -164,25 +165,24 @@ int clobber_parse_optionst::doit() goto_functionst goto_functions; - if(get_goto_program(options, goto_functions)) - return 6; + try + { + if(get_goto_program(options, goto_functions)) + return 6; - label_properties(goto_functions); + label_properties(goto_functions); - if(cmdline.isset("show-properties")) - { - const namespacet ns(symbol_table); - show_properties(ns, get_ui(), goto_functions); - return 0; - } + if(cmdline.isset("show-properties")) + { + const namespacet ns(symbol_table); + show_properties(ns, get_ui(), goto_functions); + return 0; + } - if(set_properties(goto_functions)) - return 7; + set_properties(goto_functions); - // do instrumentation + // do instrumentation - try - { const namespacet ns(symbol_table); std::ofstream out("simulator.c"); @@ -209,6 +209,12 @@ int clobber_parse_optionst::doit() return 8; } + catch(std::bad_alloc) + { + error() << "Out of memory" << messaget::eom; + return 8; + } + #if 0 // let's log some more statistics debug() << "Memory consumption:" << messaget::endl; @@ -231,28 +237,8 @@ Function: clobber_parse_optionst::set_properties bool clobber_parse_optionst::set_properties(goto_functionst &goto_functions) { - try - { - if(cmdline.isset("property")) - ::set_properties(goto_functions, cmdline.get_values("property")); - } - - catch(const char *e) - { - error(e); - return true; - } - - catch(const std::string e) - { - error(e); - return true; - } - - catch(int) - { - return true; - } + if(cmdline.isset("property")) + ::set_properties(goto_functions, cmdline.get_values("property")); return false; } @@ -279,7 +265,6 @@ bool clobber_parse_optionst::get_goto_program( return true; } - try { if(cmdline.args.size()==1 && is_goto_binary(cmdline.args[0])) @@ -290,7 +275,7 @@ bool clobber_parse_optionst::get_goto_program( symbol_table, goto_functions, get_message_handler())) return true; - config.ansi_c.set_from_symbol_table(symbol_table); + config.set_from_symbol_table(symbol_table); if(cmdline.isset("show-symbol-table")) { @@ -388,29 +373,6 @@ bool clobber_parse_optionst::get_goto_program( return true; } - catch(const char *e) - { - error(e); - return true; - } - - catch(const std::string e) - { - error(e); - return true; - } - - catch(int) - { - return true; - } - - catch(std::bad_alloc) - { - error() << "Out of memory" << eom; - return true; - } - return false; } @@ -430,7 +392,6 @@ bool clobber_parse_optionst::process_goto_program( const optionst &options, goto_functionst &goto_functions) { - try { namespacet ns(symbol_table); @@ -469,29 +430,6 @@ bool clobber_parse_optionst::process_goto_program( } } - catch(const char *e) - { - error(e); - return true; - } - - catch(const std::string e) - { - error(e); - return true; - } - - catch(int) - { - return true; - } - - catch(std::bad_alloc) - { - error() << "Out of memory" << eom; - return true; - } - return false; } diff --git a/src/clobber/clobber_parse_options.h b/src/clobber/clobber_parse_options.h index 06e1f79843d..8d1705cf0e0 100644 --- a/src/clobber/clobber_parse_options.h +++ b/src/clobber/clobber_parse_options.h @@ -44,6 +44,8 @@ class clobber_parse_optionst: const std::string &extra_options); protected: + ui_message_handlert ui_message_handler; + void get_command_line_options(optionst &options); bool get_goto_program( From 40413ed56c9b3d7186082ad9d93acecc39ca0fc2 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 17 Jan 2017 19:53:01 -0500 Subject: [PATCH 047/166] memory-models: Use ID_c_enum as ID_enum no longer exists --- src/memory-models/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/memory-models/parser.y b/src/memory-models/parser.y index 920c4b8b97f..69ce183a7a3 100644 --- a/src/memory-models/parser.y +++ b/src/memory-models/parser.y @@ -501,7 +501,7 @@ instruction: { $$=$1; stack($$).id(ID_code); - stack($$).set(ID_statement, ID_enum); + stack($$).set(ID_statement, ID_c_enum); mto($$, $2); mto($$, $4); } From ac36beacdf606ee31afef0680e21104a2a6a4760 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Wed, 18 Jan 2017 00:57:16 -0500 Subject: [PATCH 048/166] Merge improvements from aa-symex Use ranged for/forall macros, header cleanup, clear() functions. --- src/path-symex/loc_ref.h | 2 +- src/path-symex/path_symex.h | 7 ++--- src/path-symex/path_symex_history.h | 6 +++++ src/path-symex/var_map.h | 9 +++++++ src/symex/path_search.cpp | 41 +++++++++-------------------- 5 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/path-symex/loc_ref.h b/src/path-symex/loc_ref.h index 72e407c2a56..d11877683c2 100644 --- a/src/path-symex/loc_ref.h +++ b/src/path-symex/loc_ref.h @@ -16,7 +16,7 @@ class loc_reft public: unsigned loc_number; - inline loc_reft next_loc() + inline loc_reft next_loc() const { loc_reft tmp=*this; tmp.increase(); diff --git a/src/path-symex/path_symex.h b/src/path-symex/path_symex.h index d78e8f042bb..a37777d5f22 100644 --- a/src/path-symex/path_symex.h +++ b/src/path-symex/path_symex.h @@ -9,14 +9,15 @@ Author: Daniel Kroening, kroening@kroening.com #ifndef CPROVER_PATH_SYMEX_PATH_SYMEX_H #define CPROVER_PATH_SYMEX_PATH_SYMEX_H -#include "locs.h" #include "path_symex_state.h" // Transform a state by executing a single statement. // May occasionally yield more than one successor state -// (branches, function calls with trinary operator), -// which are put at the end of "further_states". +// (branches, function calls with ternary operator), +// which are put into "further_states". +// \pre: "!further_states.empty()" because "state" must +// be stored inside "further_states" void path_symex( path_symex_statet &state, std::list &further_states); diff --git a/src/path-symex/path_symex_history.h b/src/path-symex/path_symex_history.h index d7018f1a0e6..95d10771091 100644 --- a/src/path-symex/path_symex_history.h +++ b/src/path-symex/path_symex_history.h @@ -140,6 +140,12 @@ class path_symex_historyt public: typedef std::vector step_containert; step_containert step_container; + + // TODO: consider typedefing path_symex_historyt + inline void clear() + { + step_container.clear(); + } }; inline void path_symex_step_reft::generate_successor() diff --git a/src/path-symex/var_map.h b/src/path-symex/var_map.h index 08bd6e7208e..38a7b1ee1a9 100644 --- a/src/path-symex/var_map.h +++ b/src/path-symex/var_map.h @@ -78,6 +78,15 @@ class var_mapt return id_map[full_identifier]; } + void clear() + { + shared_count=0; + local_count=0; + nondet_count=0; + dynamic_count=0; + id_map.clear(); + } + void init(var_infot &var_info); const namespacet &ns; diff --git a/src/symex/path_search.cpp b/src/symex/path_search.cpp index 106fd9cba23..1a34951f9b1 100644 --- a/src/symex/path_search.cpp +++ b/src/symex/path_search.cpp @@ -271,21 +271,18 @@ void path_searcht::do_show_vcc(statet &state) std::vector steps; state.history.build_history(steps); - for(std::vector::const_iterator - s_it=steps.begin(); - s_it!=steps.end(); - s_it++) + for(const auto &step_ref : steps) { - if((*s_it)->guard.is_not_nil()) + if(step_ref->guard.is_not_nil()) { - std::string string_value=from_expr(ns, "", (*s_it)->guard); + std::string string_value=from_expr(ns, "", step_ref->guard); out << "{-" << count << "} " << string_value << '\n'; count++; } - if((*s_it)->ssa_rhs.is_not_nil()) + if(step_ref->ssa_rhs.is_not_nil()) { - equal_exprt equality((*s_it)->ssa_lhs, (*s_it)->ssa_rhs); + equal_exprt equality(step_ref->ssa_lhs, step_ref->ssa_rhs); std::string string_value=from_expr(ns, "", equality); out << "{-" << count << "} " << string_value << '\n'; count++; @@ -334,22 +331,16 @@ bool path_searcht::drop_state(const statet &state) const // unwinding limit -- loops if(unwind_limit_set && state.get_instruction()->is_backwards_goto()) { - for(path_symex_statet::unwinding_mapt::const_iterator - it=state.unwinding_map.begin(); - it!=state.unwinding_map.end(); - it++) - if(it->second>unwind_limit) + for(const auto &loop_info : state.unwinding_map) + if(loop_info.second>unwind_limit) return true; } // unwinding limit -- recursion if(unwind_limit_set && state.get_instruction()->is_function_call()) { - for(path_symex_statet::recursion_mapt::const_iterator - it=state.recursion_map.begin(); - it!=state.recursion_map.end(); - it++) - if(it->second>unwind_limit) + for(const auto &rec_info : state.recursion_map) + if(rec_info.second>unwind_limit) return true; } @@ -461,23 +452,17 @@ Function: path_searcht::initialize_property_map void path_searcht::initialize_property_map( const goto_functionst &goto_functions) { - for(goto_functionst::function_mapt::const_iterator - it=goto_functions.function_map.begin(); - it!=goto_functions.function_map.end(); - it++) + forall_goto_functions(it, goto_functions) if(!it->second.is_inlined()) { const goto_programt &goto_program=it->second.body; - for(goto_programt::instructionst::const_iterator - it=goto_program.instructions.begin(); - it!=goto_program.instructions.end(); - it++) + forall_goto_program_instructions(i_it, goto_program) { - if(!it->is_assert()) + if(!i_it->is_assert()) continue; - const source_locationt &source_location=it->source_location; + const source_locationt &source_location=i_it->source_location; irep_idt property_name=source_location.get_property_id(); From 72c9b777eb27635b35f5fd64f7431918b6c8896f Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Wed, 18 Jan 2017 00:58:14 -0500 Subject: [PATCH 049/166] aa-symex: share files with symex, path-symex Directly use files or use symbolic links to pull in modified headers. Merged various improvements from symex, path-symex to make code as similar as possible. --- src/aa-path-symex/Makefile | 3 +- src/aa-path-symex/build_goto_trace.cpp | 124 +--- src/aa-path-symex/build_goto_trace.h | 23 +- src/aa-path-symex/loc_ref.h | 86 --- src/aa-path-symex/locs.cpp | 140 ---- src/aa-path-symex/locs.h | 107 ---- src/aa-path-symex/path_symex.cpp | 73 ++- src/aa-path-symex/path_symex.h | 43 +- src/aa-path-symex/path_symex_history.cpp | 63 -- src/aa-path-symex/path_symex_history.h | 164 ----- src/aa-path-symex/path_symex_state.cpp | 54 +- src/aa-path-symex/path_symex_state.h | 6 +- src/aa-path-symex/var_map.cpp | 118 ---- src/aa-path-symex/var_map.h | 121 ---- src/aa-symex/Makefile | 11 +- src/aa-symex/path_search.cpp | 70 +- src/aa-symex/path_search.h | 48 +- src/aa-symex/symex_main.cpp | 38 -- src/aa-symex/symex_parseoptions.cpp | 784 ----------------------- src/aa-symex/symex_parseoptions.h | 78 --- src/path-symex/path_symex.cpp | 7 +- 21 files changed, 172 insertions(+), 1989 deletions(-) mode change 100644 => 120000 src/aa-path-symex/build_goto_trace.cpp mode change 100644 => 120000 src/aa-path-symex/build_goto_trace.h delete mode 100644 src/aa-path-symex/loc_ref.h delete mode 100644 src/aa-path-symex/locs.cpp delete mode 100644 src/aa-path-symex/locs.h mode change 100644 => 120000 src/aa-path-symex/path_symex.h delete mode 100644 src/aa-path-symex/path_symex_history.cpp delete mode 100644 src/aa-path-symex/path_symex_history.h delete mode 100644 src/aa-path-symex/var_map.cpp delete mode 100644 src/aa-path-symex/var_map.h delete mode 100644 src/aa-symex/symex_main.cpp delete mode 100644 src/aa-symex/symex_parseoptions.cpp delete mode 100644 src/aa-symex/symex_parseoptions.h diff --git a/src/aa-path-symex/Makefile b/src/aa-path-symex/Makefile index 272a422aac0..9d3c4d96074 100644 --- a/src/aa-path-symex/Makefile +++ b/src/aa-path-symex/Makefile @@ -1,5 +1,4 @@ -SRC = locs.cpp var_map.cpp path_symex_history.cpp path_symex_state.cpp \ - path_symex.cpp build_goto_trace.cpp +SRC = path_symex_state.cpp path_symex.cpp build_goto_trace.cpp INCLUDES= -I .. diff --git a/src/aa-path-symex/build_goto_trace.cpp b/src/aa-path-symex/build_goto_trace.cpp deleted file mode 100644 index ac37f4ea6fb..00000000000 --- a/src/aa-path-symex/build_goto_trace.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/*******************************************************************\ - -Module: Build Goto Trace from State History - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#include "build_goto_trace.h" - -/*******************************************************************\ - -Function: build_goto_trace - - Inputs: - - Outputs: - - Purpose: follow state history to build a goto trace - -\*******************************************************************/ - -void build_goto_trace( - const path_symex_statet &state, - const decision_proceduret &decision_procedure, - goto_tracet &goto_trace) -{ - // follow the history in the state, - // but in a forwards-fashion - - std::vector steps; - state.history.build_history(steps); - - unsigned step_nr; - - for(step_nr=0; step_nr -#include - -#include "path_symex_state.h" - -void build_goto_trace( - const path_symex_statet &state, - const decision_proceduret &decision_procedure, - goto_tracet &goto_trace); - -#endif // CPROVER_AA_PATH_SYMEX_BUILD_GOTO_TRACE_H diff --git a/src/aa-path-symex/build_goto_trace.h b/src/aa-path-symex/build_goto_trace.h new file mode 120000 index 00000000000..3183a6b0910 --- /dev/null +++ b/src/aa-path-symex/build_goto_trace.h @@ -0,0 +1 @@ +../path-symex/build_goto_trace.h \ No newline at end of file diff --git a/src/aa-path-symex/loc_ref.h b/src/aa-path-symex/loc_ref.h deleted file mode 100644 index 37e6935c6da..00000000000 --- a/src/aa-path-symex/loc_ref.h +++ /dev/null @@ -1,86 +0,0 @@ -/*******************************************************************\ - -Module: Program Locations - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#ifndef CPROVER_AA_PATH_SYMEX_LOC_REF_H -#define CPROVER_AA_PATH_SYMEX_LOC_REF_H - -#include - -class loc_reft -{ -public: - unsigned loc_number; - - inline loc_reft next_loc() const - { - loc_reft tmp=*this; - tmp.increase(); - return tmp; - } - - inline void increase() - { - loc_number++; - } - - inline void decrease() - { - loc_number--; - } - - inline bool is_nil() const - { - return loc_number==nil().loc_number; - } - - loc_reft():loc_number(-1) // ugly conversion - { - } - - static inline loc_reft nil() - { - return loc_reft(); - } - - inline loc_reft &operator++() // this is pre-increment - { - increase(); - return *this; - } - - inline loc_reft &operator--() // this is pre-decrement - { - decrease(); - return *this; - } -}; - -static inline bool operator < (const loc_reft l1, const loc_reft l2) -{ - return l1.loc_number < l2.loc_number; -} - -static inline bool operator != (const loc_reft l1, const loc_reft l2) -{ - return l1.loc_number != l2.loc_number; -} - -static inline bool operator == (const loc_reft l1, const loc_reft l2) -{ - return l1.loc_number == l2.loc_number; -} - -static inline std::ostream &operator << (std::ostream &out, loc_reft l) -{ - if(l.is_nil()) - return out << "nil"; - else - return out << l.loc_number; -} - -#endif // CPROVER_AA_PATH_SYMEX_LOC_REF_H diff --git a/src/aa-path-symex/locs.cpp b/src/aa-path-symex/locs.cpp deleted file mode 100644 index 5afbd8ac84a..00000000000 --- a/src/aa-path-symex/locs.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/*******************************************************************\ - -Module: Program Locations - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#include "locs.h" - -/*******************************************************************\ - -Function: locst::locst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -locst::locst( - const namespacet &_ns): - ns(_ns) -{ -} - -/*******************************************************************\ - -Function: locst::build - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void locst::build(const goto_functionst &goto_functions) -{ - // build locations - - typedef std::map target_mapt; - - target_mapt target_map; - - forall_goto_functions(f_it, goto_functions) - { - const goto_functionst::goto_functiont &goto_function = f_it->second; - - function_entryt &function_entry=function_map[f_it->first]; - function_entry.type=goto_function.type; - - if(goto_function.body_available) - { - const loc_reft entry_loc=end(); - function_entry.first_loc=entry_loc; - - forall_goto_program_instructions(i_it, goto_function.body) - { - target_map[i_it]=end(); - loc_vector.push_back(loct(i_it, f_it->first)); - } - } - else - function_entry.first_loc=loc_reft::nil(); - } - - if(function_map.find(ID_main)==function_map.end()) - throw "no entry point"; - - entry_loc=function_map[ID_main].first_loc; - - // build branch targets - for(unsigned l=0; lsecond; - - if(target.loc_number>=loc_vector.size()) - throw "locst::build: illegal jump target"; - - loc_vector[l].branch_target=target; - } - else - throw "locst does not support more than one branch target"; - } -} - -/*******************************************************************\ - -Function: locst::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void locst::output(std::ostream &out) const -{ - irep_idt function; - - for(unsigned l=0; ltype << " " -// << loc.target->location - << " " << as_string(ns, *loc.target) << "\n"; - - if(!loc.branch_target.is_nil()) - out << " T: " << loc.branch_target << "\n"; - } - - out << "\n"; - out << "The entry location is L" << entry_loc << ".\n"; -} diff --git a/src/aa-path-symex/locs.h b/src/aa-path-symex/locs.h deleted file mode 100644 index 75e0ae29f7e..00000000000 --- a/src/aa-path-symex/locs.h +++ /dev/null @@ -1,107 +0,0 @@ -/*******************************************************************\ - -Module: CFG made of Program Locations, built from goto_functionst - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#ifndef CPROVER_AA_PATH_SYMEX_LOCS_H -#define CPROVER_AA_PATH_SYMEX_LOCS_H - -#include - -#include - -#include "loc_ref.h" - -struct loct -{ -public: - loct(goto_programt::const_targett _target, - const irep_idt &_function): - target(_target), - function(_function) - { - } - - goto_programt::const_targett target; - irep_idt function; - - // we only support a single branch target - loc_reft branch_target; -}; - -class locst -{ -public: - typedef std::vector loc_vectort; - loc_vectort loc_vector; - loc_reft entry_loc; - - class function_entryt - { - public: - loc_reft first_loc; - code_typet type; - }; - - typedef std::map function_mapt; - function_mapt function_map; - - locst(const namespacet &_ns); - void build(const goto_functionst &goto_functions); - void output(std::ostream &out) const; - - inline loct &operator[] (loc_reft l) - { - assert(l.loc_number>=0 && l.loc_number < loc_vector.size()); - return loc_vector[l.loc_number]; - } - - inline const loct &operator[] (loc_reft l) const - { - assert(l.loc_number>=0 && l.loc_number < loc_vector.size()); - return loc_vector[l.loc_number]; - } - - static inline loc_reft begin() - { - loc_reft tmp; - tmp.loc_number=0; - return tmp; - } - - inline loc_reft end() const - { - loc_reft tmp; - tmp.loc_number=loc_vector.size(); - return tmp; - } - -protected: - const namespacet &ns; -}; - -class target_to_loc_mapt -{ -public: - explicit target_to_loc_mapt(const locst &locs) - { - for(loc_reft it=locs.begin(); it!=locs.end(); ++it) - map[locs[it].target]=it; - } - - inline loc_reft operator[](const goto_programt::const_targett t) const - { - mapt::const_iterator it=map.find(t); - assert(it!=map.end()); - return it->second; - } - -protected: - typedef std::map mapt; - mapt map; -}; - -#endif // CPROVER_AA_PATH_SYMEX_LOCS_H diff --git a/src/aa-path-symex/path_symex.cpp b/src/aa-path-symex/path_symex.cpp index 83e56461136..0ead6c840ba 100644 --- a/src/aa-path-symex/path_symex.cpp +++ b/src/aa-path-symex/path_symex.cpp @@ -187,7 +187,7 @@ void path_symext::assign( const exprt &lhs, const exprt &rhs) { - if(rhs.id()==ID_sideeffect) // catch side effects on rhs + if(rhs.id()==ID_side_effect) // catch side effects on rhs { const side_effect_exprt &side_effect_expr=to_side_effect_expr(rhs); const irep_idt &statement=side_effect_expr.get_statement(); @@ -208,7 +208,7 @@ void path_symext::assign( // read the address of the lhs, with propagation exprt lhs_address=state.read(address_of_exprt(lhs)); - // now SSA it, no propagation + // now SSA the lhs, no propagation exprt ssa_lhs= state.read_no_propagate(dereference_exprt(lhs_address)); @@ -285,7 +285,7 @@ void path_symext::symex_malloc( if(tmp_type.is_not_nil()) { // Did the size get multiplied? - mp_integer elem_size=pointer_offset_size(state.var_map.ns, tmp_type); + mp_integer elem_size=pointer_offset_size(tmp_type, state.var_map.ns); mp_integer alloc_size; if(elem_size<0 || to_integer(tmp_size, alloc_size)) { @@ -395,7 +395,7 @@ void path_symext::assign_rec( if(ssa_lhs.id()==ID_symbol) { - // These are expected to the SSA symbols + // These are expected to be SSA symbols assert(ssa_lhs.get_bool(ID_C_SSA_symbol)); const symbol_exprt &symbol_expr=to_symbol_expr(ssa_lhs); @@ -471,17 +471,27 @@ void path_symext::assign_rec( if(compound_type.id()==ID_struct) { - throw "unexpected struct member on lhs"; + // We flatten the top-level structs, so this one is inside an + // array or a union. + + exprt member_name(ID_member_name); + member_name.set( + ID_component_name, + ssa_lhs_member_expr.get_component_name()); + + with_exprt new_rhs(struct_op, member_name, ssa_rhs); + + assign_rec(state, guard, struct_op, new_rhs); } else if(compound_type.id()==ID_union) { - // adjust the rhs - union_exprt new_rhs; - new_rhs.type()=struct_op.type(); - new_rhs.set_component_name(ssa_lhs_member_expr.get_component_name()); - new_rhs.op()=ssa_rhs; + // rewrite into byte_extract, and do again + exprt offset=gen_zero(index_type()); - assign_rec(state, guard, struct_op, new_rhs); + byte_extract_exprt + new_lhs(byte_update_id(), struct_op, offset, ssa_rhs.type()); + + assign_rec(state, guard, new_lhs, ssa_rhs); } else throw "assign_rec: member expects struct or union type"; @@ -566,7 +576,7 @@ void path_symext::assign_rec( assert(operands.size()==components.size()); - for(unsigned i=0; i &further_states); - -// Transform a state by executing a single statement. -// Will fail if there is more than one successor state. -void path_symex(path_symex_statet &state); - -// Transforms a state by executing a goto statement; -// the 'taken' argument indicates which way. -void path_symex_goto( - path_symex_statet &state, - bool taken); - -// Transforms a state by executing an assertion statement; -// it is enforced that the assertion fails. -void path_symex_assert_fail( - path_symex_statet &state); - -#endif // CPROVER_AA_PATH_SYMEX_PATH_SYMEX_H diff --git a/src/aa-path-symex/path_symex.h b/src/aa-path-symex/path_symex.h new file mode 120000 index 00000000000..538d30846d4 --- /dev/null +++ b/src/aa-path-symex/path_symex.h @@ -0,0 +1 @@ +../path-symex/path_symex.h \ No newline at end of file diff --git a/src/aa-path-symex/path_symex_history.cpp b/src/aa-path-symex/path_symex_history.cpp deleted file mode 100644 index e35cd62d337..00000000000 --- a/src/aa-path-symex/path_symex_history.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/*******************************************************************\ - -Module: History of path-based symbolic simulator - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#include - -#include - -#include "path_symex_history.h" - -/*******************************************************************\ - -Function: path_symex_stept::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void path_symex_stept::output(std::ostream &out) const -{ - out << "PCs:"; - -/* - for(const auto &pc : s_it->pc_vector) - out << " " << pc; - */ - out << "\n"; - - out << "Guard: " << from_expr(guard) << "\n"; - out << "Full LHS: " << from_expr(full_lhs) << "\n"; - out << "SSA LHS: " << from_expr(ssa_lhs) << "\n"; - out << "SSA RHS: " << from_expr(ssa_rhs) << "\n"; - out << "\n"; -} - -/*******************************************************************\ - -Function: path_symex_stept::convert - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void path_symex_stept::convert(decision_proceduret &dest) const -{ - if(ssa_rhs.is_not_nil()) - dest << equal_exprt(ssa_lhs, ssa_rhs); - - if(guard.is_not_nil()) - dest << guard; -} diff --git a/src/aa-path-symex/path_symex_history.h b/src/aa-path-symex/path_symex_history.h deleted file mode 100644 index c2a261b7fdf..00000000000 --- a/src/aa-path-symex/path_symex_history.h +++ /dev/null @@ -1,164 +0,0 @@ -/*******************************************************************\ - -Module: History for path-based symbolic simulator - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#ifndef CPROVER_AA_PATH_SYMEX_PATH_SYMEX_HISTORY_H -#define CPROVER_AA_PATH_SYMEX_PATH_SYMEX_HISTORY_H - -#include -#include - -#include - -#include "loc_ref.h" - -class path_symex_stept; - -// This is a reference to a path_symex_stept, -// and is really cheap to copy. These references are stable, -// even though the underlying vector is not. -class path_symex_step_reft -{ -public: - explicit inline path_symex_step_reft( - class path_symex_historyt &_history): - index(std::numeric_limits::max()), - history(&_history) - { - } - - inline path_symex_step_reft(): - index(std::numeric_limits::max()), history(0) - { - } - - inline bool is_nil() const - { - return index==std::numeric_limits::max(); - } - - inline path_symex_historyt &get_history() const - { - assert(history!=0); - return *history; - } - - // pre-decrement - inline path_symex_step_reft &operator--(); - - inline path_symex_stept &operator*() const { return get(); } - inline path_symex_stept *operator->() const { return &get(); } - - void generate_successor(); - - // build a forward-traversible version of the history - void build_history(std::vector &dest) const; - -protected: - // we use a vector to store all steps - std::size_t index; - class path_symex_historyt *history; - - inline path_symex_stept &get() const; -}; - -class decision_proceduret; - -// the actual history node -class path_symex_stept -{ -public: - path_symex_step_reft predecessor; - - // the thread that did the step - unsigned thread_nr; - - // the instruction that was executed - loc_reft pc; - - exprt guard, ssa_rhs; - exprt full_lhs; - symbol_exprt ssa_lhs; - - bool hidden; - - path_symex_stept(): - guard(nil_exprt()), - ssa_rhs(nil_exprt()), - full_lhs(nil_exprt()), - hidden(false) - { - } - - // interface to solvers; this converts a single step - void convert(decision_proceduret &dest) const; - - void output(std::ostream &) const; -}; - -// converts the full history -static inline decision_proceduret &operator << ( - decision_proceduret &dest, - path_symex_step_reft src) -{ - while(!src.is_nil()) - { - src->convert(dest); - --src; - } - - return dest; -} - -// this stores the forest of histories -class path_symex_historyt -{ -public: - typedef std::vector step_containert; - step_containert step_container; - - // TODO: consider typedefing path_symex_historyt - inline void clear() - { - step_container.clear(); - } -}; - -inline void path_symex_step_reft::generate_successor() -{ - assert(history!=0); - path_symex_step_reft old=*this; - index=history->step_container.size(); - history->step_container.push_back(path_symex_stept()); - history->step_container.back().predecessor=old; -} - -inline path_symex_step_reft &path_symex_step_reft::operator--() -{ - *this=get().predecessor; - return *this; -} - -inline path_symex_stept &path_symex_step_reft::get() const -{ - assert(history!=0); - assert(!is_nil()); - return history->step_container[index]; -} - -inline void path_symex_step_reft::build_history( - std::vector &dest) const -{ - path_symex_step_reft s=*this; - while(!s.is_nil()) - { - dest.push_back(s); - --s; - } -} - -#endif // CPROVER_AA_PATH_SYMEX_PATH_SYMEX_HISTORY_H diff --git a/src/aa-path-symex/path_symex_state.cpp b/src/aa-path-symex/path_symex_state.cpp index a078c4c2e65..124b0e7fea9 100644 --- a/src/aa-path-symex/path_symex_state.cpp +++ b/src/aa-path-symex/path_symex_state.cpp @@ -17,6 +17,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include "path_symex_state.h" @@ -153,27 +154,31 @@ exprt path_symex_statet::read(const exprt &src, bool propagate) //std::cout << "path_symex_statet::read " << src.pretty() << std::endl; #endif - // This has four phases! + // This has five phases! // 1. Floating-point expression adjustment (rounding mode) - // 2. Dereferencing, including propagation of pointers. - // 3. Rewriting to SSA symbols - // 4. Simplifier + // 2. Rewrite unions into byte operators + // 3. Dereferencing, including propagation of pointers. + // 4. Rewriting to SSA symbols + // 5. Simplifier exprt tmp1=src; adjust_float_expressions(tmp1, var_map.ns); + exprt tmp2=tmp1; + rewrite_union(tmp2, var_map.ns); + // we force propagation for dereferencing - exprt tmp2=dereference_rec(tmp1, true); + exprt tmp3=dereference_rec(tmp2, true); - exprt tmp3=instantiate_rec(tmp2, propagate); + exprt tmp4=instantiate_rec(tmp3, propagate); - exprt tmp4=simplify_expr(tmp3, var_map.ns); + exprt tmp5=simplify_expr(tmp4, var_map.ns); #ifdef DEBUG //std::cout << " ==> " << tmp.pretty() << std::endl; #endif - return tmp4; + return tmp5; } /*******************************************************************\ @@ -239,13 +244,13 @@ exprt path_symex_statet::instantiate_rec( if(to_integer(array_type.size(), size)) throw "failed to convert array size"; - unsigned long long size_int=integer2unsigned(size); + std::size_t size_int=integer2size_t(size); array_exprt result(array_type); result.operands().resize(size_int); // split it up into elements - for(unsigned long long i=0; i -#include "locs.h" -#include "var_map.h" -#include "path_symex_history.h" +#include +#include +#include // These variables may be defined in this header file only because // it is (transitively) included by many essential path-symex files. diff --git a/src/aa-path-symex/var_map.cpp b/src/aa-path-symex/var_map.cpp deleted file mode 100644 index 941a8645a6f..00000000000 --- a/src/aa-path-symex/var_map.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/*******************************************************************\ - -Module: Variable Numbering - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#include -#include -#include - -#include "var_map.h" - -// #define DEBUG - -/*******************************************************************\ - -Function: var_mapt::var_infot::output - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void var_mapt::var_infot::output(std::ostream &out) const -{ - out << "full_identifier: " << full_identifier << "\n"; - out << "symbol: " << symbol << "\n"; - out << "suffix: " << suffix << "\n"; - - out << "kind: "; - - switch(kind) - { - case PROCEDURE_LOCAL: out << "PROCEDURE_LOCAL"; break; - case THREAD_LOCAL: out << "THREAD_LOCAL"; break; - case SHARED: out << "SHARED"; break; - } - - out << "\n"; - - out << "number: " << number << "\n"; - - out << "type: " << type << "\n"; - - out << "\n"; -} - -/*******************************************************************\ - -Function: var_mapt::init - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void var_mapt::init(var_infot &var_info) -{ - if(has_prefix(id2string(var_info.symbol), "symex_dynamic::")) - { - var_info.kind=var_infot::SHARED; - } - else - { - try - { - const symbolt &symbol=ns.lookup(var_info.symbol); - - if(symbol.is_static_lifetime) - { - if(symbol.is_thread_local) - var_info.kind=var_infot::THREAD_LOCAL; - else - var_info.kind=var_infot::SHARED; - } - else - var_info.kind=var_infot::PROCEDURE_LOCAL; - } - - catch(std::string s) - { - throw "var_mapt::init identifier \"" + - id2string(var_info.full_identifier)+ - "\" lookup in ns failed"; - } - } - - if(var_info.is_shared()) - var_info.number=shared_count++; - else - var_info.number=local_count++; -} - -/*******************************************************************\ - -Function: var_mapt::var_infot::ssa_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -irep_idt var_mapt::var_infot::ssa_identifier() const -{ - return id2string(full_identifier)+ - "#"+std::to_string(ssa_counter); -} diff --git a/src/aa-path-symex/var_map.h b/src/aa-path-symex/var_map.h deleted file mode 100644 index 00c95ec3ad5..00000000000 --- a/src/aa-path-symex/var_map.h +++ /dev/null @@ -1,121 +0,0 @@ -/*******************************************************************\ - -Module: Variable Numbering - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#ifndef CPROVER_AA_PATH_SYMEX_VAR_MAP_H -#define CPROVER_AA_PATH_SYMEX_VAR_MAP_H - -#include - -#include -#include - -class var_mapt -{ -public: - explicit var_mapt(const namespacet &_ns): - ns(_ns), shared_count(0), local_count(0), nondet_count(0), dynamic_count(0) - { - } - - struct var_infot - { - enum { SHARED, THREAD_LOCAL, PROCEDURE_LOCAL } kind; - - inline bool is_shared() const - { - return kind==SHARED; - } - - // the variables are numbered - unsigned number; - - // full_identifier=symbol+suffix - irep_idt full_identifier, symbol, suffix; - - // the type of the identifier (struct member or array) - typet type; - - unsigned ssa_counter; - - var_infot():kind(SHARED), number(0), ssa_counter(0) - { - } - - irep_idt ssa_identifier() const; - - symbol_exprt ssa_symbol() const - { - symbol_exprt s=symbol_exprt(ssa_identifier(), type); - s.set(ID_C_SSA_symbol, true); - s.set(ID_C_full_identifier, full_identifier); - return s; - } - - inline void increment_ssa_counter() - { - ++ssa_counter; - } - - void output(std::ostream &out) const; - }; - - typedef std::map id_mapt; - id_mapt id_map; - - inline var_infot &operator()( - const irep_idt &symbol, - const irep_idt &suffix, - const typet &type) - { - std::string full_identifier= - id2string(symbol)+id2string(suffix); - - std::pair result; - - result=id_map.insert(std::pair( - full_identifier, var_infot())); - - if(result.second) // inserted? - { - result.first->second.full_identifier=full_identifier; - result.first->second.symbol=symbol; - result.first->second.suffix=suffix; - result.first->second.type=type; - init(result.first->second); - } - - return result.first->second; - } - - inline var_infot &operator[](const irep_idt &full_identifier) - { - return id_map[full_identifier]; - } - - inline void clear() - { - shared_count=0; - local_count=0; - nondet_count=0; - dynamic_count=0; - id_map.clear(); - } - - void init(var_infot &var_info); - - const namespacet &ns; - -protected: - unsigned shared_count, local_count; - -public: - unsigned nondet_count; // free inputs - unsigned dynamic_count; // memory allocation -}; - -#endif // CPROVER_AA_PATH_SYMEX_VAR_MAP_H diff --git a/src/aa-symex/Makefile b/src/aa-symex/Makefile index 5ff56e5ded2..a5e2b0ad5d8 100644 --- a/src/aa-symex/Makefile +++ b/src/aa-symex/Makefile @@ -1,4 +1,4 @@ -SRC = symex_main.cpp symex_parseoptions.cpp path_search.cpp +SRC = path_search.cpp OBJ += ../ansi-c/ansi-c$(LIBEXT) \ ../linking/linking$(LIBEXT) \ @@ -11,8 +11,15 @@ OBJ += ../ansi-c/ansi-c$(LIBEXT) \ ../solvers/solvers$(LIBEXT) \ ../util/util$(LIBEXT) \ ../goto-symex/adjust_float_expressions$(OBJEXT) \ + ../goto-symex/rewrite_union$(OBJEXT) \ ../pointer-analysis/dereference$(OBJEXT) \ - ../aa-path-symex/aa-path-symex$(LIBEXT) + ../goto-instrument/cover$(OBJEXT) \ + ../aa-path-symex/aa-path-symex$(LIBEXT) \ + ../symex/symex_main$(OBJEXT) \ + ../symex/symex_parse_options$(OBJEXT) \ + ../symex/symex_cover$(OBJEXT) \ + ../path-symex/locs$(OBJEXT) ../path-symex/var_map$(OBJEXT) \ + ../path-symex/path_symex_history$(OBJEXT) INCLUDES= -I .. diff --git a/src/aa-symex/path_search.cpp b/src/aa-symex/path_search.cpp index 9b8d2295a45..b6fdfdd70dd 100644 --- a/src/aa-symex/path_search.cpp +++ b/src/aa-symex/path_search.cpp @@ -44,7 +44,8 @@ path_searcht::resultt path_searcht::operator()( // run concurrently. This could be remedied by piping // to individual files or inter-process communication, // a performance bottleneck, however. - *messaget::mstream.message_handler=NULL; + null_message_handlert null_message; + set_message_handler(null_message); #endif locst locs(ns); @@ -58,9 +59,9 @@ path_searcht::resultt path_searcht::operator()( queue.push_back(initial_state(var_map, locs, history)); // set up the statistics - number_of_paths=0; number_of_instructions=0; number_of_dropped_states=0; + number_of_paths=0; number_of_VCCs=0; number_of_VCCs_after_simplification=0; number_of_failed_properties=0; @@ -136,10 +137,10 @@ path_searcht::resultt path_searcht::operator()( if(state->get_instruction()->is_assert()) { if(show_vcc) - do_show_vcc(*state, ns); + do_show_vcc(*state); else { - check_assertion(*state, ns); + check_assertion(*state); // all assertions failed? if(number_of_failed_properties==property_map.size()) @@ -271,8 +272,6 @@ Function: path_searcht::report_statistics void path_searcht::report_statistics() { // report a bit - status() << "Number of paths: " - << number_of_paths << messaget::eom; status() << "Number of instructions: " << number_of_instructions << messaget::eom; @@ -280,6 +279,9 @@ void path_searcht::report_statistics() status() << "Number of dropped states: " << number_of_dropped_states << messaget::eom; + status() << "Number of paths: " + << number_of_paths << messaget::eom; + status() << "Number of fast forward steps: " << number_of_fast_forward_steps << messaget::eom; @@ -323,9 +325,7 @@ Function: path_searcht::do_show_vcc \*******************************************************************/ -void path_searcht::do_show_vcc( - statet &state, - const namespacet &ns) +void path_searcht::do_show_vcc(statet &state) { // keep statistics number_of_VCCs++; @@ -335,11 +335,11 @@ void path_searcht::do_show_vcc( mstreamt &out=result(); - if(instruction.location.is_not_nil()) - out << instruction.location << "\n"; + if(instruction.source_location.is_not_nil()) + out << instruction.source_location << '\n'; - if(instruction.location.get_comment()!="") - out << instruction.location.get_comment() << "\n"; + if(instruction.source_location.get_comment()!="") + out << instruction.source_location.get_comment() << '\n'; unsigned count=1; @@ -351,25 +351,25 @@ void path_searcht::do_show_vcc( if(step_ref->guard.is_not_nil()) { std::string string_value=from_expr(ns, "", step_ref->guard); - out << "{-" << count << "} " << string_value << "\n"; + out << "{-" << count << "} " << string_value << '\n'; count++; } - if((*s_it)->ssa_rhs.is_not_nil()) + if(step_ref->ssa_rhs.is_not_nil()) { - equal_exprt equality((*s_it)->ssa_lhs, (*s_it)->ssa_rhs); + equal_exprt equality(step_ref->ssa_lhs, step_ref->ssa_rhs); std::string string_value=from_expr(ns, "", equality); - out << "{-" << count << "} " << string_value << "\n"; + out << "{-" << count << "} " << string_value << '\n'; count++; } } - out << "|--------------------------" << "\n"; + out << "|--------------------------" << '\n'; exprt assertion=state.read(instruction.guard); out << "{" << 1 << "} " - << from_expr(ns, "", assertion) << "\n"; + << from_expr(ns, "", assertion) << '\n'; if(!assertion.is_true()) number_of_VCCs_after_simplification++; @@ -391,14 +391,17 @@ Function: path_searcht::drop_state bool path_searcht::drop_state(const statet &state) const { - // depth - if(depth_limit!=-1 && state.get_depth()>depth_limit) return true; + // depth limit + if(depth_limit_set && state.get_depth()>depth_limit) + return true; // context bound - if(context_bound!=-1 && state.get_no_thread_interleavings()) return true; + if(context_bound_set && state.get_no_thread_interleavings()>context_bound) + return true; + // unwinding limit -- loops - if(unwind_limit!=-1 && state.get_instruction()->is_backwards_goto()) + if(unwind_limit_set && state.get_instruction()->is_backwards_goto()) { for(const auto &loop_info : state.unwinding_map) if(loop_info.second>unwind_limit) @@ -406,7 +409,7 @@ bool path_searcht::drop_state(const statet &state) const } // unwinding limit -- recursion - if(unwind_limit!=-1 && state.get_instruction()->is_function_call()) + if(unwind_limit_set && state.get_instruction()->is_function_call()) { for(const auto &rec_info : state.recursion_map) if(rec_info.second>unwind_limit) @@ -428,9 +431,7 @@ Function: path_searcht::check_assertion \*******************************************************************/ -void path_searcht::check_assertion( - statet &state, - const namespacet &ns) +void path_searcht::check_assertion(statet &state) { // keep statistics number_of_VCCs++; @@ -438,13 +439,13 @@ void path_searcht::check_assertion( const goto_programt::instructiont &instruction= *state.get_instruction(); - irep_idt property_name=instruction.location.get_property_id(); + irep_idt property_name=instruction.source_location.get_property_id(); property_entryt &property_entry=property_map[property_name]; - if(property_entry.status==FAIL) + if(property_entry.status==FAILURE) return; // already failed else if(property_entry.status==NOT_REACHED) - property_entry.status=PASS; // well, for now! + property_entry.status=SUCCESS; // well, for now! // the assertion in SSA exprt assertion= @@ -469,7 +470,7 @@ void path_searcht::check_assertion( if(!state.check_assertion(bv_pointers)) { build_goto_trace(state, bv_pointers, property_entry.error_trace); - property_entry.status=FAIL; + property_entry.status=FAILURE; number_of_failed_properties++; } @@ -501,13 +502,14 @@ void path_searcht::initialize_property_map( if(!i_it->is_assert()) continue; - const locationt &location=i_it->location; + const source_locationt &source_location=i_it->source_location; - irep_idt property_name=location.get_property_id(); + irep_idt property_name=source_location.get_property_id(); property_entryt &property_entry=property_map[property_name]; property_entry.status=NOT_REACHED; - property_entry.description=location.get_comment(); + property_entry.description=source_location.get_comment(); + property_entry.source_location=source_location; } } } diff --git a/src/aa-symex/path_search.h b/src/aa-symex/path_search.h index 3c546989fd2..7a6b270c040 100644 --- a/src/aa-symex/path_search.h +++ b/src/aa-symex/path_search.h @@ -22,25 +22,39 @@ class path_searcht:public safety_checkert explicit inline path_searcht(const namespacet &_ns): safety_checkert(_ns), show_vcc(false), - depth_limit(-1), // no limit - context_bound(-1), - unwind_limit(-1) + depth_limit_set(false), // no limit + context_bound_set(false), + unwind_limit_set(false) { } virtual resultt operator()( const goto_functionst &goto_functions); - bool show_vcc; + void set_depth_limit(unsigned limit) + { + depth_limit_set=true; + depth_limit=limit; + } - unsigned depth_limit; - unsigned context_bound; - unsigned unwind_limit; + void set_context_bound(unsigned limit) + { + context_bound_set=true; + context_bound=limit; + } + + void set_unwind_limit(unsigned limit) + { + unwind_limit_set=true; + unwind_limit=limit; + } + + bool show_vcc; // statistics - unsigned number_of_paths; unsigned number_of_instructions; unsigned number_of_dropped_states; + unsigned number_of_paths; unsigned number_of_VCCs; unsigned number_of_VCCs_after_simplification; unsigned number_of_failed_properties; @@ -48,13 +62,18 @@ class path_searcht:public safety_checkert absolute_timet start_time; time_periodt sat_time; - enum statust { NOT_REACHED, PASS, FAIL }; + enum statust { NOT_REACHED, SUCCESS, FAILURE }; struct property_entryt { statust status; irep_idt description; goto_tracet error_trace; + source_locationt source_location; + + inline bool is_success() const { return status==SUCCESS; } + inline bool is_failure() const { return status==FAILURE; } + inline bool is_not_reached() const { return status==NOT_REACHED; } }; typedef std::map property_mapt; @@ -73,15 +92,17 @@ class path_searcht:public safety_checkert typedef path_symex_statet statet; // State queue. Iterators are stable. + // The states most recently executed are at the head. typedef std::list queuet; queuet queue; + // search heuristic queuet::iterator pick_state(); bool execute(queuet::iterator state, const namespacet &); - void check_assertion(statet &state, const namespacet &); - void do_show_vcc(statet &state, const namespacet &); + void check_assertion(statet &state); + void do_show_vcc(statet &state); bool drop_state(const statet &state) const; @@ -89,6 +110,11 @@ class path_searcht:public safety_checkert void initialize_property_map( const goto_functionst &goto_functions); + + unsigned depth_limit; + unsigned context_bound; + unsigned unwind_limit; + bool depth_limit_set, context_bound_set, unwind_limit_set; }; #endif // CPROVER_AA_SYMEX_PATH_SEARCH_H diff --git a/src/aa-symex/symex_main.cpp b/src/aa-symex/symex_main.cpp deleted file mode 100644 index eed970eb5cc..00000000000 --- a/src/aa-symex/symex_main.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/*******************************************************************\ - -Module: Symex Main Module - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#include - -#include "symex_parseoptions.h" - -/*******************************************************************\ - -Function: main - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -#ifdef _MSC_VER -int wmain(int argc, const wchar_t **argv_wide) -{ - const char **argv=narrow_argv(argc, argv_wide); - symex_parseoptionst parseoptions(argc, argv); - return parseoptions.main(); -} -#else -int main(int argc, const char **argv) -{ - symex_parseoptionst parseoptions(argc, argv); - return parseoptions.main(); -} -#endif diff --git a/src/aa-symex/symex_parseoptions.cpp b/src/aa-symex/symex_parseoptions.cpp deleted file mode 100644 index 8eaf3de42f1..00000000000 --- a/src/aa-symex/symex_parseoptions.cpp +++ /dev/null @@ -1,784 +0,0 @@ -/*******************************************************************\ - -Module: Symex Command Line Options Processing - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include "path_search.h" -#include "symex_parseoptions.h" - -/*******************************************************************\ - -Function: symex_parseoptionst::symex_parseoptionst - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -symex_parseoptionst::symex_parseoptionst(int argc, const char **argv): - parseoptions_baset(SYMEX_OPTIONS, argc, argv), - language_uit("Symex " CBMC_VERSION, cmdline) -{ -} - -/*******************************************************************\ - -Function: symex_parseoptionst::eval_verbosity - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void symex_parseoptionst::eval_verbosity() -{ - // this is our default verbosity - int v=messaget::M_STATISTICS; - - if(cmdline.isset("verbosity")) - { - v=unsafe_string2int(cmdline.getval("verbosity")); - if(v<0) - v=0; - else if(v>10) - v=10; - } - - set_verbosity(v); -} - -/*******************************************************************\ - -Function: symex_parseoptionst::get_command_line_options - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void symex_parseoptionst::get_command_line_options(optionst &options) -{ - if(config.set(cmdline)) - { - usage_error(); - std::exit(1); - } - - if(cmdline.isset("debug-level")) - options.set_option("debug-level", cmdline.getval("debug-level")); - - if(cmdline.isset("unwindset")) - options.set_option("unwindset", cmdline.getval("unwindset")); - - // all checks supported by goto_check - GOTO_CHECK_PARSE_OPTIONS(cmdline, options); - - // check assertions - if(cmdline.isset("no-assertions")) - options.set_option("assertions", false); - else - options.set_option("assertions", true); - - // use assumptions - if(cmdline.isset("no-assumptions")) - options.set_option("assumptions", false); - else - options.set_option("assumptions", true); - - // magic error label - if(cmdline.isset("error-label")) - options.set_option("error-label", cmdline.getval("error-label")); -} - -/*******************************************************************\ - -Function: symex_parseoptionst::doit - - Inputs: - - Outputs: - - Purpose: invoke main modules - -\*******************************************************************/ - -int symex_parseoptionst::doit() -{ - if(cmdline.isset("version")) - { - std::cout << CBMC_VERSION << std::endl; - return 0; - } - - register_language(new_ansi_c_language); - register_language(new_cpp_language); - - // - // command line options - // - - optionst options; - get_command_line_options(options); - - eval_verbosity(); - - goto_functionst goto_functions; - - if(get_goto_program(options, goto_functions)) - return 6; - - label_properties(goto_functions); - - if(cmdline.isset("show-properties")) - { - const namespacet ns(symbol_table); - show_properties(ns, get_ui(), goto_functions); - return 0; - } - - if(set_properties(goto_functions)) - return 7; - - if(cmdline.isset("show-locs")) - { - const namespacet ns(symbol_table); - locst locs(ns); - locs.build(goto_functions); - locs.output(std::cout); - return 0; - } - - // do actual Symex - - try - { - const namespacet ns(symbol_table); - path_searcht path_search(ns); - - path_search.set_message_handler(get_message_handler()); - path_search.set_verbosity(get_verbosity()); - - if(cmdline.isset("depth")) - path_search.depth_limit=unsafe_string2unsigned(cmdline.getval("depth")); - - if(cmdline.isset("context-bound")) - path_search.context_bound=unsafe_string2unsigned(cmdline.getval("context-bound")); - - if(cmdline.isset("unwind")) - path_search.unwind_limit=unsafe_string2unsigned(cmdline.getval("unwind")); - - if(cmdline.isset("show-vcc")) - { - path_search.show_vcc=true; - path_search(goto_functions); - return 0; - } - - // do actual symex - switch(path_search(goto_functions)) - { - case safety_checkert::SAFE: - report_properties(path_search.property_map); - report_success(); - return 0; - - case safety_checkert::UNSAFE: - report_properties(path_search.property_map); - report_failure(); - return 10; - - default: - return 8; - } - } - - catch(const std::string error_msg) - { - error() << error_msg << messaget::eom; - return 8; - } - - catch(const char *error_msg) - { - error() << error_msg << messaget::eom; - return 8; - } - - #if 0 - // let's log some more statistics - debug() << "Memory consumption:" << messaget::endl; - memory_info(debug()); - debug() << eom; - #endif -} - -/*******************************************************************\ - -Function: symex_parseoptionst::set_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -bool symex_parseoptionst::set_properties(goto_functionst &goto_functions) -{ - try - { - if(cmdline.isset("property")) - ::set_properties(goto_functions, cmdline.get_values("property")); - } - - catch(const char *e) - { - error(e); - return true; - } - - catch(const std::string e) - { - error(e); - return true; - } - - catch(int) - { - return true; - } - - return false; -} - -/*******************************************************************\ - -Function: symex_parseoptionst::get_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -bool symex_parseoptionst::get_goto_program( - const optionst &options, - goto_functionst &goto_functions) -{ - if(cmdline.args.empty()) - { - error() << "Please provide a program to verify" << eom; - return true; - } - - try - { - if(cmdline.args.size()==1 && - is_goto_binary(cmdline.args[0])) - { - status() << "Reading GOTO program from file" << eom; - - if(read_goto_binary(cmdline.args[0], - symbol_table, goto_functions, get_message_handler())) - return true; - - config.ansi_c.set_from_symbol_table(symbol_table); - - if(cmdline.isset("show-symbol-table")) - { - show_symbol_table(); - return true; - } - - irep_idt entry_point=goto_functions.entry_point(); - - if(symbol_table.symbols.find(entry_point)==symbol_table.symbols.end()) - { - error() << "The goto binary has no entry point; please complete linking" << eom; - return true; - } - } - else if(cmdline.isset("show-parse-tree")) - { - if(cmdline.args.size()!=1) - { - error() << "Please give one source file only" << eom; - return true; - } - - std::string filename=cmdline.args[0]; - - #ifdef _MSC_VER - std::ifstream infile(widen(filename).c_str()); - #else - std::ifstream infile(filename.c_str()); - #endif - - if(!infile) - { - error() << "failed to open input file `" << filename << "'" << eom; - return true; - } - - languaget *language=get_language_from_filename(filename); - - if(language==NULL) - { - error() << "failed to figure out type of file `" << filename << "'" << eom; - return true; - } - - status("Parsing", filename); - - if(language->parse(infile, filename, get_message_handler())) - { - error() << "PARSING ERROR" << eom; - return true; - } - - language->show_parse(std::cout); - return true; - } - else - { - - if(parse()) return true; - if(typecheck()) return true; - if(final()) return true; - - // we no longer need any parse trees or language files - clear_parse(); - - if(cmdline.isset("show-symbol-table")) - { - show_symbol_table(); - return true; - } - - irep_idt entry_point=goto_functions.entry_point(); - - if(symbol_table.symbols.find(entry_point)==symbol_table.symbols.end()) - { - error() << "No entry point; please provide a main function" << eom; - return true; - } - - status() << "Generating GOTO Program" << eom; - - goto_convert(symbol_table, goto_functions, ui_message_handler); - } - - // finally add the library - status() << "Adding CPROVER library" << eom; - link_to_library(symbol_table, goto_functions, ui_message_handler); - - if(process_goto_program(options, goto_functions)) - return true; - } - - catch(const char *e) - { - error(e); - return true; - } - - catch(const std::string e) - { - error(e); - return true; - } - - catch(int) - { - return true; - } - - catch(std::bad_alloc) - { - error() << "Out of memory" << eom; - return true; - } - - return false; -} - -/*******************************************************************\ - -Function: symex_parseoptionst::process_goto_program - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -bool symex_parseoptionst::process_goto_program( - const optionst &options, - goto_functionst &goto_functions) -{ - try - { - namespacet ns(symbol_table); - - // do partial inlining - status() << "Partial Inlining" << eom; - goto_partial_inline(goto_functions, ns, ui_message_handler); - - // add generic checks - status() << "Generic Property Instrumentation" << eom; - goto_check(ns, options, goto_functions); - - // recalculate numbers, etc. - goto_functions.update(); - - // add loop ids - goto_functions.compute_loop_numbers(); - - // if we aim to cover, replace - // all assertions by false to prevent simplification - - if(cmdline.isset("cover-assertions")) - make_assertions_false(goto_functions); - - // show it? - if(cmdline.isset("show-loops")) - { - show_loop_ids(get_ui(), goto_functions); - return true; - } - - // show it? - if(cmdline.isset("show-goto-functions")) - { - goto_functions.output(ns, std::cout); - return true; - } - } - - catch(const char *e) - { - error(e); - return true; - } - - catch(const std::string e) - { - error(e); - return true; - } - - catch(int) - { - return true; - } - - catch(std::bad_alloc) - { - error() << "Out of memory" << eom; - return true; - } - - return false; -} - -/*******************************************************************\ - -Function: symex_parseoptionst::report_properties - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void symex_parseoptionst::report_properties( - const path_searcht::property_mapt &property_map) -{ - for(const auto &prop_pair : property_map) - { - if(get_ui()==ui_message_handlert::XML_UI) - { - xmlt xml_result("result"); - xml_result.set_attribute("claim", id2string(prop_pair.first)); - - std::string status_string; - - switch(it->second.status) - { - case path_searcht::PASS: status_string="OK"; break; - case path_searcht::FAIL: status_string="FAILURE"; break; - case path_searcht::NOT_REACHED: status_string="OK"; break; - } - - xml_result.set_attribute("status", status_string); - - std::cout << xml_result << "\n"; - } - else - { - status() << "[" << prop_pair.first << "] " - << prop_pair.second.description << ": "; - switch(prop_pair.second.status) - { - case path_searcht::PASS: status() << "OK"; break; - case path_searcht::FAIL: status() << "FAILED"; break; - case path_searcht::NOT_REACHED: status() << "OK"; break; - } - status() << eom; - } - - if(cmdline.isset("show-trace") && - prop_pair.second.status==path_searcht::FAIL) - show_counterexample(prop_pair.second.error_trace); - } - - if(!cmdline.isset("property")) - { - status() << eom; - - unsigned failed=0; - - for(const auto &prop_pair : property_map) - if(prop_pair.second.status==path_searcht::FAIL) - failed++; - - status() << "** " << failed - << " of " << property_map.size() << " failed" - << eom; - } -} - -/*******************************************************************\ - -Function: symex_parseoptionst::report_success - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void symex_parseoptionst::report_success() -{ - result() << "VERIFICATION SUCCESSFUL" << eom; - - switch(get_ui()) - { - case ui_message_handlert::PLAIN: - break; - - case ui_message_handlert::XML_UI: - { - xmlt xml("cprover-status"); - xml.data="SUCCESS"; - std::cout << xml; - std::cout << std::endl; - } - break; - - default: - assert(false); - } -} - -/*******************************************************************\ - -Function: symex_parseoptionst::show_counterexample - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void symex_parseoptionst::show_counterexample( - const goto_tracet &error_trace) -{ - const namespacet ns(symbol_table); - - switch(get_ui()) - { - case ui_message_handlert::PLAIN: - std::cout << std::endl << "Counterexample:" << std::endl; - show_goto_trace(std::cout, ns, error_trace); - break; - - case ui_message_handlert::XML_UI: - { - xmlt xml; - convert(ns, error_trace, xml); - std::cout << xml << std::endl; - } - break; - - default: - assert(false); - } -} - -/*******************************************************************\ - -Function: symex_parseoptionst::report_failure - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -void symex_parseoptionst::report_failure() -{ - result() << "VERIFICATION FAILED" << eom; - - switch(get_ui()) - { - case ui_message_handlert::PLAIN: - break; - - case ui_message_handlert::XML_UI: - { - xmlt xml("cprover-status"); - xml.data="FAILURE"; - std::cout << xml; - std::cout << std::endl; - } - break; - - default: - assert(false); - } -} - -/*******************************************************************\ - -Function: symex_parseoptionst::help - - Inputs: - - Outputs: - - Purpose: display command line help - -\*******************************************************************/ - -void symex_parseoptionst::help() -{ - std::cout << - "\n" - "* * Symex " CBMC_VERSION " - Copyright (C) 2013 "; - - std::cout << "(" << (sizeof(void *)*8) << "-bit version)"; - - std::cout << " * *\n"; - - std::cout << - "* * Daniel Kroening * *\n" - "* * University of Oxford * *\n" - "* * kroening@kroening.com * *\n" - "\n" - "Usage: Purpose:\n" - "\n" - " symex [-?] [-h] [--help] show help\n" - " symex file.c ... source file names\n" - "\n" - "Frontend options:\n" - " -I path set include path (C/C++)\n" - " -D macro define preprocessor macro (C/C++)\n" - " --preprocess stop after preprocessing\n" - " --16, --32, --64 set width of int\n" - " --LP64, --ILP64, --LLP64,\n" - " --ILP32, --LP32 set width of int, long and pointers\n" - " --little-endian allow little-endian word-byte conversions\n" - " --big-endian allow big-endian word-byte conversions\n" - " --unsigned-char make \"char\" unsigned by default\n" - " --show-parse-tree show parse tree\n" - " --show-symbol-table show symbol table\n" - " --show-goto-functions show goto program\n" - " --ppc-macos set MACOS/PPC architecture\n" - " --mm model set memory model (default: sc)\n" - " --arch set architecture (default: " - << configt::this_architecture() << ")\n" - " --os set operating system (default: " - << configt::this_operating_system() << ")\n" - #ifdef _WIN32 - " --gcc use GCC as preprocessor\n" - #endif - " --no-arch don't set up an architecture\n" - " --no-library disable built-in abstract C library\n" - " --round-to-nearest IEEE floating point rounding mode (default)\n" - " --round-to-plus-inf IEEE floating point rounding mode\n" - " --round-to-minus-inf IEEE floating point rounding mode\n" - " --round-to-zero IEEE floating point rounding mode\n" - "\n" - "Program instrumentation options:\n" - GOTO_CHECK_HELP - " --show-properties show the properties\n" - " --no-assertions ignore user assertions\n" - " --no-assumptions ignore user assumptions\n" - " --error-label label check that label is unreachable\n" - "\n" - "Symex options:\n" - " --function name set main function name\n" - " --property nr only check one specific property\n" - " --depth nr limit search depth\n" - " --context-bound nr limit number of context switches\n" - " --unwind nr unwind nr times\n" - "\n" - "Other options:\n" - " --version show version and exit\n" - " --xml-ui use XML-formatted output\n" - "\n"; -} diff --git a/src/aa-symex/symex_parseoptions.h b/src/aa-symex/symex_parseoptions.h deleted file mode 100644 index 2b07b5880fd..00000000000 --- a/src/aa-symex/symex_parseoptions.h +++ /dev/null @@ -1,78 +0,0 @@ -/*******************************************************************\ - -Module: Command Line Parsing - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#ifndef CPROVER_AA_SYMEX_SYMEX_PARSEOPTIONS_H -#define CPROVER_AA_SYMEX_SYMEX_PARSEOPTIONS_H - -#include -#include - -#include - -#include - -#include "path_search.h" - -class goto_functionst; -class optionst; - -#define SYMEX_OPTIONS \ - "(function):" \ - "D:I:" \ - "(depth):(context-bound):(unwind):" \ - GOTO_CHECK_OPTIONS \ - "(no-assertions)(no-assumptions)" \ - "(16)(32)(64)(LP64)(ILP64)(LLP64)(ILP32)(LP32)" \ - "(little-endian)(big-endian)" \ - "(error-label):(verbosity):(no-library)" \ - "(version)" \ - "(i386-linux)(i386-macos)(i386-win32)(win32)(winx64)(gcc)" \ - "(ppc-macos)(unsigned-char)" \ - "(string-abstraction)(no-arch)(arch):(floatbv)(fixedbv)" \ - "(round-to-nearest)(round-to-plus-inf)(round-to-minus-inf)(round-to-zero)" \ - "(show-locs)(show-vcc)(show-properties)(show-trace)" \ - "(property):" \ - "(no-simplify)(no-unwinding-assertions)(no-propagation)" - // the last line is for CBMC-regression testing only - -class symex_parseoptionst: - public parseoptions_baset, - public language_uit -{ -public: - virtual int doit(); - virtual void help(); - - symex_parseoptionst(int argc, const char **argv); - symex_parseoptionst( - int argc, - const char **argv, - const std::string &extra_options); - -protected: - void get_command_line_options(optionst &options); - - bool get_goto_program( - const optionst &options, - goto_functionst &goto_functions); - - bool process_goto_program( - const optionst &options, - goto_functionst &goto_functions); - - bool set_properties(goto_functionst &goto_functions); - - void report_success(); - void report_failure(); - void report_properties(const path_searcht::property_mapt &); - void show_counterexample(const class goto_tracet &); - - void eval_verbosity(); -}; - -#endif // CPROVER_AA_SYMEX_SYMEX_PARSEOPTIONS_H diff --git a/src/path-symex/path_symex.cpp b/src/path-symex/path_symex.cpp index 31cc677eb16..a646e45409c 100644 --- a/src/path-symex/path_symex.cpp +++ b/src/path-symex/path_symex.cpp @@ -499,7 +499,9 @@ void path_symext::assign_rec( // array or a union. exprt member_name(ID_member_name); - member_name.set(ID_component_name, ssa_lhs_member_expr.get_component_name()); + member_name.set( + ID_component_name, + ssa_lhs_member_expr.get_component_name()); with_exprt new_rhs(struct_op, member_name, ssa_rhs); @@ -510,7 +512,8 @@ void path_symext::assign_rec( // rewrite into byte_extract, and do again exprt offset=gen_zero(index_type()); - byte_extract_exprt new_lhs(byte_update_id(), struct_op, offset, ssa_rhs.type()); + byte_extract_exprt + new_lhs(byte_update_id(), struct_op, offset, ssa_rhs.type()); assign_rec(state, guard, new_lhs, ssa_rhs); } From f3969d05ed6eec48ab3435276c52056c4903f93f Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Wed, 18 Jan 2017 00:55:53 -0500 Subject: [PATCH 050/166] Support building aa-symex, clobber, memory-model --- src/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 8d617957170..7b9e3a1d446 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,8 @@ DIRS = ansi-c big-int cbmc cpp goto-cc goto-instrument goto-programs \ goto-symex langapi pointer-analysis solvers util linking xmllang \ assembler analyses java_bytecode aa-path-symex path-symex musketeer \ - json cegis goto-analyzer jsil symex goto-diff + json cegis goto-analyzer jsil symex goto-diff aa-symex clobber \ + memory-models all: cbmc.dir goto-cc.dir goto-instrument.dir symex.dir goto-analyzer.dir goto-diff.dir @@ -43,6 +44,8 @@ symex.dir: languages goto-programs.dir pointer-analysis.dir \ goto-symex.dir linking.dir analyses.dir solvers.dir \ path-symex.dir goto-instrument.dir +aa-symex.dir: symex.dir aa-path-symex.dir + # building for a particular directory $(patsubst %, %.dir, $(DIRS)): From 3f244b361350ed071cd67cea62cc8a4da26151ed Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 17 Jan 2017 18:43:27 -0500 Subject: [PATCH 051/166] Revert "also don't build memory-models.dir and clobber.dir" This reverts commit d1095b19757d9e5abee2d70afa92ffbca09b84db. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f4d5af54c8f..dc03e9a27c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,4 +41,4 @@ matrix: script: - make -C src minisat2-download - make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 && make -C regression test - - make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 cegis.dir musketeer.dir + - make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 cegis.dir clobber.dir memory-models.dir musketeer.dir From 2e98e1017600e92959a2a9c2bc9237f040bd102b Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Tue, 17 Jan 2017 18:43:40 -0500 Subject: [PATCH 052/166] Revert "do not build aa-symex.dir" This reverts commit 898029925b6370b5a529c5c0ab20bdfb075ba743. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dc03e9a27c5..d454d25f806 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,4 +41,4 @@ matrix: script: - make -C src minisat2-download - make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 && make -C regression test - - make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 cegis.dir clobber.dir memory-models.dir musketeer.dir + - make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 aa-symex.dir cegis.dir clobber.dir memory-models.dir musketeer.dir From dcc4260b1d0f756a023e403e3b5e511c835244da Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 30 Sep 2016 12:58:44 +0100 Subject: [PATCH 053/166] Fix address space limit test. Fixes #243 --- src/solvers/flattening/bv_pointers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solvers/flattening/bv_pointers.cpp b/src/solvers/flattening/bv_pointers.cpp index b4d0382f27a..e23dccace5e 100644 --- a/src/solvers/flattening/bv_pointers.cpp +++ b/src/solvers/flattening/bv_pointers.cpp @@ -795,7 +795,7 @@ void bv_pointerst::add_addr(const exprt &expr, bvt &bv) { std::size_t a=pointer_logic.add_object(expr); - if(a==(std::size_t(1)>>object_bits)) + if(a==(std::size_t(1)< Date: Wed, 25 Jan 2017 11:48:53 +0000 Subject: [PATCH 054/166] Add address space size limit regression test --- regression/cbmc/address_space_size_limit1/test.c | 16 ++++++++++++++++ .../cbmc/address_space_size_limit1/test.desc | 5 +++++ 2 files changed, 21 insertions(+) create mode 100644 regression/cbmc/address_space_size_limit1/test.c create mode 100644 regression/cbmc/address_space_size_limit1/test.desc diff --git a/regression/cbmc/address_space_size_limit1/test.c b/regression/cbmc/address_space_size_limit1/test.c new file mode 100644 index 00000000000..a4f9e047262 --- /dev/null +++ b/regression/cbmc/address_space_size_limit1/test.c @@ -0,0 +1,16 @@ + +#include +#include + +int main(int argc, char** argv) +{ + + int i; + char* c; + for(i=0; i<300; ++i) + { + c=(char*)malloc(1); + assert(c!=(char*)0); + } + +} diff --git a/regression/cbmc/address_space_size_limit1/test.desc b/regression/cbmc/address_space_size_limit1/test.desc new file mode 100644 index 00000000000..9dcfb8970aa --- /dev/null +++ b/regression/cbmc/address_space_size_limit1/test.desc @@ -0,0 +1,5 @@ +CORE +test.c +--no-simplify --unwind 300 +too many variables +-- From de84fe11a87fda20520989ef809ab42d79abe181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Thu, 3 Nov 2016 17:41:18 +0100 Subject: [PATCH 055/166] restructure expr2java Extract expr2java to a file. --- src/java_bytecode/expr2java.cpp | 74 ++++++++++++++++----------------- src/java_bytecode/expr2java.h | 36 ++++++++++++++++ 2 files changed, 72 insertions(+), 38 deletions(-) diff --git a/src/java_bytecode/expr2java.cpp b/src/java_bytecode/expr2java.cpp index 8cf4cdd1c59..7574c1e4ce9 100644 --- a/src/java_bytecode/expr2java.cpp +++ b/src/java_bytecode/expr2java.cpp @@ -20,40 +20,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include "java_types.h" #include "expr2java.h" -class expr2javat:public expr2ct -{ -public: - expr2javat(const namespacet &_ns):expr2ct(_ns) { } - - std::string convert(const exprt &src) override - { - return expr2ct::convert(src); - } - - std::string convert(const typet &src) override - { - return expr2ct::convert(src); - } - -protected: - std::string convert(const exprt &src, unsigned &precedence) override; - std::string convert_java_this(const exprt &src, unsigned precedence); - std::string convert_java_instanceof(const exprt &src, unsigned precedence); - std::string convert_java_new(const exprt &src, unsigned precedence); - std::string convert_code_java_delete(const exprt &src, unsigned precedence); - std::string convert_struct(const exprt &src, unsigned &precedence) override; - std::string convert_code(const codet &src, unsigned indent) override; - std::string convert_constant(const constant_exprt &src, unsigned &precedence) override; - std::string convert_code_function_call(const code_function_callt &src, unsigned indent); - - std::string convert_rec( - const typet &src, - const c_qualifierst &qualifiers, - const std::string &declarator) override; - - typedef std::unordered_set id_sett; -}; - /*******************************************************************\ Function: expr2javat::convert_code_function_call @@ -244,12 +210,12 @@ std::string expr2javat::convert_constant( else if(src.type()==java_char_type()) { std::string dest; - dest.reserve(10); + dest.reserve(char_representation_length); mp_integer int_value; to_integer(src, int_value); - dest+='\''; + dest+="(char)'"; if(int_value>=' ' && int_value<127) dest+=(char)(int_value.to_long()); @@ -265,6 +231,24 @@ std::string expr2javat::convert_constant( dest+='\''; return dest; } + else if(src.type()==java_byte_type()) + { + // No byte-literals in Java, so just cast: + mp_integer int_value; + to_integer(src, int_value); + std::string dest="(byte)"; + dest+=integer2string(int_value); + return dest; + } + else if(src.type()==java_short_type()) + { + // No short-literals in Java, so just cast: + mp_integer int_value; + to_integer(src, int_value); + std::string dest="(short)"; + dest+=integer2string(int_value); + return dest; + } else if(src.type()==java_long_type()) { // long integer literals must have 'L' at the end @@ -319,7 +303,7 @@ std::string expr2javat::convert_rec( else if(src==java_double_type()) return q+"double"+d; else if(src==java_boolean_type()) - return q+"bool"+d; + return q+"boolean"+d; else if(src==java_byte_type()) return q+"byte"+d; else if(src.id()==ID_code) @@ -491,6 +475,7 @@ std::string expr2javat::convert( const exprt &src, unsigned &precedence) { + const typet &type=ns.follow(src.type()); if(src.id()=="java-this") return convert_java_this(src, precedence=15); if(src.id()=="java_instanceof") @@ -509,9 +494,22 @@ std::string expr2javat::convert( else if(src.id()=="pod_constructor") return "pod_constructor"; else if(src.id()==ID_virtual_function) - return convert_function(src, "VIRTUAL_FUNCTION", precedence=16); + { + return "VIRTUAL_FUNCTION(" + + id2string(src.get(ID_C_class)) + + "." + + id2string(src.get(ID_component_name)) + + ")"; + } else if(src.id()==ID_java_string_literal) return '"'+id2string(src.get(ID_value))+'"'; // Todo: add escaping as needed + else if(src.id()==ID_constant && (type.id()==ID_bool || type.id()==ID_c_bool)) + { + if(src.is_true()) + return "true"; + else + return "false"; + } else return expr2ct::convert(src, precedence); } diff --git a/src/java_bytecode/expr2java.h b/src/java_bytecode/expr2java.h index f69563a3697..f4d03084348 100644 --- a/src/java_bytecode/expr2java.h +++ b/src/java_bytecode/expr2java.h @@ -10,11 +10,47 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #define CPROVER_JAVA_BYTECODE_EXPR2JAVA_H #include +#include class exprt; class namespacet; class typet; +class expr2javat:public expr2ct +{ +public: + expr2javat(const namespacet &_ns):expr2ct(_ns) { } + + virtual std::string convert(const exprt &src) + { + return expr2ct::convert(src); + } + + virtual std::string convert(const typet &src) + { + return expr2ct::convert(src); + } + +protected: + virtual std::string convert(const exprt &src, unsigned &precedence); + virtual std::string convert_java_this(const exprt &src, unsigned precedence); + virtual std::string convert_java_instanceof(const exprt &src, unsigned precedence); + virtual std::string convert_java_new(const exprt &src, unsigned precedence); + virtual std::string convert_code_java_delete(const exprt &src, unsigned precedence); + virtual std::string convert_struct(const exprt &src, unsigned &precedence); + virtual std::string convert_code(const codet &src, unsigned indent); + virtual std::string convert_constant(const constant_exprt &src, unsigned &precedence); + virtual std::string convert_code_function_call(const code_function_callt &src, unsigned indent); + + virtual std::string convert_rec( + const typet &src, + const c_qualifierst &qualifiers, + const std::string &declarator); + + // length of string representation of Java Char + const std::size_t char_representation_length=14; +}; + std::string expr2java(const exprt &expr, const namespacet &ns); std::string type2java(const typet &type, const namespacet &ns); From 7aef6aeb685f7d1280c87f4652c0a780893db40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 4 Nov 2016 11:12:47 +0100 Subject: [PATCH 056/166] pre-load java.lang.Object / String in class queue java.lang.Object and java.lang.String are added explicitely to the class loading queue to prevent problems with use without having a reference in the class. --- src/java_bytecode/java_class_loader.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/java_bytecode/java_class_loader.cpp b/src/java_bytecode/java_class_loader.cpp index 3d0f8338caf..0eca596149b 100644 --- a/src/java_bytecode/java_class_loader.cpp +++ b/src/java_bytecode/java_class_loader.cpp @@ -35,6 +35,11 @@ java_bytecode_parse_treet &java_class_loadert::operator()( { std::stack queue; + // Always require java.lang.Object, as it is the base of + // internal classes such as array types. + queue.push("java.lang.Object"); + // java.lang.String + queue.push("java.lang.String"); queue.push(class_name); while(!queue.empty()) From aa459379e55b447a0ff1555a221e1efaa40c3389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Thu, 3 Nov 2016 17:48:09 +0100 Subject: [PATCH 057/166] correct array type for Java Take into account difference between atomic types and refernce types in Java array handling. --- src/java_bytecode/java_types.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/java_bytecode/java_types.cpp b/src/java_bytecode/java_types.cpp index 2e1318df274..37682a99d49 100644 --- a/src/java_bytecode/java_types.cpp +++ b/src/java_bytecode/java_types.cpp @@ -7,6 +7,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ #include +#include #include #include @@ -384,9 +385,15 @@ typet java_type_from_string(const std::string &src) case '[': // array type { + // If this is a reference array, we generate a plain array[reference] + // with void* members, but note the real type in ID_C_element_type. if(src.size()<=1) return nil_typet(); + char subtype_letter=src[1]; const typet subtype=java_type_from_string(src.substr(1, std::string::npos)); - typet tmp=java_array_type('a'); + if(subtype_letter=='L' || // [L denotes a reference array of some sort. + subtype_letter=='[') // Array-of-arrays + subtype_letter='A'; + typet tmp=java_array_type((char)tolower(subtype_letter)); tmp.subtype().set(ID_C_element_type, subtype); return tmp; } From 8620cee3e342ab13b312614ed95bdd8ce1ae6ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Tue, 6 Dec 2016 13:25:25 +0100 Subject: [PATCH 058/166] nondeterministic initialization Treat nondeterministic initialization of objects. --- src/java_bytecode/java_object_factory.cpp | 377 +++++++++++++++++++--- src/java_bytecode/java_object_factory.h | 20 +- 2 files changed, 349 insertions(+), 48 deletions(-) diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 6eeba5e23eb..b27797b0416 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -7,14 +7,18 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ #include +#include #include #include #include #include +#include +#include #include #include "java_object_factory.h" +#include "java_types.h" /*******************************************************************\ @@ -28,20 +32,126 @@ Function: gen_nondet_init \*******************************************************************/ -namespace { -void gen_nondet_init( +class gen_nondet_state { + + code_blockt& init_code; + std::set recursion_set; + bool assume_non_null; + int max_nondet_array_length; + symbol_tablet& symbol_table; + namespacet ns; + +public: + + gen_nondet_state(code_blockt& ic, bool ann, int mnal, symbol_tablet& st) : + init_code(ic), + assume_non_null(ann), + max_nondet_array_length(mnal), + symbol_table(st), + ns(st) {} + + exprt allocate_object(const exprt&, const typet&, + const source_locationt &, + bool create_dynamic_objects); + + void gen_nondet_array_init(const exprt &expr, const source_locationt &); + + void gen_nondet_init(const exprt &expr, + bool is_sub, + irep_idt class_identifier, + const source_locationt &loc, + bool skip_classid, + bool create_dynamic_objects, + const typet *override_type = 0); + + +}; + +// Returns false if we can't figure out the size of allocate_type. +// allocate_type may differ from target_expr, e.g. for target_expr having +// type int* and allocate_type being an int[10]. +exprt gen_nondet_state::allocate_object( + const exprt& target_expr, + const typet& allocate_type, + const source_locationt &loc, + bool create_dynamic_objects) +{ + const typet& allocate_type_resolved=ns.follow(allocate_type); + const typet& target_type=ns.follow(target_expr.type().subtype()); + bool cast_needed=allocate_type_resolved!=target_type; + if(!create_dynamic_objects) + { + symbolt &aux_symbol=new_tmp_symbol(symbol_table); + aux_symbol.type=allocate_type; + aux_symbol.is_static_lifetime=true; + + exprt object=aux_symbol.symbol_expr(); + exprt aoe=address_of_exprt(object); + if(cast_needed) + aoe=typecast_exprt(aoe, target_expr.type()); + code_assignt code(target_expr,aoe); + code.add_source_location()=loc; + init_code.copy_to_operands(code); + return aoe; + } + else + { + // build size expression + exprt object_size=size_of_expr(allocate_type, namespacet(symbol_table)); + + if(allocate_type.id()!=ID_empty && !object_size.is_nil()) + { + // malloc expression + exprt malloc_expr = side_effect_exprt(ID_malloc); + malloc_expr.copy_to_operands(object_size); + typet result_type=pointer_typet(allocate_type); + malloc_expr.type()=result_type; + // Create a symbol for the malloc expression so we can initialise + // without having to do it potentially through a double-deref, which + // breaks the to-SSA phase. + symbolt &malloc_sym=new_tmp_symbol(symbol_table,"malloc_site"); + malloc_sym.type=pointer_typet(allocate_type); + code_assignt assign = code_assignt(malloc_sym.symbol_expr(), malloc_expr); + code_assignt &malloc_assign = assign; + malloc_assign.add_source_location() = loc; + init_code.copy_to_operands(malloc_assign); + malloc_expr=malloc_sym.symbol_expr(); + if(cast_needed) + malloc_expr=typecast_exprt(malloc_expr,target_expr.type()); + code_assignt code(target_expr, malloc_expr); + code.add_source_location() = loc; + init_code.copy_to_operands(code); + return malloc_sym.symbol_expr(); + } + else + { + // make null + null_pointer_exprt null_pointer_expr(to_pointer_type(target_expr.type())); + code_assignt code(target_expr, null_pointer_expr); + code.add_source_location() = loc; + init_code.copy_to_operands(code); + return exprt(); + } + } +} + +// Override type says to ignore the LHS' real type, and init it with the given +// type regardless. Used at the moment for reference arrays, which are implemented +// as void* arrays but should be init'd as their true type with appropriate casts. +void gen_nondet_state::gen_nondet_init( const exprt &expr, - code_blockt &init_code, - const namespacet &ns, - std::set &recursion_set, bool is_sub, - irep_idt class_identifier) + irep_idt class_identifier, + const source_locationt &loc, + bool skip_classid, + bool create_dynamic_objects, + const typet *override_type) { - const typet &type=ns.follow(expr.type()); + const typet &type= + override_type ? ns.follow(*override_type) : ns.follow(expr.type()); if(type.id()==ID_pointer) { - #if 0 // dereferenced type const pointer_typet &pointer_type=to_pointer_type(type); const typet &subtype=ns.follow(pointer_type.subtype()); @@ -56,38 +166,72 @@ void gen_nondet_init( // make null null_pointer_exprt null_pointer_expr(pointer_type); code_assignt code(expr, null_pointer_expr); + code.add_source_location() = loc; init_code.copy_to_operands(code); return; } } - // build size expression - exprt object_size=size_of_expr(subtype, ns); - - if(subtype.id()!=ID_empty && !object_size.is_nil()) - { - // malloc expression - side_effect_exprt malloc_expr(ID_malloc); - malloc_expr.copy_to_operands(object_size); - malloc_expr.type()=pointer_type; + code_labelt set_null_label; + code_labelt init_done_label; - code_assignt code(expr, malloc_expr); - init_code.copy_to_operands(code); + static unsigned long synthetic_constructor_count=0; - // dereference expression - dereference_exprt deref_expr(expr, subtype); + if(!assume_non_null) + { + auto returns_null_sym= + new_tmp_symbol(symbol_table,"opaque_returns_null"); + returns_null_sym.type=c_bool_typet(1); + auto returns_null=returns_null_sym.symbol_expr(); + auto assign_returns_null= + code_assignt(returns_null,get_nondet_bool(returns_null_sym.type)); + assign_returns_null.add_source_location() = loc; + init_code.move_to_operands(assign_returns_null); + + auto set_null_inst=code_assignt( + expr,null_pointer_exprt(pointer_type)); + set_null_inst.add_source_location() = loc; + + std::ostringstream fresh_label_oss; + fresh_label_oss<<"post_synthetic_malloc_" + <<(++synthetic_constructor_count); + std::string fresh_label=fresh_label_oss.str(); + set_null_label=code_labelt(fresh_label,set_null_inst); + + init_done_label=code_labelt(fresh_label + "_init_done",code_skipt()); + + code_ifthenelset null_check; + null_check.cond()=notequal_exprt( + returns_null,constant_exprt("0",returns_null_sym.type)); + null_check.then_case()=code_gotot(fresh_label); + init_code.move_to_operands(null_check); + } - gen_nondet_init(deref_expr, init_code, ns, recursion_set, false, ""); + if(subtype.id()==ID_struct && + has_prefix(id2string(to_struct_type(subtype).get_tag()), "java::array[")) + { + gen_nondet_array_init(expr, loc); } - else + else { + exprt allocated=allocate_object(expr,subtype,loc,create_dynamic_objects); + { + exprt init_expr; + if(allocated.id()==ID_address_of) + init_expr=allocated.op0(); + else + init_expr=dereference_exprt(allocated,allocated.type().subtype()); + gen_nondet_init(init_expr,false,"",loc,false,create_dynamic_objects); + } + } + + if(!assume_non_null) { - // make null - null_pointer_exprt null_pointer_expr(pointer_type); - code_assignt code(expr, null_pointer_expr); - init_code.copy_to_operands(code); + init_code.copy_to_operands(code_gotot(init_done_label.get_label())); + init_code.move_to_operands(set_null_label); + init_code.move_to_operands(init_done_label); } - #endif + } else if(type.id()==ID_struct) { @@ -98,6 +242,9 @@ void gen_nondet_init( const componentst &components=struct_type.components(); + if(!is_sub) + class_identifier=struct_tag; + recursion_set.insert(struct_tag); assert(!recursion_set.empty()); @@ -110,15 +257,20 @@ void gen_nondet_init( if(name=="@class_identifier") { + if(skip_classid) + continue; + irep_idt qualified_clsid="java::"+as_string(class_identifier); - constant_exprt ci(qualified_clsid, string_typet()); + constant_exprt ci(qualified_clsid,string_typet()); - code_assignt code(me, ci); - init_code.copy_to_operands(code); + code_assignt code(me, ci); + code.add_source_location() = loc; + init_code.copy_to_operands(code); } else if(name=="@lock") { code_assignt code(me, gen_zero(me.type())); + code.add_source_location() = loc; init_code.copy_to_operands(code); } else @@ -126,14 +278,14 @@ void gen_nondet_init( assert(!name.empty()); bool _is_sub = name[0]=='@'; +#if 0 irep_idt _class_identifier= _is_sub?(class_identifier.empty()?struct_tag:class_identifier):""; +#endif - gen_nondet_init( - me, init_code, ns, recursion_set, _is_sub, _class_identifier); + gen_nondet_init(me, _is_sub, class_identifier, loc, false, create_dynamic_objects); } } - recursion_set.erase(struct_tag); } else @@ -141,11 +293,119 @@ void gen_nondet_init( side_effect_expr_nondett se=side_effect_expr_nondett(type); code_assignt code(expr, se); + code.add_source_location() = loc; init_code.copy_to_operands(code); } } + +// Borrowed from java_bytecode_convert.cpp -- todo find a sensible place to factor this. +static constant_exprt as_number(const mp_integer value, const typet &type) +{ + const unsigned int java_int_width(type.get_unsigned_int(ID_width)); + const std::string significant_bits(integer2string(value, 2)); + std::string binary_width(java_int_width - significant_bits.length(), '0'); + return constant_exprt(binary_width += significant_bits, type); +} + +void gen_nondet_state::gen_nondet_array_init(const exprt &expr, const source_locationt &loc) +{ + assert(expr.type().id()==ID_pointer); + const typet &type=ns.follow(expr.type().subtype()); + const struct_typet &struct_type=to_struct_type(type); + assert(expr.type().subtype().id() == ID_symbol); + const typet &element_type=static_cast(expr.type().subtype().find(ID_C_element_type)); + + auto max_length_expr=as_number(max_nondet_array_length,java_int_type()); + + typet allocate_type; + symbolt &length_sym=new_tmp_symbol(symbol_table,"nondet_array_length"); + length_sym.type=java_int_type(); + const auto &length_sym_expr=length_sym.symbol_expr(); + + // Initialise array with some undetermined length: + gen_nondet_init(length_sym_expr,false,irep_idt(),loc,false,false); + + // Insert assumptions to bound its length: + binary_relation_exprt assume1(length_sym_expr,ID_ge, + as_number(0, java_int_type())); + binary_relation_exprt assume2(length_sym_expr,ID_le, + max_length_expr); + code_assumet assume_inst1(assume1); + code_assumet assume_inst2(assume2); + init_code.move_to_operands(assume_inst1); + init_code.move_to_operands(assume_inst2); + + side_effect_exprt java_new_array(ID_java_new_array,expr.type()); + java_new_array.copy_to_operands(length_sym_expr); + java_new_array.set("skip_initialise",true); + java_new_array.type().subtype().set(ID_C_element_type,element_type); + codet assign = code_assignt(expr,java_new_array); + assign.add_source_location()=loc; + init_code.copy_to_operands(assign); + + exprt init_array_expr=member_exprt(dereference_exprt(expr, expr.type().subtype()), + "data", struct_type.components()[2].type()); + if(init_array_expr.type()!=pointer_typet(element_type)) + init_array_expr=typecast_exprt(init_array_expr,pointer_typet(element_type)); + + // Interpose a new symbol, as the goto-symex stage can't handle array indexing via a cast. + symbolt &array_init_symbol=new_tmp_symbol(symbol_table,"array_data_init"); + array_init_symbol.type=init_array_expr.type(); + const auto &array_init_symexpr=array_init_symbol.symbol_expr(); + codet data_assign = code_assignt(array_init_symexpr,init_array_expr); + data_assign.add_source_location() = loc; + init_code.copy_to_operands(data_assign); + + // Emit init loop for(array_init_iter=0; array_init_iter!=array.length; ++array_init_iter) + // init(array[array_init_iter]); + symbolt &counter=new_tmp_symbol(symbol_table,"array_init_iter"); + counter.type=length_sym_expr.type(); + exprt counter_expr=counter.symbol_expr(); + + init_code.copy_to_operands( + code_assignt(counter_expr,as_number(0, java_int_type()))); + + std::string head_name=as_string(counter.base_name)+"_header"; + code_labelt init_head_label(head_name,code_skipt()); + code_gotot goto_head(head_name); + + init_code.move_to_operands(init_head_label); + + std::string done_name=as_string(counter.base_name)+"_done"; + code_labelt init_done_label(done_name,code_skipt()); + code_gotot goto_done(done_name); + + code_ifthenelset done_test; + done_test.cond()=equal_exprt(counter_expr,length_sym_expr); + done_test.then_case()=goto_done; + + init_code.move_to_operands(done_test); + + // Add a redundant if(counter == max_length) break that is easier for the unwinder to understand. + code_ifthenelset max_test; + max_test.cond()=equal_exprt(counter_expr,max_length_expr); + max_test.then_case()=goto_done; + + init_code.move_to_operands(max_test); + + exprt arraycellref=dereference_exprt( + plus_exprt(array_init_symexpr,counter_expr,array_init_symexpr.type()), + array_init_symexpr.type().subtype()); + + gen_nondet_init(arraycellref,false,irep_idt(),loc,false,true, + /*override_type=*/&element_type); + + code_assignt incr(counter_expr, + plus_exprt(counter_expr, + as_number(1, java_int_type()))); + + init_code.move_to_operands(incr); + init_code.move_to_operands(goto_head); + init_code.move_to_operands(init_done_label); + } + /*******************************************************************\ Function: gen_nondet_init @@ -158,15 +418,19 @@ Function: gen_nondet_init \*******************************************************************/ -namespace { void gen_nondet_init( const exprt &expr, code_blockt &init_code, - const namespacet &ns) + symbol_tablet &symbol_table, + const source_locationt &loc, + bool skip_classid, + bool create_dynamic_objects, + bool assume_non_null, + int max_nondet_array_length) { - std::set recursion_set; - gen_nondet_init(expr, init_code, ns, recursion_set, false, ""); -} + gen_nondet_state state(init_code,assume_non_null,max_nondet_array_length, + symbol_table); + state.gen_nondet_init(expr,false,"",loc,skip_classid,create_dynamic_objects); } /*******************************************************************\ @@ -181,8 +445,7 @@ Function: new_tmp_symbol \*******************************************************************/ -namespace { -symbolt &new_tmp_symbol(symbol_tablet &symbol_table) +symbolt &new_tmp_symbol(symbol_tablet &symbol_table, const std::string& prefix) { static int temporary_counter=0; @@ -198,6 +461,23 @@ symbolt &new_tmp_symbol(symbol_tablet &symbol_table) return *symbol_ptr; } + +/*******************************************************************\ + +Function: get_nondet_bool + + Inputs: Desired type (C_bool or plain bool) + + Outputs: nondet expr of that type + + Purpose: + +\*******************************************************************/ + +exprt get_nondet_bool(const typet& type) { + // We force this to 0 and 1 and won't consider + // other values. + return typecast_exprt(side_effect_expr_nondett(bool_typet()), type); } /*******************************************************************\ @@ -216,27 +496,30 @@ exprt object_factory( const typet &type, code_blockt &init_code, bool allow_null, - symbol_tablet &symbol_table) + symbol_tablet &symbol_table, + int max_nondet_array_length, + const source_locationt &loc) { if(type.id()==ID_pointer) { symbolt &aux_symbol=new_tmp_symbol(symbol_table); - aux_symbol.type=type.subtype(); + aux_symbol.type=type; aux_symbol.is_static_lifetime=true; exprt object=aux_symbol.symbol_expr(); const namespacet ns(symbol_table); - gen_nondet_init(object, init_code, ns); + gen_nondet_init(object, init_code, symbol_table, loc, + false, false, !allow_null, + max_nondet_array_length); - // todo: need to pass null, possibly - return address_of_exprt(object); + return object; } else if(type.id()==ID_c_bool) { // We force this to 0 and 1 and won't consider // other values. - return typecast_exprt(side_effect_expr_nondett(bool_typet()), type); + return get_nondet_bool(type); } else return side_effect_expr_nondett(type); diff --git a/src/java_bytecode/java_object_factory.h b/src/java_bytecode/java_object_factory.h index 5797cb20aed..b86c5d3791c 100644 --- a/src/java_bytecode/java_object_factory.h +++ b/src/java_bytecode/java_object_factory.h @@ -16,6 +16,24 @@ exprt object_factory( const typet &type, code_blockt &init_code, bool allow_null, - symbol_tablet &symbol_table); + symbol_tablet &symbol_table, + int max_nondet_array_length, + const source_locationt &); + +void gen_nondet_init( + const exprt &expr, + code_blockt &init_code, + symbol_tablet &symbol_table, + const source_locationt &, + bool skip_classid = false, + bool create_dynamic_objects = false, + bool assume_non_null = false, + int max_nondet_array_length = 5); + +exprt get_nondet_bool(const typet&); + +symbolt &new_tmp_symbol( + symbol_tablet &symbol_table, + const std::string& prefix = "tmp_object_factory"); #endif // CPROVER_JAVA_BYTECODE_JAVA_OBJECT_FACTORY_H From 843120498f85f262958cb517f40d97d630343b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 4 Nov 2016 10:01:36 +0100 Subject: [PATCH 059/166] exception table parser Parse the exception table attribute of Java methods. --- src/java_bytecode/java_bytecode_parse_tree.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index 87b55b27b4a..38a89f87c4a 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -84,6 +84,7 @@ class java_bytecode_parse_treet struct exceptiont { + public: std::size_t start_pc; std::size_t end_pc; std::size_t handler_pc; From c3fdd435dc692267c06e5ab0b7311588f66a5294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 4 Nov 2016 10:01:58 +0100 Subject: [PATCH 060/166] handle java.lang.String literals This patch integrates a first version of handling of Java String Literals. --- src/java_bytecode/java_bytecode_typecheck.h | 3 + .../java_bytecode_typecheck_expr.cpp | 93 ++++++++++++------- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/java_bytecode/java_bytecode_typecheck.h b/src/java_bytecode/java_bytecode_typecheck.h index 56d43c15f02..d1ab4c7848e 100644 --- a/src/java_bytecode/java_bytecode_typecheck.h +++ b/src/java_bytecode/java_bytecode_typecheck.h @@ -10,6 +10,7 @@ Author: Daniel Kroening, kroening@kroening.com #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_TYPECHECK_H #include +#include #include #include @@ -63,6 +64,8 @@ class java_bytecode_typecheckt:public typecheckt virtual std::string to_string(const typet &type); std::set already_typechecked; + std::map string_literal_to_symbol_name; + std::map escaped_string_literal_count; }; #endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_TYPECHECK_H diff --git a/src/java_bytecode/java_bytecode_typecheck_expr.cpp b/src/java_bytecode/java_bytecode_typecheck_expr.cpp index 48b5f8cc462..d513bf1ebc1 100644 --- a/src/java_bytecode/java_bytecode_typecheck_expr.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_expr.cpp @@ -10,6 +10,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "java_bytecode_typecheck.h" +#include "java_pointer_casts.h" /*******************************************************************\ @@ -28,6 +29,9 @@ void java_bytecode_typecheckt::typecheck_expr(exprt &expr) if(expr.id()==ID_code) return typecheck_code(to_code(expr)); + if(expr.id()==ID_typecast && expr.type().id()==ID_pointer) + expr=make_clean_pointer_cast(expr,expr.type(),ns); + // do operands recursively Forall_operands(it, expr) typecheck_expr(*it); @@ -86,6 +90,13 @@ void java_bytecode_typecheckt::typecheck_expr_java_new_array(side_effect_exprt & typecheck_type(type); } +static void escape_non_alnum(std::string& toescape) +{ + for(size_t idx=0, lim=toescape.size(); idx!=lim; ++idx) + if(!isalnum(toescape[idx])) + toescape[idx]='_'; +} + /*******************************************************************\ Function: java_bytecode_typecheckt::typecheck_expr_java_string_literal @@ -101,37 +112,45 @@ Function: java_bytecode_typecheckt::typecheck_expr_java_string_literal void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr) { const irep_idt value=expr.get(ID_value); - - // we create a symbol for these - const irep_idt identifier="java::java.lang.String.Literal."+ - id2string(value); - - symbol_tablet::symbolst::const_iterator s_it= - symbol_table.symbols.find(identifier); - const symbol_typet string_type("java::java.lang.String"); - if(s_it==symbol_table.symbols.end()) + auto findit=string_literal_to_symbol_name.find(value); + if(findit!=string_literal_to_symbol_name.end()) { - // no, create the symbol - symbolt new_symbol; - new_symbol.name=identifier; - new_symbol.type=string_type; - new_symbol.base_name="Literal"; - new_symbol.pretty_name=value; - new_symbol.mode=ID_java; - new_symbol.is_type=false; - new_symbol.is_lvalue=true; + expr=symbol_exprt(findit->second, pointer_typet(string_type)); + return; + } - if(symbol_table.add(new_symbol)) - { - error() << "failed to add string literal symbol to symbol table" << eom; - throw 0; - } + // Create a new symbol: + std::ostringstream identifier_str; + std::string escaped=id2string(value); + escape_non_alnum(escaped); + identifier_str << "java::java.lang.String.Literal." << escaped; + // Avoid naming clashes by virtue of escaping: + size_t unique_num=++(escaped_string_literal_count[identifier_str.str()]); + if(unique_num!=1) + identifier_str << unique_num; + + irep_idt identifier_id=identifier_str.str(); + string_literal_to_symbol_name.insert(std::make_pair(value,identifier_id)); + + symbolt new_symbol; + new_symbol.name=identifier_id; + new_symbol.type=pointer_typet(string_type); + new_symbol.base_name="Literal"; + new_symbol.pretty_name=value; + new_symbol.mode=ID_java; + new_symbol.is_type=false; + new_symbol.is_lvalue=true; + new_symbol.is_static_lifetime=true; // These are basically const global data. + + if(symbol_table.add(new_symbol)) + { + error() << "failed to add string literal symbol to symbol table" << eom; + throw 0; } - expr=address_of_exprt( - symbol_exprt(identifier, string_type)); + expr=new_symbol.symbol_expr(); } /*******************************************************************\ @@ -208,26 +227,38 @@ Function: java_bytecode_typecheckt::typecheck_expr_symbol void java_bytecode_typecheckt::typecheck_expr_member(member_exprt &expr) { - // The member might be in a parent class, which we resolve here. + // The member might be in a parent class or an opaque class, which we resolve here. const irep_idt component_name=expr.get_component_name(); while(1) { - if(ns.follow(expr.struct_op().type()).id()!=ID_struct) + + typet &base_type = const_cast(ns.follow(expr.struct_op().type())); + + if(base_type.id()!=ID_struct) break; // give up - const struct_typet &struct_type= - to_struct_type(ns.follow(expr.struct_op().type())); + struct_typet &struct_type= + to_struct_type(base_type); if(struct_type.has_component(component_name)) return; // done // look at parent - const struct_typet::componentst &components= + struct_typet::componentst &components= struct_type.components(); + if(struct_type.get_bool(ID_incomplete_class)) { + // Member doesn't exist. In this case struct_type should be an opaque + // stub, and we'll add the member to it. + components.push_back(struct_typet::componentt(component_name, expr.type())); + components.back().set_base_name(component_name); + components.back().set_pretty_name(component_name); + return; + } + if(components.empty()) - break; // give up + break; const struct_typet::componentt &c=components.front(); From 385521a84b64afa00e1e0abec428381c7cc074fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 4 Nov 2016 10:09:26 +0100 Subject: [PATCH 061/166] handle array length and runtime checks for Java This updates the language interface for Java by handling the maximal sizes for arrays in Java and the runtime checks for Java analysis. --- .../java_bytecode_convert_method.cpp | 73 +++++++++++++++++-- src/java_bytecode/java_bytecode_language.cpp | 40 +++++++++- src/java_bytecode/java_bytecode_language.h | 14 +++- 3 files changed, 114 insertions(+), 13 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 854d50ac9ba..9af1aef48dd 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -895,11 +895,23 @@ codet java_bytecode_convert_methodt::convert_instructions( } else if(statement=="checkcast") { - // checkcast throws an exception in case a cast of object - // on stack to given type fails. - // The stack isn't modified. - assert(op.size()==1 && results.size()==1); - results[0]=op[0]; + if(!disable_runtime_checks) + { + // checkcast throws an exception in case a cast of object + // on stack to given type fails. + // The stack isn't modified. + // TODO: convert assertions to exceptions. + assert(op.size()==1 && results.size()==1); + binary_predicate_exprt check(op[0], "java_instanceof", arg0); + c=code_assertt(check); + c.add_source_location().set_comment("Dynamic cast check"); + c.add_source_location().set_property_class("bad-dynamic-cast"); + results[0]=op[0]; + } + else + { + c=code_skipt(); + } } else if(statement=="invokedynamic") { @@ -938,8 +950,17 @@ codet java_bytecode_convert_methodt::convert_instructions( { if(parameters.empty() || !parameters[0].get_this()) { - const empty_typet empty; - pointer_typet object_ref_type(empty); + irep_idt classname = arg0.get(ID_C_class); + typet thistype = symbol_typet(classname); + // Note invokespecial is used for super-method calls as well as constructors. + if(statement=="invokespecial") + { + if(as_string(arg0.get(ID_identifier)).find("")!=std::string::npos) + code_type.set(ID_constructor, true); + else + code_type.set("java_super_method_call", true); + } + pointer_typet object_ref_type(thistype); code_typet::parametert this_p(object_ref_type); this_p.set_this(); this_p.set_base_name("this"); @@ -1055,7 +1076,18 @@ codet java_bytecode_convert_methodt::convert_instructions( typet element_type=data_ptr.type().subtype(); const dereference_exprt element(data_plus_offset, element_type); - c=code_assignt(element, op[2]); + code_blockt assert_and_put; + if(!disable_runtime_checks) + { + codet bounds_check=get_array_bounds_check(deref,op[1],i_it->source_location); + bounds_check.add_source_location()=i_it->source_location; + assert_and_put.move_to_operands(bounds_check); + } + code_assignt array_put(element, op[2]); + array_put.add_source_location()=i_it->source_location; + assert_and_put.move_to_operands(array_put); + c=std::move(assert_and_put); + c.add_source_location()=i_it->source_location; } else if(statement==patternt("?store")) { @@ -1088,6 +1120,12 @@ codet java_bytecode_convert_methodt::convert_instructions( typet element_type=data_ptr.type().subtype(); dereference_exprt element(data_plus_offset, element_type); + if(!disable_runtime_checks) + { + codet bounds_check=get_array_bounds_check(deref,op[1],i_it->source_location); + bounds_check.add_source_location()=i_it->source_location; + c=std::move(bounds_check); + } results[0]=java_bytecode_promotion(element); } else if(statement==patternt("?load")) @@ -1613,6 +1651,25 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!i_it->source_location.get_line().empty()) java_new_array.add_source_location()=i_it->source_location; + code_blockt checkandcreate; + if(!disable_runtime_checks) + { + // TODO make this throw NegativeArrayIndexException instead. + constant_exprt intzero=as_number(0,java_int_type()); + binary_relation_exprt gezero(op[0],ID_ge,intzero); + code_assertt check(gezero); + check.add_source_location().set_comment("Array size < 0"); + check.add_source_location().set_property_class("array-create-negative-size"); + checkandcreate.move_to_operands(check); + + if(max_array_length!=0) + { + constant_exprt size_limit=as_number(max_array_length,java_int_type()); + binary_relation_exprt le_max_size(op[0],ID_le,size_limit); + code_assumet assume_le_max_size(le_max_size); + checkandcreate.move_to_operands(assume_le_max_size); + } + } const exprt tmp=tmp_variable("newarray", ref_type); c=code_assignt(tmp, java_new_array); results[0]=tmp; diff --git a/src/java_bytecode/java_bytecode_language.cpp b/src/java_bytecode/java_bytecode_language.cpp index a015f928115..12851d186e4 100644 --- a/src/java_bytecode/java_bytecode_language.cpp +++ b/src/java_bytecode/java_bytecode_language.cpp @@ -9,6 +9,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include +#include #include "java_bytecode_language.h" #include "java_bytecode_convert_class.h" @@ -22,6 +24,28 @@ Author: Daniel Kroening, kroening@kroening.com /*******************************************************************\ +Function: java_bytecode_languaget::get_language_options + + Inputs: Command-line options + + Outputs: None + + Purpose: Consume options that are java bytecode specific. + +\*******************************************************************/ + +void java_bytecode_languaget::get_language_options(const cmdlinet& cmd) +{ + disable_runtime_checks=cmd.isset("disable-runtime-check"); + assume_inputs_non_null=cmd.isset("java-assume-inputs-non-null"); + if(cmd.isset("java-max-input-array-length")) + max_nondet_array_length=safe_string2int(cmd.get_value("java-max-input-array-length")); + if(cmd.isset("java-max-vla-length")) + max_user_array_length=safe_string2int(cmd.get_value("java-max-vla-length")); +} + +/*******************************************************************\ + Function: java_bytecode_languaget::extensions Inputs: @@ -169,7 +193,11 @@ bool java_bytecode_languaget::typecheck( debug() << "Converting class " << c_it->first << eom; if(java_bytecode_convert_class( - c_it->second, symbol_table, get_message_handler())) + c_it->second, + disable_runtime_checks, + symbol_table, + get_message_handler(), + max_user_array_length)) return true; } @@ -200,7 +228,15 @@ bool java_bytecode_languaget::final(symbol_tablet &symbol_table) */ java_internal_additions(symbol_table); - if(java_entry_point(symbol_table, main_class, get_message_handler())) + + std::tuple t = get_main_symbol(symbol_table, main_class, get_message_handler()); + if(std::get<2>(t)) + return std::get<1>(t); + + symbolt entry = std::get<0>(t); + + if(java_entry_point(symbol_table,main_class,get_message_handler(), + assume_inputs_non_null,max_nondet_array_length)) return true; return false; diff --git a/src/java_bytecode/java_bytecode_language.h b/src/java_bytecode/java_bytecode_language.h index a6b5dd6d56b..f94f2890ba9 100644 --- a/src/java_bytecode/java_bytecode_language.h +++ b/src/java_bytecode/java_bytecode_language.h @@ -10,13 +10,17 @@ Author: Daniel Kroening, kroening@kroening.com #define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_LANGUAGE_H #include +#include #include "java_class_loader.h" class java_bytecode_languaget:public languaget { public: - bool preprocess( + + virtual void get_language_options(const cmdlinet&); + + virtual bool preprocess( std::istream &instream, const std::string &path, std::ostream &outstream) override; @@ -34,8 +38,8 @@ class java_bytecode_languaget:public languaget void show_parse(std::ostream &out) override; - ~java_bytecode_languaget() override; - java_bytecode_languaget() { } + virtual ~java_bytecode_languaget(); + java_bytecode_languaget() : max_nondet_array_length(5), max_user_array_length(0) { } bool from_expr( const exprt &expr, @@ -65,6 +69,10 @@ class java_bytecode_languaget:public languaget protected: irep_idt main_class; java_class_loadert java_class_loader; + bool assume_inputs_non_null; + bool disable_runtime_checks; + int max_nondet_array_length; + int max_user_array_length; }; languaget *new_java_bytecode_language(); From 11be1934b04270530b5f17fe090b6f7d4d995110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 4 Nov 2016 10:37:31 +0100 Subject: [PATCH 062/166] Java assertion handling Handle Java internal assertions which is triggered by the global `assertionsDisabled` Boolean variable. --- .../java_bytecode_convert_method.cpp | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 9af1aef48dd..4cbea1f5bca 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -887,11 +887,21 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement=="athrow") { assert(op.size()==1 && results.size()==1); - side_effect_expr_throwt throw_expr; - throw_expr.add_source_location()=i_it->source_location; - throw_expr.copy_to_operands(op[0]); - c=code_expressiont(throw_expr); - results[0]=op[0]; + if(!assertion_failure) + { + side_effect_expr_throwt throw_expr; + throw_expr.add_source_location()=i_it->source_location; + throw_expr.copy_to_operands(op[0]); + c=code_expressiont(throw_expr); + results[0]=op[0]; + } + else + { + // TODO: this can be removed once we properly handle throw + // if this athrow is generated by an assertion, then skip it + c=code_skipt(); + assertion_failure=false; + } } else if(statement=="checkcast") { @@ -939,7 +949,13 @@ codet java_bytecode_convert_methodt::convert_instructions( statement=="invokevirtual" || statement=="invokestatic") { - const bool use_this(statement!="invokestatic"); + // Remember that this is triggered by an assertion + if(statement=="invokespecial" && + as_string(arg0.get(ID_identifier)).find("AssertionError")!=std::string::npos) + { + assertion_failure=true; + } + const bool use_this(statement != "invokestatic"); const bool is_virtual( statement=="invokevirtual" || statement=="invokeinterface"); @@ -951,7 +967,7 @@ codet java_bytecode_convert_methodt::convert_instructions( if(parameters.empty() || !parameters[0].get_this()) { irep_idt classname = arg0.get(ID_C_class); - typet thistype = symbol_typet(classname); + typet thistype = symbol_typet(classname); // Note invokespecial is used for super-method calls as well as constructors. if(statement=="invokespecial") { @@ -1553,6 +1569,15 @@ codet java_bytecode_convert_methodt::convert_instructions( symbol_expr.set_identifier( arg0.get_string(ID_class)+"."+arg0.get_string(ID_component_name)); results[0]=java_bytecode_promotion(symbol_expr); + + // set $assertionDisabled to false + if(fieldname.find("$assertionsDisabled")!=std::string::npos) + { + exprt e; + e.make_false(); + c=code_assignt(symbol_expr, e); + } + } else if(statement=="putfield") { @@ -1659,7 +1684,7 @@ codet java_bytecode_convert_methodt::convert_instructions( binary_relation_exprt gezero(op[0],ID_ge,intzero); code_assertt check(gezero); check.add_source_location().set_comment("Array size < 0"); - check.add_source_location().set_property_class("array-create-negative-size"); + check.add_source_location().set_property_class("array-create-negative-size"); checkandcreate.move_to_operands(check); if(max_array_length!=0) From 09c63046a8c73257dffe66810b0c29e5f4cbae38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 4 Nov 2016 10:40:37 +0100 Subject: [PATCH 063/166] class conversion runtime checks / array handling --- .../java_bytecode_convert_class.cpp | 40 ++++++++++++++++--- .../java_bytecode_convert_class.h | 4 +- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 2db872c3f45..b65ee545cb4 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -26,9 +26,13 @@ class java_bytecode_convert_classt:public messaget public: java_bytecode_convert_classt( symbol_tablet &_symbol_table, - message_handlert &_message_handler): + message_handlert &_message_handler, + const bool &_disable_runtime_checks, + int _max_array_length): messaget(_message_handler), - symbol_table(_symbol_table) + symbol_table(_symbol_table), + disable_runtime_checks(_disable_runtime_checks), + max_array_length(_max_array_length) { } @@ -47,6 +51,8 @@ class java_bytecode_convert_classt:public messaget protected: symbol_tablet &symbol_table; + const bool &disable_runtime_checks; + int max_array_length; // conversion void convert(const classt &c); @@ -121,7 +127,8 @@ void java_bytecode_convert_classt::convert(const classt &c) // now do methods for(const auto &method : c.methods) java_bytecode_convert_method( - *class_symbol, method, symbol_table, get_message_handler()); + *class_symbol, method, symbol_table, get_message_handler(), + disable_runtime_checks, max_array_length); // is this a root class? if(c.extends.empty()) @@ -207,6 +214,11 @@ void java_bytecode_convert_classt::convert( new_symbol.is_type=false; new_symbol.value=gen_zero(field_type); + // Do we have the static field symbol already? + const auto s_it=symbol_table.symbols.find(new_symbol.name); + if(s_it!=symbol_table.symbols.end()) + symbol_table.symbols.erase(s_it); // erase, we stubbed it + if(symbol_table.add(new_symbol)) { error() << "failed to add static field symbol" << eom; @@ -259,6 +271,7 @@ void java_bytecode_convert_classt::add_array_types() // we have the base class, java.lang.Object, length and data // of appropriate type struct_type.set_tag(symbol_type.get_identifier()); +<<<<<<< d8b7f7885387d26f7031f56b237aa96e25733f6d struct_type.components().reserve(3); struct_typet::componentt @@ -271,6 +284,18 @@ void java_bytecode_convert_classt::add_array_types() struct_typet::componentt comp2("data", pointer_typet(java_type_from_char(l))); struct_type.components().push_back(comp2); +======= + struct_type.components().resize(3); + struct_type.components()[0].set_name("@java.lang.Object"); + struct_type.components()[0].type()=symbol_typet("java::java.lang.Object"); + struct_type.components()[1].set_name("length"); + struct_type.components()[1].set_pretty_name("length"); + struct_type.components()[1].type()=java_int_type(); + struct_type.components()[2].set_name("data"); + struct_type.components()[2].set_pretty_name("data"); + struct_type.components()[2].type()= + pointer_typet(java_type_from_char(letters[i])); +>>>>>>> class conversion runtime checks / array handling symbolt symbol; symbol.name=symbol_type.get_identifier(); @@ -295,11 +320,16 @@ Function: java_bytecode_convert_class bool java_bytecode_convert_class( const java_bytecode_parse_treet &parse_tree, + const bool &disable_runtime_checks, symbol_tablet &symbol_table, - message_handlert &message_handler) + message_handlert &message_handler, + int max_array_length) { java_bytecode_convert_classt java_bytecode_convert_class( - symbol_table, message_handler); + symbol_table, + message_handler, + disable_runtime_checks, + max_array_length); try { diff --git a/src/java_bytecode/java_bytecode_convert_class.h b/src/java_bytecode/java_bytecode_convert_class.h index cae00f571d0..30737fa79d0 100644 --- a/src/java_bytecode/java_bytecode_convert_class.h +++ b/src/java_bytecode/java_bytecode_convert_class.h @@ -16,7 +16,9 @@ Author: Daniel Kroening, kroening@kroening.com bool java_bytecode_convert_class( const java_bytecode_parse_treet &parse_tree, + const bool &disable_runtime_checks, symbol_tablet &symbol_table, - message_handlert &message_handler); + message_handlert &message_handler, + int max_array_length); #endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_CLASS_H From 8877d75eeae902dc2c68dc390e10168278d00ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 4 Nov 2016 10:47:20 +0100 Subject: [PATCH 064/166] java bytecode index in source location This adds bytecode index to source location and completes source location information. It also completes JSON output for Java source location information. JSON output for Java --- .../java_bytecode_convert_method.cpp | 17 +++++++++++++---- src/java_bytecode/java_bytecode_parse_tree.h | 1 + src/java_bytecode/java_bytecode_parser.cpp | 10 ++++++++++ src/java_bytecode/java_entry_point.cpp | 17 ++++++++++++----- src/util/irep_ids.txt | 1 + src/util/json_expr.cpp | 7 +++++-- src/util/source_location.cpp | 2 ++ src/util/source_location.h | 10 ++++++++++ 8 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 4cbea1f5bca..5c3eb8b43f4 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -336,8 +336,8 @@ void java_bytecode_convert_methodt::convert( method_symbol.name=method.get_name(); method_symbol.base_name=method.get_base_name(); method_symbol.mode=ID_java; - method_symbol.name=method.get_name(); - method_symbol.base_name=method.get_base_name(); + method_symbol.location=m.source_location; + method_symbol.location.set_function(method_identifier); if(method.get_base_name()=="") method_symbol.pretty_name=id2string(class_symbol.pretty_name)+"."+ @@ -985,7 +985,12 @@ codet java_bytecode_convert_methodt::convert_instructions( } code_function_callt call; - call.add_source_location()=i_it->source_location; + source_locationt loc; + loc=i_it->source_location; + loc.set_function(method_id); + source_locationt &dloc = loc; + + call.add_source_location()=dloc; call.arguments()=pop(parameters.size()); // double-check a bit @@ -1057,7 +1062,7 @@ codet java_bytecode_convert_methodt::convert_instructions( call.function()=symbol_exprt(arg0.get(ID_identifier), arg0.type()); } - call.function().add_source_location()=i_it->source_location; + call.function().add_source_location()=dloc; c=call; } else if(statement=="return") @@ -1292,6 +1297,7 @@ codet java_bytecode_convert_methodt::convert_instructions( cast_if_necessary(condition); code_branch.cond()=condition; + code_branch.cond().add_source_location()=i_it->source_location; code_branch.then_case()=code_gotot(label(number)); code_branch.then_case().add_source_location()=i_it->source_location; code_branch.add_source_location()=i_it->source_location; @@ -1316,9 +1322,12 @@ codet java_bytecode_convert_methodt::convert_instructions( code_branch.cond()= binary_relation_exprt(op[0], id, gen_zero(op[0].type())); code_branch.cond().add_source_location()=i_it->source_location; + code_branch.cond().add_source_location().set_function(method_id); code_branch.then_case()=code_gotot(label(number)); code_branch.then_case().add_source_location()=i_it->source_location; + code_branch.then_case().add_source_location().set_function(method_id); code_branch.add_source_location()=i_it->source_location; + code_branch.add_source_location().set_function(method_id); c=code_branch; } diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index 38a89f87c4a..398e3959d1a 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -72,6 +72,7 @@ class java_bytecode_parse_treet public: irep_idt base_name; bool is_native, is_abstract, is_synchronized; + source_locationt source_location; typedef std::vector instructionst; instructionst instructions; diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 8a6483abef1..b78afc6c062 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -746,6 +746,7 @@ void java_bytecode_parsert::rbytecode( instructiont &instruction=instructions.back(); instruction.statement=bytecodes[bytecode].mnemonic; instruction.address=start_of_instruction; + instruction.source_location.set_java_bytecode_index(std::to_string(bytecodeIndex)); switch(bytecodes[bytecode].format) { @@ -1001,8 +1002,16 @@ void java_bytecode_parsert::rmethod_attribute(methodt &method) line_number=it->source_location.get_line(); else if(!line_number.empty()) it->source_location.set_line(line_number); + it->source_location.set_function("java::"+ + id2string(parse_tree.parsed_class.name)+"."+ + id2string(method.name)+":"+ + method.signature); } + // line number of method + if(!method.instructions.empty()) + method.source_location.set_line( + method.instructions.begin()->source_location.get_line()); } else if(attribute_name=="RuntimeInvisibleAnnotations" || attribute_name=="RuntimeVisibleAnnotations") @@ -1416,6 +1425,7 @@ void java_bytecode_parsert::rclass_attribute(classt &parsed_class) m_it!=parsed_class.methods.end(); m_it++) { + m_it->source_location.set_file(sourcefile_name); for(instructionst::iterator i_it=m_it->instructions.begin(); i_it!=m_it->instructions.end(); i_it++) diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index ee0c0c1c2ae..ecfb8ebc99e 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -123,6 +123,7 @@ bool java_static_lifetime_init( code_function_callt function_call; function_call.lhs()=nil_exprt(); function_call.function()=it->second.symbol_expr(); + function_call.add_source_location()=source_location; code_block.add(function_call); } } @@ -176,7 +177,7 @@ exprt::operandst java_build_arguments( index_exprt(string_constantt(p_symbol.base_name), gen_zero(index_type()))); input.op1()=main_arguments[param_number]; - input.add_source_location()=parameters[param_number].source_location(); + input.add_source_location()=function.location; init_code.move_to_operands(input); } @@ -223,8 +224,7 @@ void java_record_outputs( index_exprt(string_constantt(return_symbol.base_name), gen_zero(index_type()))); output.op1()=return_symbol.symbol_expr(); - output.add_source_location()= - function.value.operands().back().source_location(); + output.add_source_location()=function.location; init_code.move_to_operands(output); } @@ -245,7 +245,7 @@ void java_record_outputs( index_exprt(string_constantt(p_symbol.base_name), gen_zero(index_type()))); output.op1()=main_arguments[param_number]; - output.add_source_location()=parameters[param_number].source_location(); + output.add_source_location()=function.location; init_code.move_to_operands(output); } @@ -437,8 +437,15 @@ bool java_entry_point( // build call to the main method code_function_callt call_main; - call_main.add_source_location()=symbol.location; + + source_locationt loc = symbol.location; + loc.set_function(symbol.name); + source_locationt &dloc = loc; + + call_main.add_source_location()=dloc; call_main.function()=symbol.symbol_expr(); + call_main.function().add_source_location()=dloc; + if(to_code_type(symbol.type).return_type()!=empty_typet()) { auxiliary_symbolt return_symbol; diff --git a/src/util/irep_ids.txt b/src/util/irep_ids.txt index 82ff934bd2f..95cb32a2480 100644 --- a/src/util/irep_ids.txt +++ b/src/util/irep_ids.txt @@ -733,3 +733,4 @@ verilog_array low high bswap +java_bytecode_index diff --git a/src/util/json_expr.cpp b/src/util/json_expr.cpp index ab03dc33a60..5fbb4325607 100644 --- a/src/util/json_expr.cpp +++ b/src/util/json_expr.cpp @@ -16,7 +16,7 @@ Author: Peter Schrammel #include "config.h" #include "json_expr.h" - +#include /*******************************************************************\ Function: json @@ -45,6 +45,9 @@ json_objectt json(const source_locationt &location) if(!location.get_function().empty()) result["function"]=json_stringt(id2string(location.get_function())); + if(!location.get_java_bytecode_index().empty()) + result["bytecode_index"]=json_stringt(id2string(location.get_java_bytecode_index())); + return result; } @@ -259,7 +262,7 @@ json_objectt json( if(expr.get(ID_value)==ID_NULL) result["data"]=json_stringt("NULL"); } - else if(type.id()==ID_bool) + else if(type.id()==ID_bool || type.id()==ID_c_bool) { result["name"]=json_stringt("boolean"); result["binary"]=json_stringt(expr.is_true()?"1":"0"); diff --git a/src/util/source_location.cpp b/src/util/source_location.cpp index 9406fd61011..8f8b16e3970 100644 --- a/src/util/source_location.cpp +++ b/src/util/source_location.cpp @@ -31,6 +31,7 @@ std::string source_locationt::as_string(bool print_cwd) const const irep_idt &line=get_line(); const irep_idt &column=get_column(); const irep_idt &function=get_function(); + const irep_idt &bytecode=get_java_bytecode_index(); if(!file.empty()) { @@ -45,6 +46,7 @@ std::string source_locationt::as_string(bool print_cwd) const if(!line.empty()) { if(dest!="") dest+=' '; dest+="line "+id2string(line); } if(!column.empty()) { if(dest!="") dest+=' '; dest+="column "+id2string(column); } if(!function.empty()) { if(dest!="") dest+=' '; dest+="function "+id2string(function); } + if(!bytecode.empty()) { if(dest!="") dest+=' '; dest+="bytecode_index "+id2string(bytecode); } return dest; } diff --git a/src/util/source_location.h b/src/util/source_location.h index c34cfb5f9d2..83a79a8f03d 100644 --- a/src/util/source_location.h +++ b/src/util/source_location.h @@ -68,6 +68,11 @@ class source_locationt:public irept return get(ID_comment); } + inline const irep_idt &get_java_bytecode_index() const + { + return get(ID_java_bytecode_index); + } + inline void set_file(const irep_idt &file) { set(ID_file, file); @@ -118,6 +123,11 @@ class source_locationt:public irept set(ID_comment, comment); } + inline void set_java_bytecode_index(const irep_idt &index) + { + set(ID_java_bytecode_index, index); + } + inline void set_hide() { set(ID_hide, true); From f8f88899150e1b9a3895ba12f809f96affae9520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 4 Nov 2016 10:45:02 +0100 Subject: [PATCH 065/166] Correct parsing / generation of source filename --- src/java_bytecode/java_bytecode_parser.cpp | 31 +++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index b78afc6c062..f0f87644263 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -6,8 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include #include #include +#include #include #include @@ -136,10 +138,10 @@ class java_bytecode_parsert:public parsert } } - u8 read_bytes(unsigned bytes) + u8 read_bytes(size_t bytes) { u8 result=0; - for(unsigned i=0; i Date: Wed, 11 Jan 2017 15:48:22 +0100 Subject: [PATCH 066/166] Clean up Java pointer cast handling --- src/java_bytecode/Makefile | 3 +- src/java_bytecode/java_pointer_casts.cpp | 150 +++++++++++++++++++++++ src/java_bytecode/java_pointer_casts.h | 24 ++++ 3 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/java_bytecode/java_pointer_casts.cpp create mode 100644 src/java_bytecode/java_pointer_casts.h diff --git a/src/java_bytecode/Makefile b/src/java_bytecode/Makefile index f13c327ef77..66ad1003cac 100644 --- a/src/java_bytecode/Makefile +++ b/src/java_bytecode/Makefile @@ -5,7 +5,8 @@ SRC = java_bytecode_language.cpp java_bytecode_parse_tree.cpp \ java_bytecode_typecheck_type.cpp java_bytecode_internal_additions.cpp \ java_root_class.cpp java_bytecode_parser.cpp bytecode_info.cpp \ java_class_loader.cpp jar_file.cpp java_object_factory.cpp \ - java_bytecode_convert_method.cpp java_local_variable_table.cpp + java_bytecode_convert_method.cpp java_local_variable_table.cpp \ + java_pointer_casts.cpp INCLUDES= -I .. diff --git a/src/java_bytecode/java_pointer_casts.cpp b/src/java_bytecode/java_pointer_casts.cpp new file mode 100644 index 00000000000..30bce554248 --- /dev/null +++ b/src/java_bytecode/java_pointer_casts.cpp @@ -0,0 +1,150 @@ + +#include +#include +#include + +#include "java_pointer_casts.h" + +/*******************************************************************\ + +Function: clean_deref + + Inputs: pointer + + Outputs: dereferenced pointer + + Purpose: dereference pointer expression + +\*******************************************************************/ + +exprt clean_deref(const exprt ptr) +{ + return ptr.id()==ID_address_of + ? ptr.op0() + : dereference_exprt(ptr, ptr.type().subtype()); +} + +/*******************************************************************\ + +Function: find_superclass_with_type + + Inputs: pointer + target type to search + + Outputs: true iff a super class with target type is found + + Purpose: + +\*******************************************************************/ + + +bool find_superclass_with_type(exprt &ptr,const typet &target_type, + const namespacet &ns) +{ + + while(true) + { + + const typet ptr_base=ns.follow(ptr.type().subtype()); + + if(ptr_base.id()!=ID_struct) + return false; + + const struct_typet &base_struct=to_struct_type(ptr_base); + + if(base_struct.components().size()==0) + return false; + + const typet &first_field_type= + ns.follow(base_struct.components()[0].type()); + ptr=clean_deref(ptr); + ptr=member_exprt(ptr,base_struct.components()[0].get_name(), + first_field_type); + ptr=address_of_exprt(ptr); + + if(first_field_type==target_type) + return true; + } +} + + +/*******************************************************************\ + +Function: look_through_casts + + Inputs: input expression + + Outputs: recursively search target of typecast + + Purpose: + +\*******************************************************************/ + +static const exprt& look_through_casts(const exprt& in) +{ + if(in.id()==ID_typecast) + { + assert(in.type().id()==ID_pointer); + return look_through_casts(in.op0()); + } + else { + return in; + } +} + + +/*******************************************************************\ + +Function: make_clean_pointer_cast + + Inputs: raw pointer + target type + namespace + + Outputs: cleaned up typecast expression + + Purpose: + +\*******************************************************************/ + +exprt make_clean_pointer_cast(const exprt &rawptr,const typet &target_type, + const namespacet &ns) +{ + + assert(target_type.id()==ID_pointer && + "Non-pointer target in make_clean_pointer_cast?"); + + const exprt &ptr=look_through_casts(rawptr); + + if(ptr.type()==target_type) + return ptr; + + if(ptr.type().subtype()==empty_typet() || + target_type.subtype()==empty_typet()) + return typecast_exprt(ptr,target_type); + + const typet &target_base=ns.follow(target_type.subtype()); + + exprt bare_ptr=ptr; + while(bare_ptr.id()==ID_typecast) + { + assert(bare_ptr.type().id()==ID_pointer && + "Non-pointer in make_clean_pointer_cast?"); + if(bare_ptr.type().subtype()==empty_typet()) + bare_ptr=bare_ptr.op0(); + } + + assert(bare_ptr.type().id()==ID_pointer && + "Non-pointer in make_clean_pointer_cast?"); + + if(bare_ptr.type()==target_type) + return bare_ptr; + + exprt superclass_ptr=bare_ptr; + if(find_superclass_with_type(superclass_ptr,target_base,ns)) + return superclass_ptr; + + return typecast_exprt(bare_ptr,target_type); +} + + diff --git a/src/java_bytecode/java_pointer_casts.h b/src/java_bytecode/java_pointer_casts.h new file mode 100644 index 00000000000..c07492b3db2 --- /dev/null +++ b/src/java_bytecode/java_pointer_casts.h @@ -0,0 +1,24 @@ +/*******************************************************************\ + +Module: JAVA Pointer Casts + +Author: DiffBlue + +\*******************************************************************/ + +#ifndef CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H +#define CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H + +exprt clean_deref(const exprt ptr); + +bool find_superclass_with_type( + exprt &ptr, + const typet &target_type, + const namespacet &ns); + +exprt make_clean_pointer_cast( + const exprt &ptr, + const typet &target_type, + const namespacet &ns); + +#endif // CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H From ba45b556fad61027799d435e3bc2a8d1233a9fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 11 Nov 2016 12:17:33 +0100 Subject: [PATCH 067/166] extract java bytecode convert method class This extracts the convert method class into an extra file. --- .../java_bytecode_convert_class.cpp | 43 +-- .../java_bytecode_convert_class.h | 4 +- .../java_bytecode_convert_method.cpp | 326 ++++++++++++++++-- .../java_bytecode_convert_method.h | 4 +- src/java_bytecode/java_bytecode_language.cpp | 10 +- src/java_bytecode/java_pointer_casts.cpp | 11 +- 6 files changed, 340 insertions(+), 58 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index b65ee545cb4..5d3fd7213f4 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -27,8 +27,8 @@ class java_bytecode_convert_classt:public messaget java_bytecode_convert_classt( symbol_tablet &_symbol_table, message_handlert &_message_handler, - const bool &_disable_runtime_checks, - int _max_array_length): + const bool _disable_runtime_checks, + size_t _max_array_length): messaget(_message_handler), symbol_table(_symbol_table), disable_runtime_checks(_disable_runtime_checks), @@ -51,8 +51,8 @@ class java_bytecode_convert_classt:public messaget protected: symbol_tablet &symbol_table; - const bool &disable_runtime_checks; - int max_array_length; + const bool disable_runtime_checks; + size_t max_array_length; // conversion void convert(const classt &c); @@ -127,8 +127,12 @@ void java_bytecode_convert_classt::convert(const classt &c) // now do methods for(const auto &method : c.methods) java_bytecode_convert_method( - *class_symbol, method, symbol_table, get_message_handler(), - disable_runtime_checks, max_array_length); + *class_symbol, + method, + symbol_table, + get_message_handler(), + disable_runtime_checks, + max_array_length); // is this a root class? if(c.extends.empty()) @@ -271,9 +275,6 @@ void java_bytecode_convert_classt::add_array_types() // we have the base class, java.lang.Object, length and data // of appropriate type struct_type.set_tag(symbol_type.get_identifier()); -<<<<<<< d8b7f7885387d26f7031f56b237aa96e25733f6d - - struct_type.components().reserve(3); struct_typet::componentt comp0("@java.lang.Object", symbol_typet("java::java.lang.Object")); struct_type.components().push_back(comp0); @@ -284,18 +285,6 @@ void java_bytecode_convert_classt::add_array_types() struct_typet::componentt comp2("data", pointer_typet(java_type_from_char(l))); struct_type.components().push_back(comp2); -======= - struct_type.components().resize(3); - struct_type.components()[0].set_name("@java.lang.Object"); - struct_type.components()[0].type()=symbol_typet("java::java.lang.Object"); - struct_type.components()[1].set_name("length"); - struct_type.components()[1].set_pretty_name("length"); - struct_type.components()[1].type()=java_int_type(); - struct_type.components()[2].set_name("data"); - struct_type.components()[2].set_pretty_name("data"); - struct_type.components()[2].type()= - pointer_typet(java_type_from_char(letters[i])); ->>>>>>> class conversion runtime checks / array handling symbolt symbol; symbol.name=symbol_type.get_identifier(); @@ -320,16 +309,16 @@ Function: java_bytecode_convert_class bool java_bytecode_convert_class( const java_bytecode_parse_treet &parse_tree, - const bool &disable_runtime_checks, symbol_tablet &symbol_table, message_handlert &message_handler, - int max_array_length) + const bool disable_runtime_checks, + size_t max_array_length) { java_bytecode_convert_classt java_bytecode_convert_class( - symbol_table, - message_handler, - disable_runtime_checks, - max_array_length); + symbol_table, + message_handler, + disable_runtime_checks, + max_array_length); try { diff --git a/src/java_bytecode/java_bytecode_convert_class.h b/src/java_bytecode/java_bytecode_convert_class.h index 30737fa79d0..264df6ca9df 100644 --- a/src/java_bytecode/java_bytecode_convert_class.h +++ b/src/java_bytecode/java_bytecode_convert_class.h @@ -16,9 +16,9 @@ Author: Daniel Kroening, kroening@kroening.com bool java_bytecode_convert_class( const java_bytecode_parse_treet &parse_tree, - const bool &disable_runtime_checks, symbol_tablet &symbol_table, message_handlert &message_handler, - int max_array_length); + const bool disable_runtime_checks, + size_t max_array_length); #endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_CLASS_H diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 5c3eb8b43f4..70bdc4f86c0 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -55,6 +55,245 @@ class patternt const char *p; }; +class java_bytecode_convert_methodt:public messaget +{ +public: + java_bytecode_convert_methodt( + symbol_tablet &_symbol_table, + message_handlert &_message_handler, + bool _disable_runtime_checks, + size_t _max_array_length): + messaget(_message_handler), + symbol_table(_symbol_table), + disable_runtime_checks(_disable_runtime_checks), + max_array_length(_max_array_length) + { + } + + typedef java_bytecode_parse_treet::methodt methodt; + typedef java_bytecode_parse_treet::instructiont instructiont; + typedef methodt::instructionst instructionst; + + void operator()(const symbolt &class_symbol, const methodt &method) + { + convert(class_symbol, method); + } + +protected: + symbol_tablet &symbol_table; + const bool disable_runtime_checks; + size_t max_array_length; + + irep_idt method_id; + irep_idt current_method; + typet method_return_type; + + class variablet + { + public: + symbol_exprt symbol_expr; + size_t start_pc; + size_t length; + bool is_parameter=false; + }; + + typedef std::vector variablest; + expanding_vector variables; + std::set used_local_names; + bool method_has_this; + + typedef enum instruction_sizet + { + INST_INDEX=2, + INST_INDEX_CONST=3 + } instruction_sizet; + + // return corresponding reference of variable + const variablet &find_variable_for_slot( + size_t address, + variablest &var_list, + instruction_sizet inst_size) + { + for(const variablet &var : var_list) + { + size_t start_pc=var.start_pc; + size_t length=var.length; + if(address+(size_t)inst_size>=start_pc && + address::max(); + return var_list[list_length]; + } + + // JVM local variables + enum variable_cast_argumentt + { + CAST_AS_NEEDED, + NO_CAST + }; + + const exprt variable( + const exprt &arg, + char type_char, + size_t address, + instruction_sizet inst_size, + variable_cast_argumentt do_cast) + { + irep_idt number=to_constant_expr(arg).get_value(); + + std::size_t number_int=safe_string2size_t(id2string(number)); + typet t=java_type_from_char(type_char); + variablest &var_list=variables[number_int]; + + // search variable in list for correct frame / address if necessary + const variablet &var= + find_variable_for_slot(address, var_list, inst_size); + + if(var.symbol_expr.get_identifier().empty()) + { + // an un-named local variable + irep_idt base_name="anonlocal::"+id2string(number)+type_char; + irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); + + symbol_exprt result(identifier, t); + result.set(ID_C_base_name, base_name); + used_local_names.insert(result); + + return result; + } + else + { + exprt result=var.symbol_expr; + if(do_cast==CAST_AS_NEEDED && t!=result.type()) + result=typecast_exprt(result, t); + return result; + } + } + + // temporary variables + std::list tmp_vars; + + symbol_exprt tmp_variable(const std::string &prefix, const typet &type) + { + irep_idt base_name=prefix+"_tmp"+std::to_string(tmp_vars.size()); + irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); + + auxiliary_symbolt tmp_symbol; + tmp_symbol.base_name=base_name; + tmp_symbol.is_static_lifetime=false; + tmp_symbol.mode=ID_java; + tmp_symbol.name=identifier; + tmp_symbol.type=type; + symbol_table.add(tmp_symbol); + + symbol_exprt result(identifier, type); + result.set(ID_C_base_name, base_name); + tmp_vars.push_back(result); + + return result; + } + + // JVM program locations + irep_idt label(const irep_idt &address) + { + return "pc"+id2string(address); + } + + // JVM Stack + typedef std::vector stackt; + stackt stack; + + exprt::operandst pop(std::size_t n) + { + if(stack.size() successors; + std::set predecessors; + codet code; + stackt stack; + bool done; + }; + + typedef std::map address_mapt; + + struct block_tree_nodet + { + bool leaf; + std::vector branch_addresses; + std::vector branch; + block_tree_nodet():leaf(false) {} + explicit block_tree_nodet(bool l):leaf(l) {} + static block_tree_nodet get_leaf() { return block_tree_nodet(true); } + }; + + static void replace_goto_target( + codet &repl, + const irep_idt &old_label, + const irep_idt &new_label); + + code_blockt &get_block_for_pcrange( + block_tree_nodet &tree, + code_blockt &this_block, + unsigned address_start, + unsigned address_limit, + unsigned next_block_start_address); + + code_blockt &get_or_create_block_for_pcrange( + block_tree_nodet &tree, + code_blockt &this_block, + unsigned address_start, + unsigned address_limit, + unsigned next_block_start_address, + const address_mapt &amap, + bool allow_merge=true); + + // conversion + void convert(const symbolt &class_symbol, const methodt &); + void convert(const instructiont &); + + codet convert_instructions( + const instructionst &, const code_typet &); + + const bytecode_infot &get_bytecode_info(const irep_idt &statement); +}; + const size_t SLOTS_PER_INTEGER(1u); const size_t INTEGER_WIDTH(64u); static size_t count_slots( @@ -302,6 +541,7 @@ void java_bytecode_convert_methodt::convert( // add as a JVM variable std::size_t slots=get_variable_slots(param); variables[param_index][0].symbol_expr=parameter_symbol.symbol_expr(); + variables[param_index][0].is_parameter=true; variables[param_index][0].start_pc=0; variables[param_index][0].length=std::numeric_limits::max(); variables[param_index][0].is_parameter=true; @@ -347,6 +587,8 @@ void java_bytecode_convert_methodt::convert( id2string(method.get_base_name())+"()"; method_symbol.type=member_type; + if(is_constructor(method)) + method_symbol.type.set(ID_constructor,true); current_method=method_symbol.name; method_has_this=code_type.has_this(); @@ -418,6 +660,27 @@ static member_exprt to_member(const exprt &pointer, const exprt &fieldref) obj_deref, fieldref.get(ID_component_name), fieldref.type()); } +codet get_array_bounds_check(const exprt &arraystruct, const exprt &idx, const source_locationt& original_sloc) +{ + constant_exprt intzero=as_number(0,java_int_type()); + binary_relation_exprt gezero(idx,ID_ge,intzero); + const member_exprt length_field( + arraystruct, "length", java_int_type()); + binary_relation_exprt ltlength(idx,ID_lt,length_field); + code_blockt boundschecks; + boundschecks.add(code_assertt(gezero)); + boundschecks.operands().back().add_source_location()=original_sloc; + boundschecks.operands().back().add_source_location().set_comment("Array index < 0"); + boundschecks.operands().back().add_source_location().set_property_class("array-index-oob-low"); + boundschecks.add(code_assertt(ltlength)); + boundschecks.operands().back().add_source_location()=original_sloc; + boundschecks.operands().back().add_source_location().set_comment("Array index >= length"); + boundschecks.operands().back().add_source_location().set_property_class("array-index-oob-high"); + + // TODO make this throw ArrayIndexOutOfBoundsException instead of asserting. + return boundschecks; +} + /*******************************************************************\ Function: replace_goto_target @@ -834,6 +1097,8 @@ codet java_bytecode_convert_methodt::convert_instructions( setup_local_variables(method,address_map); std::set working_set; + bool assertion_failure = false; + if(!instructions.empty()) working_set.insert(instructions.front().address); @@ -919,9 +1184,7 @@ codet java_bytecode_convert_methodt::convert_instructions( results[0]=op[0]; } else - { c=code_skipt(); - } } else if(statement=="invokedynamic") { @@ -988,10 +1251,10 @@ codet java_bytecode_convert_methodt::convert_instructions( source_locationt loc; loc=i_it->source_location; loc.set_function(method_id); - source_locationt &dloc = loc; + source_locationt &source_loc=loc; - call.add_source_location()=dloc; - call.arguments()=pop(parameters.size()); + call.add_source_location()=source_loc; + call.arguments() = pop(parameters.size()); // double-check a bit if(use_this) @@ -1037,6 +1300,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // does the function symbol exist? irep_idt id=arg0.get(ID_identifier); + if(symbol_table.symbols.find(id)==symbol_table.symbols.end()) { // no, create stub @@ -1062,8 +1326,8 @@ codet java_bytecode_convert_methodt::convert_instructions( call.function()=symbol_exprt(arg0.get(ID_identifier), arg0.type()); } - call.function().add_source_location()=dloc; - c=call; + call.function().add_source_location()=source_loc; + c = call; } else if(statement=="return") { @@ -1275,7 +1539,7 @@ codet java_bytecode_convert_methodt::convert_instructions( } else { - const unsigned int value(arg0.get_unsigned_int(ID_value)); + const size_t value(arg0.get_unsigned_int(ID_value)); const typet type=java_type_from_char(statement[0]); results[0]=as_number(value, type); } @@ -1404,7 +1668,7 @@ codet java_bytecode_convert_methodt::convert_instructions( const typecast_exprt lhs(op[0], target); const typecast_exprt rhs(op[1], target); - results[0]=lshr_exprt(lhs, rhs); + results[0]=typecast_exprt(lshr_exprt(lhs, rhs),op[0].type()); } else if(statement==patternt("?add")) { @@ -1575,8 +1839,8 @@ codet java_bytecode_convert_methodt::convert_instructions( { assert(op.empty() && results.size()==1); symbol_exprt symbol_expr(arg0.type()); - symbol_expr.set_identifier( - arg0.get_string(ID_class)+"."+arg0.get_string(ID_component_name)); + const auto& fieldname=arg0.get_string(ID_component_name); + symbol_expr.set_identifier(arg0.get_string(ID_class)+"."+fieldname); results[0]=java_bytecode_promotion(symbol_expr); // set $assertionDisabled to false @@ -1586,7 +1850,6 @@ codet java_bytecode_convert_methodt::convert_instructions( e.make_false(); c=code_assignt(symbol_expr, e); } - } else if(statement=="putfield") { @@ -1597,8 +1860,8 @@ codet java_bytecode_convert_methodt::convert_instructions( { assert(op.size()==1 && results.empty()); symbol_exprt symbol_expr(arg0.type()); - symbol_expr.set_identifier( - arg0.get_string(ID_class)+"."+arg0.get_string(ID_component_name)); + const auto& fieldname=arg0.get_string(ID_component_name); + symbol_expr.set_identifier(arg0.get_string(ID_class)+"."+fieldname); c=code_assignt(symbol_expr, op[0]); } else if(statement==patternt("?2?")) // i2c etc. @@ -1662,13 +1925,32 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!i_it->source_location.get_line().empty()) java_new_array.add_source_location()=i_it->source_location; + code_blockt checkandcreate; + if(!disable_runtime_checks) + { + // TODO make this throw NegativeArrayIndexException instead. + constant_exprt intzero=as_number(0,java_int_type()); + binary_relation_exprt gezero(op[0],ID_ge,intzero); + code_assertt check(gezero); + check.add_source_location().set_comment("Array size < 0"); + check.add_source_location().set_property_class("array-create-negative-size"); + checkandcreate.move_to_operands(check); + } + if(max_array_length!=0) + { + constant_exprt size_limit=as_number(max_array_length,java_int_type()); + binary_relation_exprt le_max_size(op[0],ID_le,size_limit); + code_assumet assume_le_max_size(le_max_size); + checkandcreate.move_to_operands(assume_le_max_size); + } const exprt tmp=tmp_variable("newarray", ref_type); - c=code_assignt(tmp, java_new_array); + checkandcreate.copy_to_operands(code_assignt(tmp, java_new_array)); + c=std::move(checkandcreate); results[0]=tmp; } else if(statement=="multianewarray") { - // The first argument is the type, the second argument is the dimension. + // The first argument is the type, the second argument is the number of dimensions. // The size of each dimension is on the stack. irep_idt number=to_constant_expr(arg1).get_value(); std::size_t dimension=safe_string2size_t(id2string(number)); @@ -1676,8 +1958,7 @@ codet java_bytecode_convert_methodt::convert_instructions( op=pop(dimension); assert(results.size()==1); - // arg0.type() - const pointer_typet ref_type=java_array_type('a'); + const pointer_typet ref_type=pointer_typet(arg0.type()); side_effect_exprt java_new_array(ID_java_new_array, ref_type); java_new_array.operands()=op; @@ -2028,10 +2309,15 @@ void java_bytecode_convert_method( const symbolt &class_symbol, const java_bytecode_parse_treet::methodt &method, symbol_tablet &symbol_table, - message_handlert &message_handler) + message_handlert &message_handler, + bool disable_runtime_checks, + size_t max_array_length) { java_bytecode_convert_methodt java_bytecode_convert_method( - symbol_table, message_handler); + symbol_table, + message_handler, + disable_runtime_checks, + max_array_length); java_bytecode_convert_method(class_symbol, method); } diff --git a/src/java_bytecode/java_bytecode_convert_method.h b/src/java_bytecode/java_bytecode_convert_method.h index ff652b3fe91..8945af95bd1 100644 --- a/src/java_bytecode/java_bytecode_convert_method.h +++ b/src/java_bytecode/java_bytecode_convert_method.h @@ -18,6 +18,8 @@ void java_bytecode_convert_method( const symbolt &class_symbol, const java_bytecode_parse_treet::methodt &, symbol_tablet &symbol_table, - message_handlert &message_handler); + message_handlert &message_handler, + bool disable_runtime_checks, + size_t max_array_length); #endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_METHOD_H diff --git a/src/java_bytecode/java_bytecode_language.cpp b/src/java_bytecode/java_bytecode_language.cpp index 12851d186e4..afbf40d93b2 100644 --- a/src/java_bytecode/java_bytecode_language.cpp +++ b/src/java_bytecode/java_bytecode_language.cpp @@ -193,11 +193,11 @@ bool java_bytecode_languaget::typecheck( debug() << "Converting class " << c_it->first << eom; if(java_bytecode_convert_class( - c_it->second, - disable_runtime_checks, - symbol_table, - get_message_handler(), - max_user_array_length)) + c_it->second, + symbol_table, + get_message_handler(), + disable_runtime_checks, + max_user_array_length)) return true; } diff --git a/src/java_bytecode/java_pointer_casts.cpp b/src/java_bytecode/java_pointer_casts.cpp index 30bce554248..483e0287467 100644 --- a/src/java_bytecode/java_pointer_casts.cpp +++ b/src/java_bytecode/java_pointer_casts.cpp @@ -1,3 +1,10 @@ +/*******************************************************************\ + +Module: JAVA Pointer Casts + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ #include #include @@ -115,7 +122,7 @@ exprt make_clean_pointer_cast(const exprt &rawptr,const typet &target_type, "Non-pointer target in make_clean_pointer_cast?"); const exprt &ptr=look_through_casts(rawptr); - + if(ptr.type()==target_type) return ptr; @@ -146,5 +153,3 @@ exprt make_clean_pointer_cast(const exprt &rawptr,const typet &target_type, return typecast_exprt(bare_ptr,target_type); } - - From 6f6d613cb935e117afb1d578f3f22fd073866c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Wed, 11 Jan 2017 16:44:03 +0100 Subject: [PATCH 068/166] Java entry point / main function Restructure finding of the entry point of the Java function or the main function of the program. --- src/java_bytecode/java_bytecode_language.cpp | 15 +- src/java_bytecode/java_bytecode_language.h | 13 +- src/java_bytecode/java_entry_point.cpp | 221 +++++++++++++++---- src/java_bytecode/java_entry_point.h | 16 +- src/java_bytecode/java_object_factory.cpp | 12 +- src/java_bytecode/java_object_factory.h | 4 +- src/java_bytecode/java_types.cpp | 4 +- 7 files changed, 215 insertions(+), 70 deletions(-) diff --git a/src/java_bytecode/java_bytecode_language.cpp b/src/java_bytecode/java_bytecode_language.cpp index afbf40d93b2..3bf20193698 100644 --- a/src/java_bytecode/java_bytecode_language.cpp +++ b/src/java_bytecode/java_bytecode_language.cpp @@ -6,6 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include + #include #include #include @@ -39,9 +41,9 @@ void java_bytecode_languaget::get_language_options(const cmdlinet& cmd) disable_runtime_checks=cmd.isset("disable-runtime-check"); assume_inputs_non_null=cmd.isset("java-assume-inputs-non-null"); if(cmd.isset("java-max-input-array-length")) - max_nondet_array_length=safe_string2int(cmd.get_value("java-max-input-array-length")); + max_nondet_array_length=std::stoi(cmd.get_value("java-max-input-array-length")); if(cmd.isset("java-max-vla-length")) - max_user_array_length=safe_string2int(cmd.get_value("java-max-vla-length")); + max_user_array_length=std::stoi(cmd.get_value("java-max-vla-length")); } /*******************************************************************\ @@ -229,11 +231,12 @@ bool java_bytecode_languaget::final(symbol_tablet &symbol_table) java_internal_additions(symbol_table); - std::tuple t = get_main_symbol(symbol_table, main_class, get_message_handler()); - if(std::get<2>(t)) - return std::get<1>(t); + main_function_resultt res= + get_main_symbol(symbol_table, main_class, get_message_handler()); + if(res.stop_convert) + return res.error_found; - symbolt entry = std::get<0>(t); + symbolt entry=res.main_function; if(java_entry_point(symbol_table,main_class,get_message_handler(), assume_inputs_non_null,max_nondet_array_length)) diff --git a/src/java_bytecode/java_bytecode_language.h b/src/java_bytecode/java_bytecode_language.h index f94f2890ba9..7fef0f68c97 100644 --- a/src/java_bytecode/java_bytecode_language.h +++ b/src/java_bytecode/java_bytecode_language.h @@ -69,10 +69,15 @@ class java_bytecode_languaget:public languaget protected: irep_idt main_class; java_class_loadert java_class_loader; - bool assume_inputs_non_null; - bool disable_runtime_checks; - int max_nondet_array_length; - int max_user_array_length; + bool assume_inputs_non_null; // assume inputs variables to be non-null + + bool disable_runtime_checks; // disable run-time checks for java, i.e., + // ASSERTS for + // - checkcast / instanceof + // - array bounds check + // - array size for newarray + size_t max_nondet_array_length; // maximal length for non-det array creation + size_t max_user_array_length; // max size for user supplied arrays }; languaget *new_java_bytecode_language(); diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index ecfb8ebc99e..d5f44931b9a 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -21,6 +21,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include @@ -28,6 +29,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_entry_point.h" #include "java_object_factory.h" +#include "java_types.h" #define INITIALIZE CPROVER_PREFIX "initialize" @@ -82,30 +84,75 @@ Function: java_static_lifetime_init \*******************************************************************/ +static bool should_init_symbol(const symbolt& sym) +{ + if(sym.type.id()!=ID_code && + sym.is_lvalue && + sym.is_state_var && + sym.is_static_lifetime && + sym.mode==ID_java) + return true; + + if(has_prefix(id2string(sym.name),"java::java.lang.String.Literal")) + return true; + + return false; +} + bool java_static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, - message_handlert &message_handler) + message_handlert &message_handler, + bool assume_init_pointers_not_null, + unsigned max_nondet_array_length) { symbolt &initialize_symbol=symbol_table.lookup(INITIALIZE); code_blockt &code_block=to_code_block(to_code(initialize_symbol.value)); - // we need to zero out all static variables + // we need to zero out all static variables, or nondet-initialize if they're external. + // Iterate over a copy of the symtab, as its iterators are invalidated by object_factory: - for(symbol_tablet::symbolst::const_iterator - it=symbol_table.symbols.begin(); - it!=symbol_table.symbols.end(); - it++) + std::vector symnames; + symnames.reserve(symbol_table.symbols.size()); + for(const auto& entry : symbol_table.symbols) + symnames.push_back(entry.first); + + for(const auto& symname : symnames) { - if(it->second.type.id()!=ID_code && - it->second.is_lvalue && - it->second.is_state_var && - it->second.is_static_lifetime && - it->second.value.is_not_nil() && - it->second.mode==ID_java) + const symbolt& sym=symbol_table.lookup(symname); + if(should_init_symbol(sym)) { - code_assignt assignment(it->second.symbol_expr(), it->second.value); - code_block.add(assignment); + if(sym.value.is_nil() && sym.type!=empty_typet()) + { + bool allow_null=!assume_init_pointers_not_null; + if(allow_null) + { + std::string namestr=id2string(sym.symbol_expr().get_identifier()); + const std::string suffix="@class_model"; + // Static '.class' fields are always non-null. + if(namestr.size()>=suffix.size() && + namestr.substr(namestr.size()-suffix.size())==suffix) + allow_null=false; + if(allow_null && has_prefix( + namestr, + "java::java.lang.String.Literal")) + allow_null=false; + } + auto newsym=object_factory(sym.type, + code_block, + allow_null, + symbol_table, + max_nondet_array_length, + source_location); + code_assignt assignment(sym.symbol_expr(), newsym); + code_block.add(assignment); + } + else if(sym.value.is_not_nil()) + { + code_assignt assignment(sym.symbol_expr(), sym.value); + assignment.add_source_location()=source_location; + code_block.add(assignment); + } } } @@ -131,6 +178,11 @@ bool java_static_lifetime_init( return false; } +static bool is_string_array(const typet& t) +{ + typet compare_to=java_type_from_string("[Ljava.lang.String;"); + return full_eq(t,compare_to); +} /*******************************************************************\ @@ -147,7 +199,9 @@ Function: java_build_arguments exprt::operandst java_build_arguments( const symbolt &function, code_blockt &init_code, - symbol_tablet &symbol_table) + symbol_tablet &symbol_table, + bool assume_init_pointers_not_null, + unsigned max_nondet_array_length) { const code_typet::parameterst ¶meters= to_code_type(function.type).parameters(); @@ -159,13 +213,28 @@ exprt::operandst java_build_arguments( param_numbersecond; @@ -341,7 +402,10 @@ bool java_entry_point( { message.error() << "main symbol `" << config.main << "' not a function" << messaget::eom; - return true; + res.main_function=symbol; + res.error_found=true; + res.stop_convert=true; + return res; } // check if it has a body @@ -349,7 +413,10 @@ bool java_entry_point( { message.error() << "main method `" << main_class << "' has no body" << messaget::eom; - return true; + res.main_function=symbol; + res.error_found=true; + res.stop_convert=true; + return res; } } else @@ -359,7 +426,12 @@ bool java_entry_point( // are we given a main class? if(main_class.empty()) - return false; // silently ignore + { + res.main_function=symbol; + res.error_found=false; + res.stop_convert=true; + return res; // silently ignore + } std::string entry_method= id2string(main_class)+".main"; @@ -382,14 +454,20 @@ bool java_entry_point( if(matches.empty()) { // Not found, silently ignore - return false; + res.main_function=symbol; + res.error_found=false; + res.stop_convert=true; + return res; } if(matches.size()>=2) { message.error() << "main method in `" << main_class << "' is ambiguous" << messaget::eom; - return true; // give up with error, no main + res.main_function=symbol; + res.error_found=true; + res.stop_convert=true; + return res; // give up with error, no main } // function symbol @@ -400,16 +478,59 @@ bool java_entry_point( { message.error() << "main method `" << main_class << "' has no body" << messaget::eom; - return true; // give up with error + res.main_function=symbol; + res.error_found=true; + res.stop_convert=true; + return res; // give up with error } } + res.main_function=symbol; + res.error_found=false; + res.stop_convert=false; + return res; // give up with error +} + +/*******************************************************************\ + +Function: java_entry_point + + Inputs: symbol_table + main class + message_handler + allow pointers in initialization code to be null + + Outputs: true if error occurred on entry point search + + Purpose: find entry point and create initialization code for function + +\*******************************************************************/ + +bool java_entry_point( + symbol_tablet &symbol_table, + const irep_idt &main_class, + message_handlert &message_handler, + bool assume_init_pointers_not_null, + size_t max_nondet_array_length) +{ + // check if the entry point is already there + if(symbol_table.symbols.find(goto_functionst::entry_point())!= + symbol_table.symbols.end()) + return false; // silently ignore + + messaget message(message_handler); + main_function_resultt res = get_main_symbol(symbol_table, main_class, message_handler); + if(res.stop_convert) + return res.stop_convert; + symbolt symbol = res.main_function; + assert(!symbol.value.is_nil()); assert(symbol.type.id()==ID_code); create_initialize(symbol_table); - if(java_static_lifetime_init(symbol_table, symbol.location, message_handler)) + if(java_static_lifetime_init(symbol_table, symbol.location, message_handler, + assume_init_pointers_not_null, max_nondet_array_length)) return true; code_blockt init_code; @@ -460,7 +581,9 @@ bool java_entry_point( } exprt::operandst main_arguments= - java_build_arguments(symbol, init_code, symbol_table); + java_build_arguments(symbol, init_code, symbol_table, + assume_init_pointers_not_null, + max_nondet_array_length); call_main.arguments()=main_arguments; init_code.move_to_operands(call_main); diff --git a/src/java_bytecode/java_entry_point.h b/src/java_bytecode/java_entry_point.h index 5cbee65febb..7fa562de89a 100644 --- a/src/java_bytecode/java_entry_point.h +++ b/src/java_bytecode/java_entry_point.h @@ -14,6 +14,20 @@ Author: Daniel Kroening, kroening@kroening.com bool java_entry_point( class symbol_tablet &symbol_table, const irep_idt &main_class, - class message_handlert &message_handler); + class message_handlert &message_handler, + bool assume_init_pointers_not_null, + size_t max_nondet_array_length); + +typedef struct +{ + symbolt main_function; + bool error_found; + bool stop_convert; +} main_function_resultt; + +main_function_resultt get_main_symbol( + symbol_tablet &symbol_table, + const irep_idt &main_class, + message_handlert &); #endif // CPROVER_JAVA_BYTECODE_JAVA_ENTRY_POINT_H diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index b27797b0416..766d2202358 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -37,13 +37,13 @@ class gen_nondet_state { code_blockt& init_code; std::set recursion_set; bool assume_non_null; - int max_nondet_array_length; + size_t max_nondet_array_length; symbol_tablet& symbol_table; namespacet ns; public: - gen_nondet_state(code_blockt& ic, bool ann, int mnal, symbol_tablet& st) : + gen_nondet_state(code_blockt& ic, bool ann, size_t mnal, symbol_tablet& st) : init_code(ic), assume_non_null(ann), max_nondet_array_length(mnal), @@ -301,7 +301,7 @@ void gen_nondet_state::gen_nondet_init( // Borrowed from java_bytecode_convert.cpp -- todo find a sensible place to factor this. static constant_exprt as_number(const mp_integer value, const typet &type) { - const unsigned int java_int_width(type.get_unsigned_int(ID_width)); + const size_t java_int_width(type.get_unsigned_int(ID_width)); const std::string significant_bits(integer2string(value, 2)); std::string binary_width(java_int_width - significant_bits.length(), '0'); return constant_exprt(binary_width += significant_bits, type); @@ -426,7 +426,7 @@ void gen_nondet_init( bool skip_classid, bool create_dynamic_objects, bool assume_non_null, - int max_nondet_array_length) + size_t max_nondet_array_length) { gen_nondet_state state(init_code,assume_non_null,max_nondet_array_length, symbol_table); @@ -447,7 +447,7 @@ Function: new_tmp_symbol symbolt &new_tmp_symbol(symbol_tablet &symbol_table, const std::string& prefix) { - static int temporary_counter=0; + static size_t temporary_counter=0; auxiliary_symbolt new_symbol; symbolt *symbol_ptr; @@ -497,7 +497,7 @@ exprt object_factory( code_blockt &init_code, bool allow_null, symbol_tablet &symbol_table, - int max_nondet_array_length, + size_t max_nondet_array_length, const source_locationt &loc) { if(type.id()==ID_pointer) diff --git a/src/java_bytecode/java_object_factory.h b/src/java_bytecode/java_object_factory.h index b86c5d3791c..5e8d4417ad5 100644 --- a/src/java_bytecode/java_object_factory.h +++ b/src/java_bytecode/java_object_factory.h @@ -17,7 +17,7 @@ exprt object_factory( code_blockt &init_code, bool allow_null, symbol_tablet &symbol_table, - int max_nondet_array_length, + size_t max_nondet_array_length, const source_locationt &); void gen_nondet_init( @@ -28,7 +28,7 @@ void gen_nondet_init( bool skip_classid = false, bool create_dynamic_objects = false, bool assume_non_null = false, - int max_nondet_array_length = 5); + size_t max_nondet_array_length = 5); exprt get_nondet_bool(const typet&); diff --git a/src/java_bytecode/java_types.cpp b/src/java_bytecode/java_types.cpp index 37682a99d49..5b19db8e581 100644 --- a/src/java_bytecode/java_types.cpp +++ b/src/java_bytecode/java_types.cpp @@ -448,7 +448,7 @@ char java_char_from_type(const typet &type) if(id==ID_signedbv) { - const unsigned int width(type.get_unsigned_int(ID_width)); + const size_t width(type.get_unsigned_int(ID_width)); if(java_int_type().get_unsigned_int(ID_width) == width) return 'i'; else if(java_long_type().get_unsigned_int(ID_width) == width) @@ -462,7 +462,7 @@ char java_char_from_type(const typet &type) return 'c'; else if(id==ID_floatbv) { - const unsigned int width(type.get_unsigned_int(ID_width)); + const size_t width(type.get_unsigned_int(ID_width)); if(java_float_type().get_unsigned_int(ID_width) == width) return 'f'; else if(java_double_type().get_unsigned_int(ID_width) == width) From 50089afebb0113e5d0009d3e7927ef701d616108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 19 Dec 2016 12:51:15 +0100 Subject: [PATCH 069/166] Correct java type width handling Use `.get_width()` instead of `ID_width` and split a complex statement in Java typecheck. --- .../java_bytecode_typecheck_expr.cpp | 3 ++- src/java_bytecode/java_types.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/java_bytecode/java_bytecode_typecheck_expr.cpp b/src/java_bytecode/java_bytecode_typecheck_expr.cpp index d513bf1ebc1..fd60c72b7dc 100644 --- a/src/java_bytecode/java_bytecode_typecheck_expr.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_expr.cpp @@ -127,7 +127,8 @@ void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr) escape_non_alnum(escaped); identifier_str << "java::java.lang.String.Literal." << escaped; // Avoid naming clashes by virtue of escaping: - size_t unique_num=++(escaped_string_literal_count[identifier_str.str()]); + size_t unique_num=escaped_string_literal_count[identifier_str.str()]; + unique_num++; if(unique_num!=1) identifier_str << unique_num; diff --git a/src/java_bytecode/java_types.cpp b/src/java_bytecode/java_types.cpp index 5b19db8e581..88fc91d1587 100644 --- a/src/java_bytecode/java_types.cpp +++ b/src/java_bytecode/java_types.cpp @@ -448,24 +448,24 @@ char java_char_from_type(const typet &type) if(id==ID_signedbv) { - const size_t width(type.get_unsigned_int(ID_width)); - if(java_int_type().get_unsigned_int(ID_width) == width) + const size_t width=to_signedbv_type(type).get_width(); + if(to_signedbv_type(java_int_type()).get_width()==width) return 'i'; - else if(java_long_type().get_unsigned_int(ID_width) == width) + else if(to_signedbv_type(java_long_type()).get_width()==width) return 'l'; - else if(java_short_type().get_unsigned_int(ID_width) == width) + else if(to_signedbv_type(java_short_type()).get_width()==width) return 's'; - else if(java_byte_type().get_unsigned_int(ID_width) == width) + else if(to_signedbv_type(java_byte_type()).get_width()==width) return 'b'; } else if(id==ID_unsignedbv) return 'c'; else if(id==ID_floatbv) { - const size_t width(type.get_unsigned_int(ID_width)); - if(java_float_type().get_unsigned_int(ID_width) == width) + const size_t width(to_floatbv_type(type).get_width()); + if(to_floatbv_type(java_float_type()).get_width()==width) return 'f'; - else if(java_double_type().get_unsigned_int(ID_width) == width) + else if(to_floatbv_type(java_double_type()).get_width()==width) return 'd'; } else if(id==ID_c_bool) From 51999dca129dae3826156eaa849e4aca25f19dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 13 Jan 2017 16:47:22 +0100 Subject: [PATCH 070/166] pacify cpplint --- src/java_bytecode/expr2java.cpp | 12 +- src/java_bytecode/expr2java.h | 18 +- .../java_bytecode_convert_class.cpp | 11 +- .../java_bytecode_convert_method.cpp | 181 +++++++----- src/java_bytecode/java_bytecode_language.cpp | 11 +- src/java_bytecode/java_bytecode_language.h | 5 +- src/java_bytecode/java_bytecode_parser.cpp | 148 +++++----- src/java_bytecode/java_bytecode_typecheck.h | 4 +- .../java_bytecode_typecheck_expr.cpp | 21 +- src/java_bytecode/java_class_loader.cpp | 8 +- src/java_bytecode/java_entry_point.cpp | 93 +++--- src/java_bytecode/java_object_factory.cpp | 264 ++++++++++-------- src/java_bytecode/java_object_factory.h | 10 +- src/java_bytecode/java_pointer_casts.cpp | 45 +-- src/util/json_expr.cpp | 12 +- src/util/source_location.cpp | 40 ++- src/util/source_location.h | 3 - 17 files changed, 532 insertions(+), 354 deletions(-) diff --git a/src/java_bytecode/expr2java.cpp b/src/java_bytecode/expr2java.cpp index 7574c1e4ce9..47e21d2f9c7 100644 --- a/src/java_bytecode/expr2java.cpp +++ b/src/java_bytecode/expr2java.cpp @@ -90,7 +90,10 @@ std::string expr2javat::convert_code_function_call( unsigned p; std::string arg_str=convert(*it, p); - if(first) first=false; else dest+=", "; + if(first) + first=false; + else + dest+=", "; // TODO: ggf. Klammern je nach p dest+=arg_str; } @@ -218,7 +221,7 @@ std::string expr2javat::convert_constant( dest+="(char)'"; if(int_value>=' ' && int_value<127) - dest+=(char)(int_value.to_long()); + dest+=static_cast(int_value.to_long()); else { std::string hex=integer2string(int_value, 16); @@ -332,7 +335,8 @@ std::string expr2javat::convert_rec( if(code_type.has_ellipsis()) { - if(!parameters.empty()) dest+=", "; + if(!parameters.empty()) + dest+=", "; dest+="..."; } @@ -534,7 +538,7 @@ std::string expr2javat::convert_code( if(statement==ID_java_new || statement==ID_java_new_array) - return convert_java_new(src,indent); + return convert_java_new(src, indent); if(statement==ID_function_call) return convert_code_function_call(to_code_function_call(src), indent); diff --git a/src/java_bytecode/expr2java.h b/src/java_bytecode/expr2java.h index f4d03084348..a304f077288 100644 --- a/src/java_bytecode/expr2java.h +++ b/src/java_bytecode/expr2java.h @@ -19,7 +19,7 @@ class typet; class expr2javat:public expr2ct { public: - expr2javat(const namespacet &_ns):expr2ct(_ns) { } + explicit expr2javat(const namespacet &_ns):expr2ct(_ns) { } virtual std::string convert(const exprt &src) { @@ -34,13 +34,21 @@ class expr2javat:public expr2ct protected: virtual std::string convert(const exprt &src, unsigned &precedence); virtual std::string convert_java_this(const exprt &src, unsigned precedence); - virtual std::string convert_java_instanceof(const exprt &src, unsigned precedence); + virtual std::string convert_java_instanceof( + const exprt &src, + unsigned precedence); virtual std::string convert_java_new(const exprt &src, unsigned precedence); - virtual std::string convert_code_java_delete(const exprt &src, unsigned precedence); + virtual std::string convert_code_java_delete( + const exprt &src, + unsigned precedence); virtual std::string convert_struct(const exprt &src, unsigned &precedence); virtual std::string convert_code(const codet &src, unsigned indent); - virtual std::string convert_constant(const constant_exprt &src, unsigned &precedence); - virtual std::string convert_code_function_call(const code_function_callt &src, unsigned indent); + virtual std::string convert_constant( + const constant_exprt &src, + unsigned &precedence); + virtual std::string convert_code_function_call( + const code_function_callt &src, + unsigned indent); virtual std::string convert_rec( const typet &src, diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 5d3fd7213f4..295d7bfb367 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -20,7 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -namespace { class java_bytecode_convert_classt:public messaget { public: @@ -61,7 +60,6 @@ class java_bytecode_convert_classt:public messaget void generate_class_stub(const irep_idt &class_name); void add_array_types(); }; -} /*******************************************************************\ @@ -151,7 +149,8 @@ Function: java_bytecode_convert_classt::generate_class_stub \*******************************************************************/ -void java_bytecode_convert_classt::generate_class_stub(const irep_idt &class_name) +void java_bytecode_convert_classt::generate_class_stub( + const irep_idt &class_name) { class_typet class_type; @@ -174,7 +173,8 @@ void java_bytecode_convert_classt::generate_class_stub(const irep_idt &class_nam if(symbol_table.move(new_symbol, class_symbol)) { - warning() << "stub class symbol "+id2string(new_symbol.name)+" already exists"; + warning() << "stub class symbol "+ + id2string(new_symbol.name)+" already exists"; } else { @@ -213,7 +213,8 @@ void java_bytecode_convert_classt::convert( new_symbol.name=id2string(class_symbol.name)+"."+id2string(f.name); new_symbol.base_name=f.name; new_symbol.type=field_type; - new_symbol.pretty_name=id2string(class_symbol.pretty_name)+"."+id2string(f.name); + new_symbol.pretty_name=id2string(class_symbol.pretty_name)+ + "."+id2string(f.name); new_symbol.mode=ID_java; new_symbol.is_type=false; new_symbol.value=gen_zero(field_type); diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 70bdc4f86c0..c54f4f235f8 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -172,6 +172,8 @@ class java_bytecode_convert_methodt:public messaget else { exprt result=var.symbol_expr; + if(!var.is_parameter) + used_local_names.insert(to_symbol_expr(result)); if(do_cast==CAST_AS_NEEDED && t!=result.type()) result=typecast_exprt(result, t); return result; @@ -289,7 +291,8 @@ class java_bytecode_convert_methodt:public messaget void convert(const instructiont &); codet convert_instructions( - const instructionst &, const code_typet &); + const instructionst &, + const code_typet &); const bytecode_infot &get_bytecode_info(const irep_idt &statement); }; @@ -588,7 +591,7 @@ void java_bytecode_convert_methodt::convert( method_symbol.type=member_type; if(is_constructor(method)) - method_symbol.type.set(ID_constructor,true); + method_symbol.type.set(ID_constructor, true); current_method=method_symbol.name; method_has_this=code_type.has_this(); @@ -620,7 +623,8 @@ const bytecode_infot &java_bytecode_convert_methodt::get_bytecode_info( const irep_idt &statement) { for(const bytecode_infot *p=bytecode_info; p->mnemonic!=0; p++) - if(statement==p->mnemonic) return *p; + if(statement==p->mnemonic) + return *p; error() << "failed to find bytecode mnemonic `" << statement << '\'' << eom; @@ -629,14 +633,20 @@ const bytecode_infot &java_bytecode_convert_methodt::get_bytecode_info( static irep_idt get_if_cmp_operator(const irep_idt &stmt) { - if(stmt==patternt("if_?cmplt")) return ID_lt; - if(stmt==patternt("if_?cmple")) return ID_le; - if(stmt==patternt("if_?cmpgt")) return ID_gt; - if(stmt==patternt("if_?cmpge")) return ID_ge; - if(stmt==patternt("if_?cmpeq")) return ID_equal; - if(stmt==patternt("if_?cmpne")) return ID_notequal; - - throw "Unhandled java comparison instruction"; + if(stmt==patternt("if_?cmplt")) + return ID_lt; + if(stmt==patternt("if_?cmple")) + return ID_le; + if(stmt==patternt("if_?cmpgt")) + return ID_gt; + if(stmt==patternt("if_?cmpge")) + return ID_ge; + if(stmt==patternt("if_?cmpeq")) + return ID_equal; + if(stmt==patternt("if_?cmpne")) + return ID_notequal; + + throw "unhandled java comparison instruction"; } static constant_exprt as_number(const mp_integer value, const typet &type) @@ -657,25 +667,33 @@ static member_exprt to_member(const exprt &pointer, const exprt &fieldref) const dereference_exprt obj_deref(pointer2, class_type); return member_exprt( - obj_deref, fieldref.get(ID_component_name), fieldref.type()); + obj_deref, + fieldref.get(ID_component_name), + fieldref.type()); } -codet get_array_bounds_check(const exprt &arraystruct, const exprt &idx, const source_locationt& original_sloc) +codet get_array_bounds_check( + const exprt &arraystruct, + const exprt &idx, + const source_locationt& original_sloc) { - constant_exprt intzero=as_number(0,java_int_type()); - binary_relation_exprt gezero(idx,ID_ge,intzero); - const member_exprt length_field( - arraystruct, "length", java_int_type()); - binary_relation_exprt ltlength(idx,ID_lt,length_field); + constant_exprt intzero=as_number(0, java_int_type()); + binary_relation_exprt gezero(idx, ID_ge, intzero); + const member_exprt length_field(arraystruct, "length", java_int_type()); + binary_relation_exprt ltlength(idx, ID_lt, length_field); code_blockt boundschecks; boundschecks.add(code_assertt(gezero)); boundschecks.operands().back().add_source_location()=original_sloc; - boundschecks.operands().back().add_source_location().set_comment("Array index < 0"); - boundschecks.operands().back().add_source_location().set_property_class("array-index-oob-low"); + boundschecks.operands().back().add_source_location() + .set_comment("Array index < 0"); + boundschecks.operands().back().add_source_location() + .set_property_class("array-index-oob-low"); boundschecks.add(code_assertt(ltlength)); boundschecks.operands().back().add_source_location()=original_sloc; - boundschecks.operands().back().add_source_location().set_comment("Array index >= length"); - boundschecks.operands().back().add_source_location().set_property_class("array-index-oob-high"); + boundschecks.operands().back().add_source_location() + .set_comment("Array index >= length"); + boundschecks.operands().back().add_source_location() + .set_property_class("array-index-oob-high"); // TODO make this throw ArrayIndexOutOfBoundsException instead of asserting. return boundschecks; @@ -1000,9 +1018,10 @@ codet java_bytecode_convert_methodt::convert_instructions( i_it++) { std::pair a_entry= - address_map.insert(std::make_pair( - i_it->address, - converted_instructiont(i_it, code_skipt()))); + address_map.insert( + std::make_pair( + i_it->address, + converted_instructiont(i_it, code_skipt()))); assert(a_entry.second); // addresses are strictly increasing, hence we must have inserted // a new maximal key @@ -1097,7 +1116,7 @@ codet java_bytecode_convert_methodt::convert_instructions( setup_local_variables(method,address_map); std::set working_set; - bool assertion_failure = false; + bool assertion_failure=false; if(!instructions.empty()) working_set.insert(instructions.front().address); @@ -1109,19 +1128,22 @@ codet java_bytecode_convert_methodt::convert_instructions( assert(a_it!=address_map.end()); working_set.erase(cur); - if(a_it->second.done) continue; - working_set.insert(a_it->second.successors.begin(), - a_it->second.successors.end()); + if(a_it->second.done) + continue; + working_set + .insert(a_it->second.successors.begin(), a_it->second.successors.end()); instructionst::const_iterator i_it=a_it->second.source; stack.swap(a_it->second.stack); a_it->second.stack.clear(); codet &c=a_it->second.code; - assert(stack.empty() || - a_it->second.predecessors.size()<=1 || - has_prefix(stack.front().get_string(ID_C_base_name), - "$stack")); + assert( + stack.empty() || + a_it->second.predecessors.size()<=1 || + has_prefix( + stack.front().get_string(ID_C_base_name), + "$stack")); irep_idt statement=i_it->statement; exprt arg0=i_it->args.size()>=1?i_it->args[0]:nil_exprt(); @@ -1214,11 +1236,12 @@ codet java_bytecode_convert_methodt::convert_instructions( { // Remember that this is triggered by an assertion if(statement=="invokespecial" && - as_string(arg0.get(ID_identifier)).find("AssertionError")!=std::string::npos) + as_string(arg0.get(ID_identifier)) + .find("AssertionError")!=std::string::npos) { assertion_failure=true; } - const bool use_this(statement != "invokestatic"); + const bool use_this(statement!="invokestatic"); const bool is_virtual( statement=="invokevirtual" || statement=="invokeinterface"); @@ -1229,12 +1252,14 @@ codet java_bytecode_convert_methodt::convert_instructions( { if(parameters.empty() || !parameters[0].get_this()) { - irep_idt classname = arg0.get(ID_C_class); - typet thistype = symbol_typet(classname); - // Note invokespecial is used for super-method calls as well as constructors. + irep_idt classname=arg0.get(ID_C_class); + typet thistype=symbol_typet(classname); + // Note invokespecial is used for super-method calls as well as + // constructors. if(statement=="invokespecial") { - if(as_string(arg0.get(ID_identifier)).find("")!=std::string::npos) + if(as_string(arg0.get(ID_identifier)) + .find("")!=std::string::npos) code_type.set(ID_constructor, true); else code_type.set("java_super_method_call", true); @@ -1254,7 +1279,7 @@ codet java_bytecode_convert_methodt::convert_instructions( source_locationt &source_loc=loc; call.add_source_location()=source_loc; - call.arguments() = pop(parameters.size()); + call.arguments()=pop(parameters.size()); // double-check a bit if(use_this) @@ -1327,7 +1352,7 @@ codet java_bytecode_convert_methodt::convert_instructions( } call.function().add_source_location()=source_loc; - c = call; + c=call; } else if(statement=="return") { @@ -1340,7 +1365,8 @@ codet java_bytecode_convert_methodt::convert_instructions( // conversion. assert(op.size()==1 && results.empty()); exprt r=op[0]; - if(r.type()!=method_return_type) r=typecast_exprt(r, method_return_type); + if(r.type()!=method_return_type) + r=typecast_exprt(r, method_return_type); c=code_returnt(r); } else if(statement==patternt("?astore")) @@ -1355,7 +1381,9 @@ codet java_bytecode_convert_methodt::convert_instructions( const dereference_exprt deref(pointer, pointer.type().subtype()); const member_exprt data_ptr( - deref, "data", pointer_typet(java_type_from_char(type_char))); + deref, + "data", + pointer_typet(java_type_from_char(type_char))); plus_exprt data_plus_offset(data_ptr, op[1], data_ptr.type()); typet element_type=data_ptr.type().subtype(); @@ -1364,7 +1392,8 @@ codet java_bytecode_convert_methodt::convert_instructions( code_blockt assert_and_put; if(!disable_runtime_checks) { - codet bounds_check=get_array_bounds_check(deref,op[1],i_it->source_location); + codet bounds_check= + get_array_bounds_check(deref, op[1], i_it->source_location); bounds_check.add_source_location()=i_it->source_location; assert_and_put.move_to_operands(bounds_check); } @@ -1379,7 +1408,8 @@ codet java_bytecode_convert_methodt::convert_instructions( // store value into some local variable assert(op.size()==1 && results.empty()); - exprt var=variable(arg0, statement[0], i_it->address, NO_CAST); + exprt var= + variable(arg0, statement[0], i_it->address, INST_INDEX, NO_CAST); exprt toassign=op[0]; if('a'==statement[0] && toassign.type()!=var.type()) @@ -1399,7 +1429,9 @@ codet java_bytecode_convert_methodt::convert_instructions( const dereference_exprt deref(pointer, pointer.type().subtype()); const member_exprt data_ptr( - deref, "data", pointer_typet(java_type_from_char(type_char))); + deref, + "data", + pointer_typet(java_type_from_char(type_char))); plus_exprt data_plus_offset(data_ptr, op[1], data_ptr.type()); typet element_type=data_ptr.type().subtype(); @@ -1407,7 +1439,8 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!disable_runtime_checks) { - codet bounds_check=get_array_bounds_check(deref,op[1],i_it->source_location); + codet bounds_check= + get_array_bounds_check(deref, op[1], i_it->source_location); bounds_check.add_source_location()=i_it->source_location; c=std::move(bounds_check); } @@ -1416,7 +1449,8 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement==patternt("?load")) { // load a value from a local variable - results[0]=variable(arg0, statement[0], i_it->address, CAST_AS_NEEDED); + results[0]= + variable(arg0, statement[0], i_it->address, INST_INDEX, CAST_AS_NEEDED); } else if(statement=="ldc" || statement=="ldc_w" || statement=="ldc2" || statement=="ldc2_w") @@ -1524,9 +1558,9 @@ codet java_bytecode_convert_methodt::convert_instructions( if(is_double || is_float) { const ieee_float_spect spec( - is_float ? - ieee_float_spect::single_precision() : - ieee_float_spect::double_precision()); + is_float? + ieee_float_spect::single_precision(): + ieee_float_spect::double_precision()); ieee_floatt value(spec); const typet &arg_type(arg0.type()); @@ -1554,7 +1588,8 @@ codet java_bytecode_convert_methodt::convert_instructions( irep_idt number=to_constant_expr(arg0).get_value(); assert(op.size()==2 && results.empty()); - code_ifthenelset code_branch; + code_ifthenelset + code_branch; const irep_idt cmp_op=get_if_cmp_operator(statement); binary_relation_exprt condition(op[0], cmp_op, op[1]); @@ -1582,7 +1617,8 @@ codet java_bytecode_convert_methodt::convert_instructions( irep_idt number=to_constant_expr(arg0).get_value(); assert(op.size()==1 && results.empty()); - code_ifthenelset code_branch; + code_ifthenelset + code_branch; code_branch.cond()= binary_relation_exprt(op[0], id, gen_zero(op[0].type())); code_branch.cond().add_source_location()=i_it->source_location; @@ -1599,7 +1635,8 @@ codet java_bytecode_convert_methodt::convert_instructions( { irep_idt number=to_constant_expr(arg0).get_value(); assert(op.size()==1 && results.empty()); - code_ifthenelset code_branch; + code_ifthenelset + code_branch; const typecast_exprt lhs(op[0], pointer_typet(empty_typet())); const exprt rhs(gen_zero(lhs.type())); code_branch.cond()=binary_relation_exprt(lhs, ID_notequal, rhs); @@ -1613,7 +1650,8 @@ codet java_bytecode_convert_methodt::convert_instructions( { assert(op.size()==1 && results.empty()); irep_idt number=to_constant_expr(arg0).get_value(); - code_ifthenelset code_branch; + code_ifthenelset + code_branch; const typecast_exprt lhs(op[0], pointer_typet(empty_typet())); const exprt rhs(gen_zero(lhs.type())); code_branch.cond()=binary_relation_exprt(lhs, ID_equal, rhs); @@ -1626,7 +1664,8 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement=="iinc") { code_assignt code_assign; - code_assign.lhs()=variable(arg0, 'i', i_it->address, NO_CAST); + code_assign.lhs()= + variable(arg0, 'i', i_it->address, INST_INDEX_CONST, NO_CAST); code_assign.rhs()=plus_exprt( variable(arg0, 'i', i_it->address, CAST_AS_NEEDED), typecast_exprt(arg1, java_int_type())); @@ -1668,7 +1707,7 @@ codet java_bytecode_convert_methodt::convert_instructions( const typecast_exprt lhs(op[0], target); const typecast_exprt rhs(op[1], target); - results[0]=typecast_exprt(lshr_exprt(lhs, rhs),op[0].type()); + results[0]=typecast_exprt(lshr_exprt(lhs, rhs), op[0].type()); } else if(statement==patternt("?add")) { @@ -1715,9 +1754,13 @@ codet java_bytecode_convert_methodt::convert_instructions( const typet t=java_int_type(); results[0]= - if_exprt(binary_relation_exprt(op[0], ID_equal, op[1]), gen_zero(t), - if_exprt(binary_relation_exprt(op[0], ID_gt, op[1]), from_integer(1, t), - from_integer(-1, t))); + if_exprt( + binary_relation_exprt(op[0], ID_equal, op[1]), + gen_zero(t), + if_exprt( + binary_relation_exprt(op[0], ID_gt, op[1]), + from_integer(1, t), + from_integer(-1, t))); } else if(statement==patternt("?cmp?")) { @@ -1929,17 +1972,18 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!disable_runtime_checks) { // TODO make this throw NegativeArrayIndexException instead. - constant_exprt intzero=as_number(0,java_int_type()); - binary_relation_exprt gezero(op[0],ID_ge,intzero); + constant_exprt intzero=as_number(0, java_int_type()); + binary_relation_exprt gezero(op[0], ID_ge, intzero); code_assertt check(gezero); check.add_source_location().set_comment("Array size < 0"); - check.add_source_location().set_property_class("array-create-negative-size"); + check.add_source_location() + .set_property_class("array-create-negative-size"); checkandcreate.move_to_operands(check); } if(max_array_length!=0) { - constant_exprt size_limit=as_number(max_array_length,java_int_type()); - binary_relation_exprt le_max_size(op[0],ID_le,size_limit); + constant_exprt size_limit=as_number(max_array_length, java_int_type()); + binary_relation_exprt le_max_size(op[0], ID_le, size_limit); code_assumet assume_le_max_size(le_max_size); checkandcreate.move_to_operands(assume_le_max_size); } @@ -1950,8 +1994,8 @@ codet java_bytecode_convert_methodt::convert_instructions( } else if(statement=="multianewarray") { - // The first argument is the type, the second argument is the number of dimensions. - // The size of each dimension is on the stack. + // The first argument is the type, the second argument is the number of + // dimensions. The size of each dimension is on the stack. irep_idt number=to_constant_expr(arg1).get_value(); std::size_t dimension=safe_string2size_t(id2string(number)); @@ -2138,8 +2182,7 @@ codet java_bytecode_convert_methodt::convert_instructions( stackt::const_iterator os_it=a_it2->second.stack.begin(); for(auto &expr : stack) { - assert(has_prefix(os_it->get_string(ID_C_base_name), - "$stack")); + assert(has_prefix(os_it->get_string(ID_C_base_name), "$stack")); symbol_exprt lhs=to_symbol_expr(*os_it); code_assignt a(lhs, expr); more_code.copy_to_operands(a); diff --git a/src/java_bytecode/java_bytecode_language.cpp b/src/java_bytecode/java_bytecode_language.cpp index 3bf20193698..20b996999d5 100644 --- a/src/java_bytecode/java_bytecode_language.cpp +++ b/src/java_bytecode/java_bytecode_language.cpp @@ -41,7 +41,8 @@ void java_bytecode_languaget::get_language_options(const cmdlinet& cmd) disable_runtime_checks=cmd.isset("disable-runtime-check"); assume_inputs_non_null=cmd.isset("java-assume-inputs-non-null"); if(cmd.isset("java-max-input-array-length")) - max_nondet_array_length=std::stoi(cmd.get_value("java-max-input-array-length")); + max_nondet_array_length= + std::stoi(cmd.get_value("java-max-input-array-length")); if(cmd.isset("java-max-vla-length")) max_user_array_length=std::stoi(cmd.get_value("java-max-vla-length")); } @@ -238,8 +239,12 @@ bool java_bytecode_languaget::final(symbol_tablet &symbol_table) symbolt entry=res.main_function; - if(java_entry_point(symbol_table,main_class,get_message_handler(), - assume_inputs_non_null,max_nondet_array_length)) + if(java_entry_point( + symbol_table, + main_class, + get_message_handler(), + assume_inputs_non_null, + max_nondet_array_length)) return true; return false; diff --git a/src/java_bytecode/java_bytecode_language.h b/src/java_bytecode/java_bytecode_language.h index 7fef0f68c97..dbbc945ccaf 100644 --- a/src/java_bytecode/java_bytecode_language.h +++ b/src/java_bytecode/java_bytecode_language.h @@ -17,7 +17,6 @@ Author: Daniel Kroening, kroening@kroening.com class java_bytecode_languaget:public languaget { public: - virtual void get_language_options(const cmdlinet&); virtual bool preprocess( @@ -39,7 +38,9 @@ class java_bytecode_languaget:public languaget void show_parse(std::ostream &out) override; virtual ~java_bytecode_languaget(); - java_bytecode_languaget() : max_nondet_array_length(5), max_user_array_length(0) { } + java_bytecode_languaget(): + max_nondet_array_length(5), + max_user_array_length(0) { } bool from_expr( const exprt &expr, diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index f0f87644263..f2e14888d10 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -352,7 +352,7 @@ void java_bytecode_parsert::get_class_refs() } break; - default:; + default:{}; } } @@ -447,7 +447,8 @@ void java_bytecode_parsert::rconstant_pool() it++) { // the first entry isn't used - if(it==constant_pool.begin()) continue; + if(it==constant_pool.begin()) + continue; it->tag=read_u1(); @@ -520,7 +521,8 @@ void java_bytecode_parsert::rconstant_pool() it++) { // the first entry isn't used - if(it==constant_pool.begin()) continue; + if(it==constant_pool.begin()) + continue; switch(it->tag) { @@ -637,13 +639,12 @@ void java_bytecode_parsert::rconstant_pool() { it->expr.id("invokedynamic"); const pool_entryt &nameandtype_entry=pool_entry(it->ref2); - //const pool_entryt &name_entry=pool_entry(nameandtype_entry.ref1); typet type=type_entry(nameandtype_entry.ref2); it->expr.type()=type; } break; - default:; + default:{}; } } } @@ -665,7 +666,8 @@ void java_bytecode_parsert::rinterfaces(classt &parsed_class) u2 interfaces_count=read_u2(); for(std::size_t i=0; isource_location.get_line(); else if(!line_number.empty()) it->source_location.set_line(line_number); - it->source_location.set_function("java::"+ - id2string(parse_tree.parsed_class.name)+"."+ - id2string(method.name)+":"+ - method.signature); + it->source_location + .set_function( + "java::"+id2string(parse_tree.parsed_class.name)+"."+ + id2string(method.name)+":"+method.signature); } // line number of method @@ -1078,7 +1088,8 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) if(attribute_name=="LineNumberTable") { // address -> instructiont - typedef std::map instruction_mapt; + typedef std::map instruction_mapt; instruction_mapt instruction_map; for(methodt::instructionst::iterator @@ -1120,7 +1131,8 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) method.local_variable_table[i].index=index; method.local_variable_table[i].name=pool_entry(name_index).s; - method.local_variable_table[i].signature=id2string(pool_entry(descriptor_index).s); + method.local_variable_table[i].signature= + id2string(pool_entry(descriptor_index).s); method.local_variable_table[i].start_pc=start_pc; method.local_variable_table[i].length=length; } @@ -1134,96 +1146,106 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) for(size_t i=0; i already_typechecked; - std::map string_literal_to_symbol_name; - std::map escaped_string_literal_count; + std::map string_literal_to_symbol_name; + std::map escaped_string_literal_count; }; #endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_TYPECHECK_H diff --git a/src/java_bytecode/java_bytecode_typecheck_expr.cpp b/src/java_bytecode/java_bytecode_typecheck_expr.cpp index fd60c72b7dc..d1bb21eea0d 100644 --- a/src/java_bytecode/java_bytecode_typecheck_expr.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_expr.cpp @@ -30,7 +30,7 @@ void java_bytecode_typecheckt::typecheck_expr(exprt &expr) return typecheck_code(to_code(expr)); if(expr.id()==ID_typecast && expr.type().id()==ID_pointer) - expr=make_clean_pointer_cast(expr,expr.type(),ns); + expr=make_clean_pointer_cast(expr, expr.type(), ns); // do operands recursively Forall_operands(it, expr) @@ -83,7 +83,8 @@ Function: java_bytecode_typecheckt::typecheck_expr_java_new_array \*******************************************************************/ -void java_bytecode_typecheckt::typecheck_expr_java_new_array(side_effect_exprt &expr) +void java_bytecode_typecheckt::typecheck_expr_java_new_array( + side_effect_exprt &expr) { assert(expr.operands().size()>=1); // one per dimension typet &type=expr.type(); @@ -133,7 +134,7 @@ void java_bytecode_typecheckt::typecheck_expr_java_string_literal(exprt &expr) identifier_str << unique_num; irep_idt identifier_id=identifier_str.str(); - string_literal_to_symbol_name.insert(std::make_pair(value,identifier_id)); + string_literal_to_symbol_name.insert(std::make_pair(value, identifier_id)); symbolt new_symbol; new_symbol.name=identifier_id; @@ -228,13 +229,13 @@ Function: java_bytecode_typecheckt::typecheck_expr_symbol void java_bytecode_typecheckt::typecheck_expr_member(member_exprt &expr) { - // The member might be in a parent class or an opaque class, which we resolve here. + // The member might be in a parent class or an opaque class, which we resolve + // here. const irep_idt component_name=expr.get_component_name(); while(1) { - - typet &base_type = const_cast(ns.follow(expr.struct_op().type())); + typet &base_type=const_cast(ns.follow(expr.struct_op().type())); if(base_type.id()!=ID_struct) break; // give up @@ -249,10 +250,12 @@ void java_bytecode_typecheckt::typecheck_expr_member(member_exprt &expr) struct_typet::componentst &components= struct_type.components(); - if(struct_type.get_bool(ID_incomplete_class)) { - // Member doesn't exist. In this case struct_type should be an opaque + if(struct_type.get_bool(ID_incomplete_class)) + { + // member doesn't exist. In this case struct_type should be an opaque // stub, and we'll add the member to it. - components.push_back(struct_typet::componentt(component_name, expr.type())); + components + .push_back(struct_typet::componentt(component_name, expr.type())); components.back().set_base_name(component_name); components.back().set_pretty_name(component_name); return; diff --git a/src/java_bytecode/java_class_loader.cpp b/src/java_bytecode/java_class_loader.cpp index 0eca596149b..541faf6828d 100644 --- a/src/java_bytecode/java_class_loader.cpp +++ b/src/java_bytecode/java_class_loader.cpp @@ -209,7 +209,8 @@ Function: java_class_loadert::read_jar_file void java_class_loadert::read_jar_file(const irep_idt &file) { // done already? - if(jar_map.find(file)!=jar_map.end()) return; + if(jar_map.find(file)!=jar_map.end()) + return; #ifndef HAVE_LIBZIP error() << "no support for reading JAR files configured" << eom; @@ -277,7 +278,8 @@ std::string java_class_loadert::file_to_class_name(const std::string &file) // slash to dot for(std::string::iterator it=result.begin(); it!=result.end(); it++) - if(*it=='/') *it='.'; + if(*it=='/') + *it='.'; return result; } @@ -301,11 +303,13 @@ std::string java_class_loadert::class_name_to_file(const irep_idt &class_name) // dots (package name separators) to slash, depending on OS for(std::string::iterator it=result.begin(); it!=result.end(); it++) if(*it=='.') + { #ifdef _WIN32 *it='\\'; #else *it='/'; #endif + } // add .class suffix result+=".class"; diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index d5f44931b9a..e828b898d5f 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -20,7 +20,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include #include @@ -93,7 +92,7 @@ static bool should_init_symbol(const symbolt& sym) sym.mode==ID_java) return true; - if(has_prefix(id2string(sym.name),"java::java.lang.String.Literal")) + if(has_prefix(id2string(sym.name), "java::java.lang.String.Literal")) return true; return false; @@ -109,8 +108,9 @@ bool java_static_lifetime_init( symbolt &initialize_symbol=symbol_table.lookup(INITIALIZE); code_blockt &code_block=to_code_block(to_code(initialize_symbol.value)); - // we need to zero out all static variables, or nondet-initialize if they're external. - // Iterate over a copy of the symtab, as its iterators are invalidated by object_factory: + // W need to zero out all static variables, or nondet-initialize if they're + // external. Iterate over a copy of the symtab, as its iterators are + // invalidated by object_factory: std::vector symnames; symnames.reserve(symbol_table.symbols.size()); @@ -138,20 +138,21 @@ bool java_static_lifetime_init( "java::java.lang.String.Literal")) allow_null=false; } - auto newsym=object_factory(sym.type, - code_block, - allow_null, - symbol_table, - max_nondet_array_length, - source_location); - code_assignt assignment(sym.symbol_expr(), newsym); - code_block.add(assignment); + auto newsym=object_factory( + sym.type, + code_block, + allow_null, + symbol_table, + max_nondet_array_length, + source_location); + code_assignt assignment(sym.symbol_expr(), newsym); + code_block.add(assignment); } else if(sym.value.is_not_nil()) { - code_assignt assignment(sym.symbol_expr(), sym.value); - assignment.add_source_location()=source_location; - code_block.add(assignment); + code_assignt assignment(sym.symbol_expr(), sym.value); + assignment.add_source_location()=source_location; + code_block.add(assignment); } } } @@ -181,7 +182,7 @@ bool java_static_lifetime_init( static bool is_string_array(const typet& t) { typet compare_to=java_type_from_string("[Ljava.lang.String;"); - return full_eq(t,compare_to); + return full_eq(t, compare_to); } /*******************************************************************\ @@ -219,7 +220,7 @@ exprt::operandst java_build_arguments( bool is_main=is_default_entry_point; if(!is_main) { - bool named_main=has_suffix(config.main,".main"); + bool named_main=has_suffix(config.main, ".main"); bool has_correct_type= to_code_type(function.type).return_type().id()==ID_empty && (!to_code_type(function.type).has_this()) && @@ -231,10 +232,13 @@ exprt::operandst java_build_arguments( bool allow_null=(!is_main) && (!is_this) && !assume_init_pointers_not_null; main_arguments[param_number]= - object_factory(parameters[param_number].type(), - init_code, allow_null, symbol_table, - max_nondet_array_length, - function.location); + object_factory( + parameters[param_number].type(), + init_code, + allow_null, + symbol_table, + max_nondet_array_length, + function.location); const symbolt &p_symbol= symbol_table.lookup(parameters[param_number].get_identifier()); @@ -243,8 +247,9 @@ exprt::operandst java_build_arguments( codet input(ID_input); input.operands().resize(2); input.op0()=address_of_exprt( - index_exprt(string_constantt(p_symbol.base_name), - gen_zero(index_type()))); + index_exprt( + string_constantt(p_symbol.base_name), + gen_zero(index_type()))); input.op1()=main_arguments[param_number]; input.add_source_location()=function.location; @@ -289,9 +294,11 @@ void java_record_outputs( const symbolt &return_symbol=symbol_table.lookup("return'"); - output.op0()=address_of_exprt( - index_exprt(string_constantt(return_symbol.base_name), - gen_zero(index_type()))); + output.op0()= + address_of_exprt( + index_exprt( + string_constantt(return_symbol.base_name), + gen_zero(index_type()))); output.op1()=return_symbol.symbol_expr(); output.add_source_location()=function.location; @@ -310,9 +317,11 @@ void java_record_outputs( // record as an output codet output(ID_output); output.operands().resize(2); - output.op0()=address_of_exprt( - index_exprt(string_constantt(p_symbol.base_name), - gen_zero(index_type()))); + output.op0()= + address_of_exprt( + index_exprt( + string_constantt(p_symbol.base_name), + gen_zero(index_type()))); output.op1()=main_arguments[param_number]; output.add_source_location()=function.location; @@ -519,18 +528,23 @@ bool java_entry_point( return false; // silently ignore messaget message(message_handler); - main_function_resultt res = get_main_symbol(symbol_table, main_class, message_handler); + main_function_resultt res= + get_main_symbol(symbol_table, main_class, message_handler); if(res.stop_convert) return res.stop_convert; - symbolt symbol = res.main_function; + symbolt symbol=res.main_function; assert(!symbol.value.is_nil()); assert(symbol.type.id()==ID_code); create_initialize(symbol_table); - if(java_static_lifetime_init(symbol_table, symbol.location, message_handler, - assume_init_pointers_not_null, max_nondet_array_length)) + if(java_static_lifetime_init( + symbol_table, + symbol.location, + message_handler, + assume_init_pointers_not_null, + max_nondet_array_length)) return true; code_blockt init_code; @@ -559,9 +573,9 @@ bool java_entry_point( code_function_callt call_main; - source_locationt loc = symbol.location; + source_locationt loc=symbol.location; loc.set_function(symbol.name); - source_locationt &dloc = loc; + source_locationt &dloc=loc; call_main.add_source_location()=dloc; call_main.function()=symbol.symbol_expr(); @@ -581,9 +595,12 @@ bool java_entry_point( } exprt::operandst main_arguments= - java_build_arguments(symbol, init_code, symbol_table, - assume_init_pointers_not_null, - max_nondet_array_length); + java_build_arguments( + symbol, + init_code, + symbol_table, + assume_init_pointers_not_null, + max_nondet_array_length); call_main.arguments()=main_arguments; init_code.move_to_operands(call_main); diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 766d2202358..2935a411dd1 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -32,45 +32,45 @@ Function: gen_nondet_init \*******************************************************************/ -class gen_nondet_state { - - code_blockt& init_code; +class gen_nondet_statet +{ + code_blockt &init_code; std::set recursion_set; bool assume_non_null; size_t max_nondet_array_length; - symbol_tablet& symbol_table; + symbol_tablet &symbol_table; namespacet ns; public: - - gen_nondet_state(code_blockt& ic, bool ann, size_t mnal, symbol_tablet& st) : + gen_nondet_statet(code_blockt& ic, bool ann, size_t mnal, symbol_tablet& st) : init_code(ic), assume_non_null(ann), max_nondet_array_length(mnal), symbol_table(st), ns(st) {} - exprt allocate_object(const exprt&, const typet&, - const source_locationt &, - bool create_dynamic_objects); + exprt allocate_object( + const exprt&, + const typet&, + const source_locationt &, + bool create_dynamic_objects); void gen_nondet_array_init(const exprt &expr, const source_locationt &); - void gen_nondet_init(const exprt &expr, - bool is_sub, - irep_idt class_identifier, - const source_locationt &loc, - bool skip_classid, - bool create_dynamic_objects, - const typet *override_type = 0); - - + void gen_nondet_init( + const exprt &expr, + bool is_sub, + irep_idt class_identifier, + const source_locationt &loc, + bool skip_classid, + bool create_dynamic_objects, + const typet *override_type=0); }; // Returns false if we can't figure out the size of allocate_type. // allocate_type may differ from target_expr, e.g. for target_expr having // type int* and allocate_type being an int[10]. -exprt gen_nondet_state::allocate_object( +exprt gen_nondet_statet::allocate_object( const exprt& target_expr, const typet& allocate_type, const source_locationt &loc, @@ -89,7 +89,7 @@ exprt gen_nondet_state::allocate_object( exprt aoe=address_of_exprt(object); if(cast_needed) aoe=typecast_exprt(aoe, target_expr.type()); - code_assignt code(target_expr,aoe); + code_assignt code(target_expr, aoe); code.add_source_location()=loc; init_code.copy_to_operands(code); return aoe; @@ -102,24 +102,24 @@ exprt gen_nondet_state::allocate_object( if(allocate_type.id()!=ID_empty && !object_size.is_nil()) { // malloc expression - exprt malloc_expr = side_effect_exprt(ID_malloc); + exprt malloc_expr=side_effect_exprt(ID_malloc); malloc_expr.copy_to_operands(object_size); typet result_type=pointer_typet(allocate_type); malloc_expr.type()=result_type; // Create a symbol for the malloc expression so we can initialise // without having to do it potentially through a double-deref, which // breaks the to-SSA phase. - symbolt &malloc_sym=new_tmp_symbol(symbol_table,"malloc_site"); + symbolt &malloc_sym=new_tmp_symbol(symbol_table, "malloc_site"); malloc_sym.type=pointer_typet(allocate_type); - code_assignt assign = code_assignt(malloc_sym.symbol_expr(), malloc_expr); - code_assignt &malloc_assign = assign; - malloc_assign.add_source_location() = loc; + code_assignt assign=code_assignt(malloc_sym.symbol_expr(), malloc_expr); + code_assignt &malloc_assign=assign; + malloc_assign.add_source_location()=loc; init_code.copy_to_operands(malloc_assign); malloc_expr=malloc_sym.symbol_expr(); if(cast_needed) - malloc_expr=typecast_exprt(malloc_expr,target_expr.type()); + malloc_expr=typecast_exprt(malloc_expr, target_expr.type()); code_assignt code(target_expr, malloc_expr); - code.add_source_location() = loc; + code.add_source_location()=loc; init_code.copy_to_operands(code); return malloc_sym.symbol_expr(); } @@ -128,7 +128,7 @@ exprt gen_nondet_state::allocate_object( // make null null_pointer_exprt null_pointer_expr(to_pointer_type(target_expr.type())); code_assignt code(target_expr, null_pointer_expr); - code.add_source_location() = loc; + code.add_source_location()=loc; init_code.copy_to_operands(code); return exprt(); } @@ -136,9 +136,10 @@ exprt gen_nondet_state::allocate_object( } // Override type says to ignore the LHS' real type, and init it with the given -// type regardless. Used at the moment for reference arrays, which are implemented -// as void* arrays but should be init'd as their true type with appropriate casts. -void gen_nondet_state::gen_nondet_init( +// type regardless. Used at the moment for reference arrays, which are +// implemented as void* arrays but should be init'd as their true type with +// appropriate casts. +void gen_nondet_statet::gen_nondet_init( const exprt &expr, bool is_sub, irep_idt class_identifier, @@ -166,7 +167,7 @@ void gen_nondet_state::gen_nondet_init( // make null null_pointer_exprt null_pointer_expr(pointer_type); code_assignt code(expr, null_pointer_expr); - code.add_source_location() = loc; + code.add_source_location()=loc; init_code.copy_to_operands(code); return; @@ -181,29 +182,32 @@ void gen_nondet_state::gen_nondet_init( if(!assume_non_null) { auto returns_null_sym= - new_tmp_symbol(symbol_table,"opaque_returns_null"); + new_tmp_symbol(symbol_table, "opaque_returns_null"); returns_null_sym.type=c_bool_typet(1); auto returns_null=returns_null_sym.symbol_expr(); auto assign_returns_null= - code_assignt(returns_null,get_nondet_bool(returns_null_sym.type)); - assign_returns_null.add_source_location() = loc; + code_assignt(returns_null, get_nondet_bool(returns_null_sym.type)); + assign_returns_null.add_source_location()=loc; init_code.move_to_operands(assign_returns_null); - auto set_null_inst=code_assignt( - expr,null_pointer_exprt(pointer_type)); - set_null_inst.add_source_location() = loc; + auto set_null_inst= + code_assignt(expr, null_pointer_exprt(pointer_type)); + set_null_inst.add_source_location()=loc; std::ostringstream fresh_label_oss; fresh_label_oss<<"post_synthetic_malloc_" <<(++synthetic_constructor_count); std::string fresh_label=fresh_label_oss.str(); - set_null_label=code_labelt(fresh_label,set_null_inst); + set_null_label=code_labelt(fresh_label, set_null_inst); - init_done_label=code_labelt(fresh_label + "_init_done",code_skipt()); + init_done_label=code_labelt(fresh_label+"_init_done", code_skipt()); - code_ifthenelset null_check; - null_check.cond()=notequal_exprt( - returns_null,constant_exprt("0",returns_null_sym.type)); + code_ifthenelset + null_check; + null_check.cond()= + notequal_exprt( + returns_null, + constant_exprt("0", returns_null_sym.type)); null_check.then_case()=code_gotot(fresh_label); init_code.move_to_operands(null_check); } @@ -213,15 +217,23 @@ void gen_nondet_state::gen_nondet_init( { gen_nondet_array_init(expr, loc); } - else { - exprt allocated=allocate_object(expr,subtype,loc,create_dynamic_objects); + else + { + exprt allocated= + allocate_object(expr, subtype, loc, create_dynamic_objects); { exprt init_expr; if(allocated.id()==ID_address_of) init_expr=allocated.op0(); else - init_expr=dereference_exprt(allocated,allocated.type().subtype()); - gen_nondet_init(init_expr,false,"",loc,false,create_dynamic_objects); + init_expr=dereference_exprt(allocated, allocated.type().subtype()); + gen_nondet_init( + init_expr, + false, + "", + loc, + false, + create_dynamic_objects); } } @@ -231,7 +243,6 @@ void gen_nondet_state::gen_nondet_init( init_code.move_to_operands(set_null_label); init_code.move_to_operands(init_done_label); } - } else if(type.id()==ID_struct) { @@ -257,33 +268,38 @@ void gen_nondet_state::gen_nondet_init( if(name=="@class_identifier") { - if(skip_classid) - continue; + if(skip_classid) + continue; irep_idt qualified_clsid="java::"+as_string(class_identifier); - constant_exprt ci(qualified_clsid,string_typet()); - - code_assignt code(me, ci); - code.add_source_location() = loc; - init_code.copy_to_operands(code); + constant_exprt ci(qualified_clsid, string_typet()); + code_assignt code(me, ci); + code.add_source_location()=loc; + init_code.copy_to_operands(code); } else if(name=="@lock") { code_assignt code(me, gen_zero(me.type())); - code.add_source_location() = loc; + code.add_source_location()=loc; init_code.copy_to_operands(code); } else { assert(!name.empty()); - bool _is_sub = name[0]=='@'; + bool _is_sub=name[0]=='@'; #if 0 irep_idt _class_identifier= _is_sub?(class_identifier.empty()?struct_tag:class_identifier):""; #endif - gen_nondet_init(me, _is_sub, class_identifier, loc, false, create_dynamic_objects); + gen_nondet_init( + me, + _is_sub, + class_identifier, + loc, + false, + create_dynamic_objects); } } recursion_set.erase(struct_tag); @@ -293,116 +309,133 @@ void gen_nondet_state::gen_nondet_init( side_effect_expr_nondett se=side_effect_expr_nondett(type); code_assignt code(expr, se); - code.add_source_location() = loc; + code.add_source_location()=loc; init_code.copy_to_operands(code); } } -// Borrowed from java_bytecode_convert.cpp -- todo find a sensible place to factor this. +// Borrowed from java_bytecode_convert.cpp -- todo find a sensible place to +// factor this. static constant_exprt as_number(const mp_integer value, const typet &type) { const size_t java_int_width(type.get_unsigned_int(ID_width)); const std::string significant_bits(integer2string(value, 2)); - std::string binary_width(java_int_width - significant_bits.length(), '0'); - return constant_exprt(binary_width += significant_bits, type); + std::string binary_width(java_int_width-significant_bits.length(), '0'); + return constant_exprt(binary_width+significant_bits, type); } -void gen_nondet_state::gen_nondet_array_init(const exprt &expr, const source_locationt &loc) +void gen_nondet_statet::gen_nondet_array_init( + const exprt &expr, + const source_locationt &loc) { assert(expr.type().id()==ID_pointer); const typet &type=ns.follow(expr.type().subtype()); const struct_typet &struct_type=to_struct_type(type); - assert(expr.type().subtype().id() == ID_symbol); - const typet &element_type=static_cast(expr.type().subtype().find(ID_C_element_type)); + assert(expr.type().subtype().id()==ID_symbol); + const typet &element_type= + static_cast(expr.type().subtype().find(ID_C_element_type)); - auto max_length_expr=as_number(max_nondet_array_length,java_int_type()); + auto max_length_expr=as_number(max_nondet_array_length, java_int_type()); typet allocate_type; - symbolt &length_sym=new_tmp_symbol(symbol_table,"nondet_array_length"); + symbolt &length_sym=new_tmp_symbol(symbol_table, "nondet_array_length"); length_sym.type=java_int_type(); const auto &length_sym_expr=length_sym.symbol_expr(); // Initialise array with some undetermined length: - gen_nondet_init(length_sym_expr,false,irep_idt(),loc,false,false); + gen_nondet_init(length_sym_expr, false, irep_idt(), loc, false, false); // Insert assumptions to bound its length: - binary_relation_exprt assume1(length_sym_expr,ID_ge, - as_number(0, java_int_type())); - binary_relation_exprt assume2(length_sym_expr,ID_le, - max_length_expr); + binary_relation_exprt + assume1(length_sym_expr, ID_ge, as_number(0, java_int_type())); + binary_relation_exprt + assume2(length_sym_expr, ID_le, max_length_expr); code_assumet assume_inst1(assume1); code_assumet assume_inst2(assume2); init_code.move_to_operands(assume_inst1); init_code.move_to_operands(assume_inst2); - side_effect_exprt java_new_array(ID_java_new_array,expr.type()); + side_effect_exprt java_new_array(ID_java_new_array, expr.type()); java_new_array.copy_to_operands(length_sym_expr); - java_new_array.set("skip_initialise",true); - java_new_array.type().subtype().set(ID_C_element_type,element_type); - codet assign = code_assignt(expr,java_new_array); + java_new_array.set("skip_initialise", true); + java_new_array.type().subtype().set(ID_C_element_type, element_type); + codet assign=code_assignt(expr, java_new_array); assign.add_source_location()=loc; init_code.copy_to_operands(assign); - exprt init_array_expr=member_exprt(dereference_exprt(expr, expr.type().subtype()), - "data", struct_type.components()[2].type()); + exprt init_array_expr= + member_exprt( + dereference_exprt(expr, expr.type().subtype()), + "data", + struct_type.components()[2].type()); if(init_array_expr.type()!=pointer_typet(element_type)) - init_array_expr=typecast_exprt(init_array_expr,pointer_typet(element_type)); + init_array_expr= + typecast_exprt(init_array_expr, pointer_typet(element_type)); - // Interpose a new symbol, as the goto-symex stage can't handle array indexing via a cast. - symbolt &array_init_symbol=new_tmp_symbol(symbol_table,"array_data_init"); + // Interpose a new symbol, as the goto-symex stage can't handle array indexing + // via a cast. + symbolt &array_init_symbol=new_tmp_symbol(symbol_table, "array_data_init"); array_init_symbol.type=init_array_expr.type(); const auto &array_init_symexpr=array_init_symbol.symbol_expr(); - codet data_assign = code_assignt(array_init_symexpr,init_array_expr); - data_assign.add_source_location() = loc; + codet data_assign=code_assignt(array_init_symexpr, init_array_expr); + data_assign.add_source_location()=loc; init_code.copy_to_operands(data_assign); - // Emit init loop for(array_init_iter=0; array_init_iter!=array.length; ++array_init_iter) - // init(array[array_init_iter]); - symbolt &counter=new_tmp_symbol(symbol_table,"array_init_iter"); + // Emit init loop for(array_init_iter=0; array_init_iter!=array.length; + // ++array_init_iter) init(array[array_init_iter]); + symbolt &counter=new_tmp_symbol(symbol_table, "array_init_iter"); counter.type=length_sym_expr.type(); exprt counter_expr=counter.symbol_expr(); init_code.copy_to_operands( - code_assignt(counter_expr,as_number(0, java_int_type()))); + code_assignt(counter_expr, as_number(0, java_int_type()))); std::string head_name=as_string(counter.base_name)+"_header"; - code_labelt init_head_label(head_name,code_skipt()); + code_labelt init_head_label(head_name, code_skipt()); code_gotot goto_head(head_name); init_code.move_to_operands(init_head_label); std::string done_name=as_string(counter.base_name)+"_done"; - code_labelt init_done_label(done_name,code_skipt()); + code_labelt init_done_label(done_name, code_skipt()); code_gotot goto_done(done_name); - code_ifthenelset done_test; - done_test.cond()=equal_exprt(counter_expr,length_sym_expr); + code_ifthenelset + done_test; + done_test.cond()=equal_exprt(counter_expr, length_sym_expr); done_test.then_case()=goto_done; init_code.move_to_operands(done_test); - // Add a redundant if(counter == max_length) break that is easier for the unwinder to understand. - code_ifthenelset max_test; - max_test.cond()=equal_exprt(counter_expr,max_length_expr); + // Add a redundant if(counter == max_length) break that is easier for the + // unwinder to understand. + code_ifthenelset + max_test; + max_test.cond()=equal_exprt(counter_expr, max_length_expr); max_test.then_case()=goto_done; init_code.move_to_operands(max_test); exprt arraycellref=dereference_exprt( - plus_exprt(array_init_symexpr,counter_expr,array_init_symexpr.type()), + plus_exprt(array_init_symexpr, counter_expr, array_init_symexpr.type()), array_init_symexpr.type().subtype()); - gen_nondet_init(arraycellref,false,irep_idt(),loc,false,true, - /*override_type=*/&element_type); + gen_nondet_init( + arraycellref, + false, + irep_idt(), + loc, + false, + true, + /*override_type=*/&element_type); - code_assignt incr(counter_expr, - plus_exprt(counter_expr, - as_number(1, java_int_type()))); + code_assignt incr( + counter_expr, + plus_exprt(counter_expr, as_number(1, java_int_type()))); init_code.move_to_operands(incr); init_code.move_to_operands(goto_head); init_code.move_to_operands(init_done_label); - } @@ -424,13 +457,16 @@ void gen_nondet_init( symbol_tablet &symbol_table, const source_locationt &loc, bool skip_classid, - bool create_dynamic_objects, + bool create_dyn_objs, bool assume_non_null, size_t max_nondet_array_length) { - gen_nondet_state state(init_code,assume_non_null,max_nondet_array_length, - symbol_table); - state.gen_nondet_init(expr,false,"",loc,skip_classid,create_dynamic_objects); + gen_nondet_statet state( + init_code, + assume_non_null, + max_nondet_array_length, + symbol_table); + state.gen_nondet_init(expr, false, "", loc, skip_classid, create_dyn_objs); } /*******************************************************************\ @@ -457,7 +493,8 @@ symbolt &new_tmp_symbol(symbol_tablet &symbol_table, const std::string& prefix) new_symbol.name="tmp_object_factory$"+std::to_string(++temporary_counter); new_symbol.base_name=new_symbol.name; new_symbol.mode=ID_java; - } while(symbol_table.move(new_symbol, symbol_ptr)); + } + while(symbol_table.move(new_symbol, symbol_ptr)); return *symbol_ptr; } @@ -474,7 +511,8 @@ Function: get_nondet_bool \*******************************************************************/ -exprt get_nondet_bool(const typet& type) { +exprt get_nondet_bool(const typet& type) +{ // We force this to 0 and 1 and won't consider // other values. return typecast_exprt(side_effect_expr_nondett(bool_typet()), type); @@ -509,9 +547,15 @@ exprt object_factory( exprt object=aux_symbol.symbol_expr(); const namespacet ns(symbol_table); - gen_nondet_init(object, init_code, symbol_table, loc, - false, false, !allow_null, - max_nondet_array_length); + gen_nondet_init( + object, + init_code, + symbol_table, + loc, + false, + false, + !allow_null, + max_nondet_array_length); return object; } diff --git a/src/java_bytecode/java_object_factory.h b/src/java_bytecode/java_object_factory.h index 5e8d4417ad5..a868a2ae200 100644 --- a/src/java_bytecode/java_object_factory.h +++ b/src/java_bytecode/java_object_factory.h @@ -25,15 +25,15 @@ void gen_nondet_init( code_blockt &init_code, symbol_tablet &symbol_table, const source_locationt &, - bool skip_classid = false, - bool create_dynamic_objects = false, - bool assume_non_null = false, - size_t max_nondet_array_length = 5); + bool skip_classid=false, + bool create_dynamic_objects=false, + bool assume_non_null=false, + size_t max_nondet_array_length=5); exprt get_nondet_bool(const typet&); symbolt &new_tmp_symbol( symbol_tablet &symbol_table, - const std::string& prefix = "tmp_object_factory"); + const std::string& prefix="tmp_object_factory"); #endif // CPROVER_JAVA_BYTECODE_JAVA_OBJECT_FACTORY_H diff --git a/src/java_bytecode/java_pointer_casts.cpp b/src/java_bytecode/java_pointer_casts.cpp index 483e0287467..b8a569f55f4 100644 --- a/src/java_bytecode/java_pointer_casts.cpp +++ b/src/java_bytecode/java_pointer_casts.cpp @@ -45,13 +45,13 @@ Function: find_superclass_with_type \*******************************************************************/ -bool find_superclass_with_type(exprt &ptr,const typet &target_type, - const namespacet &ns) +bool find_superclass_with_type( + exprt &ptr, + const typet &target_type, + const namespacet &ns) { - while(true) { - const typet ptr_base=ns.follow(ptr.type().subtype()); if(ptr_base.id()!=ID_struct) @@ -65,8 +65,10 @@ bool find_superclass_with_type(exprt &ptr,const typet &target_type, const typet &first_field_type= ns.follow(base_struct.components()[0].type()); ptr=clean_deref(ptr); - ptr=member_exprt(ptr,base_struct.components()[0].get_name(), - first_field_type); + ptr=member_exprt( + ptr, + base_struct.components()[0].get_name(), + first_field_type); ptr=address_of_exprt(ptr); if(first_field_type==target_type) @@ -94,9 +96,8 @@ static const exprt& look_through_casts(const exprt& in) assert(in.type().id()==ID_pointer); return look_through_casts(in.op0()); } - else { + else return in; - } } @@ -114,12 +115,14 @@ Function: make_clean_pointer_cast \*******************************************************************/ -exprt make_clean_pointer_cast(const exprt &rawptr,const typet &target_type, - const namespacet &ns) +exprt make_clean_pointer_cast( + const exprt &rawptr, + const typet &target_type, + const namespacet &ns) { - - assert(target_type.id()==ID_pointer && - "Non-pointer target in make_clean_pointer_cast?"); + assert( + target_type.id()==ID_pointer && + "Non-pointer target in make_clean_pointer_cast?"); const exprt &ptr=look_through_casts(rawptr); @@ -128,28 +131,30 @@ exprt make_clean_pointer_cast(const exprt &rawptr,const typet &target_type, if(ptr.type().subtype()==empty_typet() || target_type.subtype()==empty_typet()) - return typecast_exprt(ptr,target_type); + return typecast_exprt(ptr, target_type); const typet &target_base=ns.follow(target_type.subtype()); exprt bare_ptr=ptr; while(bare_ptr.id()==ID_typecast) { - assert(bare_ptr.type().id()==ID_pointer && - "Non-pointer in make_clean_pointer_cast?"); + assert( + bare_ptr.type().id()==ID_pointer && + "Non-pointer in make_clean_pointer_cast?"); if(bare_ptr.type().subtype()==empty_typet()) bare_ptr=bare_ptr.op0(); } - assert(bare_ptr.type().id()==ID_pointer && - "Non-pointer in make_clean_pointer_cast?"); + assert( + bare_ptr.type().id()==ID_pointer && + "Non-pointer in make_clean_pointer_cast?"); if(bare_ptr.type()==target_type) return bare_ptr; exprt superclass_ptr=bare_ptr; - if(find_superclass_with_type(superclass_ptr,target_base,ns)) + if(find_superclass_with_type(superclass_ptr, target_base, ns)) return superclass_ptr; - return typecast_exprt(bare_ptr,target_type); + return typecast_exprt(bare_ptr, target_type); } diff --git a/src/util/json_expr.cpp b/src/util/json_expr.cpp index 5fbb4325607..4d9f7b5aa54 100644 --- a/src/util/json_expr.cpp +++ b/src/util/json_expr.cpp @@ -46,7 +46,8 @@ json_objectt json(const source_locationt &location) result["function"]=json_stringt(id2string(location.get_function())); if(!location.get_java_bytecode_index().empty()) - result["bytecode_index"]=json_stringt(id2string(location.get_java_bytecode_index())); + result["bytecode_index"]= + json_stringt(id2string(location.get_java_bytecode_index())); return result; } @@ -81,12 +82,14 @@ json_objectt json( else if(type.id()==ID_signedbv) { result["name"]=json_stringt("integer"); - result["width"]=json_numbert(std::to_string(to_signedbv_type(type).get_width())); + result["width"]= + json_numbert(std::to_string(to_signedbv_type(type).get_width())); } else if(type.id()==ID_floatbv) { result["name"]=json_stringt("float"); - result["width"]=json_numbert(std::to_string(to_floatbv_type(type).get_width())); + result["width"]= + json_numbert(std::to_string(to_floatbv_type(type).get_width())); } else if(type.id()==ID_bv) { @@ -107,7 +110,8 @@ json_objectt json( else if(type.id()==ID_fixedbv) { result["name"]=json_stringt("fixed"); - result["width"]=json_numbert(std::to_string(to_fixedbv_type(type).get_width())); + result["width"]= + json_numbert(std::to_string(to_fixedbv_type(type).get_width())); } else if(type.id()==ID_pointer) { diff --git a/src/util/source_location.cpp b/src/util/source_location.cpp index 8f8b16e3970..7583b40b496 100644 --- a/src/util/source_location.cpp +++ b/src/util/source_location.cpp @@ -35,18 +35,39 @@ std::string source_locationt::as_string(bool print_cwd) const if(!file.empty()) { - if(dest!="") dest+=' '; + if(dest!="") + dest+=' '; dest+="file "; if(print_cwd) - dest+=concat_dir_file(id2string(get_working_directory()), - id2string(file)); + dest+= + concat_dir_file(id2string(get_working_directory()), id2string(file)); else dest+=id2string(file); } - if(!line.empty()) { if(dest!="") dest+=' '; dest+="line "+id2string(line); } - if(!column.empty()) { if(dest!="") dest+=' '; dest+="column "+id2string(column); } - if(!function.empty()) { if(dest!="") dest+=' '; dest+="function "+id2string(function); } - if(!bytecode.empty()) { if(dest!="") dest+=' '; dest+="bytecode_index "+id2string(bytecode); } + if(!line.empty()) + { + if(dest!="") + dest+=' '; + dest+="line "+id2string(line); + } + if(!column.empty()) + { + if(dest!="") + dest+=' '; + dest+="column "+id2string(column); + } + if(!function.empty()) + { + if(dest!="") + dest+=' '; + dest+="function "+id2string(function); + } + if(!bytecode.empty()) + { + if(dest!="") + dest+=' '; + dest+="bytecode_index "+id2string(bytecode); + } return dest; } @@ -67,9 +88,8 @@ std::ostream &operator << ( std::ostream &out, const source_locationt &source_location) { - if(source_location.is_nil()) return out; - + if(source_location.is_nil()) + return out; out << source_location.as_string(); - return out; } diff --git a/src/util/source_location.h b/src/util/source_location.h index 83a79a8f03d..8d1e297b535 100644 --- a/src/util/source_location.h +++ b/src/util/source_location.h @@ -147,9 +147,6 @@ class source_locationt:public irept std::string as_string(bool print_cwd) const; }; -// will go away -//typedef source_locationt locationt; - std::ostream &operator <<(std::ostream &, const source_locationt &); #endif // CPROVER_UTIL_SOURCE_LOCATION_H From b8cc2940357f82b364e07125a144195d13664f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 13 Jan 2017 23:35:20 +0100 Subject: [PATCH 071/166] take comments into account --- src/java_bytecode/expr2java.cpp | 2 +- .../java_bytecode_convert_class.cpp | 6 ++--- .../java_bytecode_convert_class.h | 2 +- .../java_bytecode_convert_method.cpp | 22 +++++++++---------- src/java_bytecode/java_bytecode_language.h | 2 +- src/java_bytecode/java_bytecode_parser.cpp | 2 +- src/java_bytecode/java_entry_point.cpp | 4 ++-- src/java_bytecode/java_types.cpp | 6 ++--- src/util/irep_ids.txt | 1 + 9 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/java_bytecode/expr2java.cpp b/src/java_bytecode/expr2java.cpp index 47e21d2f9c7..505e7425921 100644 --- a/src/java_bytecode/expr2java.cpp +++ b/src/java_bytecode/expr2java.cpp @@ -506,7 +506,7 @@ std::string expr2javat::convert( ")"; } else if(src.id()==ID_java_string_literal) - return '"'+id2string(src.get(ID_value))+'"'; // Todo: add escaping as needed + return '"'+id2string(src.get(ID_value))+'"'; // TODO: add escaping as needed else if(src.id()==ID_constant && (type.id()==ID_bool || type.id()==ID_c_bool)) { if(src.is_true()) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 295d7bfb367..320f3a95ba9 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -26,7 +26,7 @@ class java_bytecode_convert_classt:public messaget java_bytecode_convert_classt( symbol_tablet &_symbol_table, message_handlert &_message_handler, - const bool _disable_runtime_checks, + bool _disable_runtime_checks, size_t _max_array_length): messaget(_message_handler), symbol_table(_symbol_table), @@ -51,7 +51,7 @@ class java_bytecode_convert_classt:public messaget protected: symbol_tablet &symbol_table; const bool disable_runtime_checks; - size_t max_array_length; + const size_t max_array_length; // conversion void convert(const classt &c); @@ -312,7 +312,7 @@ bool java_bytecode_convert_class( const java_bytecode_parse_treet &parse_tree, symbol_tablet &symbol_table, message_handlert &message_handler, - const bool disable_runtime_checks, + bool disable_runtime_checks, size_t max_array_length) { java_bytecode_convert_classt java_bytecode_convert_class( diff --git a/src/java_bytecode/java_bytecode_convert_class.h b/src/java_bytecode/java_bytecode_convert_class.h index 264df6ca9df..ffaaf6e34da 100644 --- a/src/java_bytecode/java_bytecode_convert_class.h +++ b/src/java_bytecode/java_bytecode_convert_class.h @@ -18,7 +18,7 @@ bool java_bytecode_convert_class( const java_bytecode_parse_treet &parse_tree, symbol_tablet &symbol_table, message_handlert &message_handler, - const bool disable_runtime_checks, + bool disable_runtime_checks, size_t max_array_length); #endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_CONVERT_CLASS_H diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index c54f4f235f8..09d02b5dc58 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -1882,12 +1882,12 @@ codet java_bytecode_convert_methodt::convert_instructions( { assert(op.empty() && results.size()==1); symbol_exprt symbol_expr(arg0.type()); - const auto& fieldname=arg0.get_string(ID_component_name); - symbol_expr.set_identifier(arg0.get_string(ID_class)+"."+fieldname); + const auto& field_name=arg0.get_string(ID_component_name); + symbol_expr.set_identifier(arg0.get_string(ID_class)+"."+field_name); results[0]=java_bytecode_promotion(symbol_expr); // set $assertionDisabled to false - if(fieldname.find("$assertionsDisabled")!=std::string::npos) + if(field_name.find("$assertionsDisabled")!=std::string::npos) { exprt e; e.make_false(); @@ -1903,8 +1903,8 @@ codet java_bytecode_convert_methodt::convert_instructions( { assert(op.size()==1 && results.empty()); symbol_exprt symbol_expr(arg0.type()); - const auto& fieldname=arg0.get_string(ID_component_name); - symbol_expr.set_identifier(arg0.get_string(ID_class)+"."+fieldname); + const auto& field_name=arg0.get_string(ID_component_name); + symbol_expr.set_identifier(arg0.get_string(ID_class)+"."+field_name); c=code_assignt(symbol_expr, op[0]); } else if(statement==patternt("?2?")) // i2c etc. @@ -1968,7 +1968,7 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!i_it->source_location.get_line().empty()) java_new_array.add_source_location()=i_it->source_location; - code_blockt checkandcreate; + code_blockt check_and_create; if(!disable_runtime_checks) { // TODO make this throw NegativeArrayIndexException instead. @@ -1978,18 +1978,18 @@ codet java_bytecode_convert_methodt::convert_instructions( check.add_source_location().set_comment("Array size < 0"); check.add_source_location() .set_property_class("array-create-negative-size"); - checkandcreate.move_to_operands(check); + check_and_create.move_to_operands(check); } if(max_array_length!=0) { constant_exprt size_limit=as_number(max_array_length, java_int_type()); binary_relation_exprt le_max_size(op[0], ID_le, size_limit); code_assumet assume_le_max_size(le_max_size); - checkandcreate.move_to_operands(assume_le_max_size); + check_and_create.move_to_operands(assume_le_max_size); } const exprt tmp=tmp_variable("newarray", ref_type); - checkandcreate.copy_to_operands(code_assignt(tmp, java_new_array)); - c=std::move(checkandcreate); + check_and_create.copy_to_operands(code_assignt(tmp, java_new_array)); + c=std::move(check_and_create); results[0]=tmp; } else if(statement=="multianewarray") @@ -2109,7 +2109,7 @@ codet java_bytecode_convert_methodt::convert_instructions( assert(op.size()==1 && results.size()==1); results[0]= - binary_predicate_exprt(op[0], "java_instanceof", arg0); + binary_predicate_exprt(op[0], ID_java_instanceof, arg0); } else if(statement=="monitorenter") { diff --git a/src/java_bytecode/java_bytecode_language.h b/src/java_bytecode/java_bytecode_language.h index dbbc945ccaf..834f6d60544 100644 --- a/src/java_bytecode/java_bytecode_language.h +++ b/src/java_bytecode/java_bytecode_language.h @@ -78,7 +78,7 @@ class java_bytecode_languaget:public languaget // - array bounds check // - array size for newarray size_t max_nondet_array_length; // maximal length for non-det array creation - size_t max_user_array_length; // max size for user supplied arrays + size_t max_user_array_length; // max size for user code created arrays }; languaget *new_java_bytecode_language(); diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index f2e14888d10..c025a4ad268 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -946,7 +946,7 @@ void java_bytecode_parsert::rbytecode( break; default: - assert(false && "unknown instruction"); + throw "unknown JVM bytecode instruction"; } bytecode_index++; } diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index e828b898d5f..ebca33adc21 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -463,7 +463,7 @@ main_function_resultt get_main_symbol( if(matches.empty()) { // Not found, silently ignore - res.main_function=symbol; + res.main_function=symbolt(); res.error_found=false; res.stop_convert=true; return res; @@ -473,7 +473,7 @@ main_function_resultt get_main_symbol( { message.error() << "main method in `" << main_class << "' is ambiguous" << messaget::eom; - res.main_function=symbol; + res.main_function=symbolt(); res.error_found=true; res.stop_convert=true; return res; // give up with error, no main diff --git a/src/java_bytecode/java_types.cpp b/src/java_bytecode/java_types.cpp index 88fc91d1587..cd3d23b22bd 100644 --- a/src/java_bytecode/java_types.cpp +++ b/src/java_bytecode/java_types.cpp @@ -7,7 +7,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ #include -#include +#include #include #include @@ -392,8 +392,8 @@ typet java_type_from_string(const std::string &src) const typet subtype=java_type_from_string(src.substr(1, std::string::npos)); if(subtype_letter=='L' || // [L denotes a reference array of some sort. subtype_letter=='[') // Array-of-arrays - subtype_letter='A'; - typet tmp=java_array_type((char)tolower(subtype_letter)); + subtype_letter='A'; + typet tmp=java_array_type(std::tolower(subtype_letter)); tmp.subtype().set(ID_C_element_type, subtype); return tmp; } diff --git a/src/util/irep_ids.txt b/src/util/irep_ids.txt index 95cb32a2480..e6f70ccbf37 100644 --- a/src/util/irep_ids.txt +++ b/src/util/irep_ids.txt @@ -734,3 +734,4 @@ low high bswap java_bytecode_index +java_instanceof From 6ea64f11a31fae8f6bd0f318d44ee24fdc984a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Sun, 15 Jan 2017 21:35:04 +0100 Subject: [PATCH 072/166] fix linter warnings after rebase --- .../java_bytecode_convert_method.cpp | 51 ++++++++++--------- src/java_bytecode/java_object_factory.cpp | 14 +++-- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 09d02b5dc58..f92208a1d8f 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -1017,11 +1017,9 @@ codet java_bytecode_convert_methodt::convert_instructions( i_it!=instructions.end(); i_it++) { + converted_instructiont ins=converted_instructiont(i_it, code_skipt()); std::pair a_entry= - address_map.insert( - std::make_pair( - i_it->address, - converted_instructiont(i_it, code_skipt()))); + address_map.insert(std::make_pair(i_it->address, ins)); assert(a_entry.second); // addresses are strictly increasing, hence we must have inserted // a new maximal key @@ -1060,7 +1058,9 @@ codet java_bytecode_convert_methodt::convert_instructions( i_it->statement=="jsr_w") { instructionst::const_iterator next=i_it; - assert(++next!=instructions.end() && "jsr without valid return address?"); + assert( + ++next!=instructions.end() && + "jsr without valid return address?"); targets.insert(next->address); jsr_ret_targets.push_back(next->address); } @@ -1088,12 +1088,11 @@ codet java_bytecode_convert_methodt::convert_instructions( } } - // Draw edges from every `ret` to every `jsr` successor. - // Could do better with flow analysis to distinguish multiple subroutines within - // the same function. + // Draw edges from every `ret` to every `jsr` successor. Could do better with + // flow analysis to distinguish multiple subroutines within the same function. for(const auto retinst : ret_instructions) { - auto& a_entry=address_map.at(retinst->address); + auto &a_entry=address_map.at(retinst->address); a_entry.successors.insert( a_entry.successors.end(), jsr_ret_targets.begin(), @@ -1529,7 +1528,8 @@ codet java_bytecode_convert_methodt::convert_instructions( branches.move_to_operands(g); else { - code_ifthenelset branch; + code_ifthenelset + branch; auto address_ptr=as_number( jsr_ret_targets[idx], pointer_typet(void_typet(), 64)); @@ -1558,9 +1558,8 @@ codet java_bytecode_convert_methodt::convert_instructions( if(is_double || is_float) { const ieee_float_spect spec( - is_float? - ieee_float_spect::single_precision(): - ieee_float_spect::double_precision()); + is_float?ieee_float_spect::single_precision(): + ieee_float_spect::double_precision()); ieee_floatt value(spec); const typet &arg_type(arg0.type()); @@ -1752,15 +1751,19 @@ codet java_bytecode_convert_methodt::convert_instructions( // 1 if op[0] is greater than op[1] const typet t=java_int_type(); + exprt one=from_integer(1, t); + exprt minus_one=from_integer(-1, t); + + if_exprt greater=if_exprt( + binary_relation_exprt(op[0], ID_gt, op[1]), + one, + minus_one); results[0]= if_exprt( binary_relation_exprt(op[0], ID_equal, op[1]), gen_zero(t), - if_exprt( - binary_relation_exprt(op[0], ID_gt, op[1]), - from_integer(1, t), - from_integer(-1, t))); + greater); } else if(statement==patternt("?cmp?")) { @@ -1779,19 +1782,21 @@ codet java_bytecode_convert_methodt::convert_instructions( // (value1 == NaN || value2 == NaN) ? // nan_value : value1 == value2 ? 0 : value1 < value2 -1 ? 1 : 0; + exprt nan_op0=ieee_float_equal_exprt(nan_expr, op[0]); + exprt nan_op1=ieee_float_equal_exprt(nan_expr, op[1]); + exprt one=from_integer(1, result_type); + exprt minus_one=from_integer(-1, result_type); results[0]= if_exprt( - or_exprt( - ieee_float_equal_exprt(nan_expr, op[0]), - ieee_float_equal_exprt(nan_expr, op[1])), + or_exprt(nan_op0, nan_op1), nan_result, if_exprt( ieee_float_equal_exprt(op[0], op[1]), gen_zero(result_type), if_exprt( binary_relation_exprt(op[0], ID_lt, op[1]), - from_integer(-1, result_type), - from_integer(1, result_type)))); + minus_one, + one))); } else if(statement==patternt("?cmpl")) { @@ -2200,7 +2205,7 @@ codet java_bytecode_convert_methodt::convert_instructions( else { c.make_block(); - auto& last_statement=to_code_block(c).find_last_statement(); + auto &last_statement=to_code_block(c).find_last_statement(); if(last_statement.get_statement()==ID_goto) { // Insert stack twiddling before branch: diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 2935a411dd1..c63288efc6f 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -204,10 +204,9 @@ void gen_nondet_statet::gen_nondet_init( code_ifthenelset null_check; + exprt null_return=constant_exprt("0", returns_null_sym.type); null_check.cond()= - notequal_exprt( - returns_null, - constant_exprt("0", returns_null_sym.type)); + notequal_exprt(returns_null, null_return); null_check.then_case()=code_gotot(fresh_label); init_code.move_to_operands(null_check); } @@ -387,8 +386,8 @@ void gen_nondet_statet::gen_nondet_array_init( counter.type=length_sym_expr.type(); exprt counter_expr=counter.symbol_expr(); - init_code.copy_to_operands( - code_assignt(counter_expr, as_number(0, java_int_type()))); + exprt java_zero=as_number(0, java_int_type()); + init_code.copy_to_operands(code_assignt(counter_expr, java_zero)); std::string head_name=as_string(counter.base_name)+"_header"; code_labelt init_head_label(head_name, code_skipt()); @@ -429,9 +428,8 @@ void gen_nondet_statet::gen_nondet_array_init( true, /*override_type=*/&element_type); - code_assignt incr( - counter_expr, - plus_exprt(counter_expr, as_number(1, java_int_type()))); + exprt java_one=as_number(1, java_int_type()); + code_assignt incr(counter_expr, plus_exprt(counter_expr, java_one)); init_code.move_to_operands(incr); init_code.move_to_operands(goto_head); From 8d32fc7057208735034f6de53487b960f5cce207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Sun, 15 Jan 2017 22:07:57 +0100 Subject: [PATCH 073/166] remove static method is_string_array --- src/java_bytecode/java_entry_point.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index ebca33adc21..09fff0cc4de 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -179,12 +179,6 @@ bool java_static_lifetime_init( return false; } -static bool is_string_array(const typet& t) -{ - typet compare_to=java_type_from_string("[Ljava.lang.String;"); - return full_eq(t, compare_to); -} - /*******************************************************************\ Function: java_build_arguments @@ -221,11 +215,13 @@ exprt::operandst java_build_arguments( if(!is_main) { bool named_main=has_suffix(config.main, ".main"); + const typet &string_array_type= + java_type_from_string("[Ljava.lang.String;"); bool has_correct_type= to_code_type(function.type).return_type().id()==ID_empty && (!to_code_type(function.type).has_this()) && parameters.size()==1 && - is_string_array(parameters[0].type()); + full_eq(parameters[0].type(), string_array_type); is_main=(named_main && has_correct_type); } From f454ed8d4f5ff0af5468d9d3a1d80dea1418ed3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Sun, 15 Jan 2017 22:15:13 +0100 Subject: [PATCH 074/166] take comments into account --- .../java_bytecode_convert_method.cpp | 31 ++++++++++++------- src/java_bytecode/java_entry_point.cpp | 2 +- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index f92208a1d8f..d84fdba79d9 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -108,6 +108,11 @@ class java_bytecode_convert_methodt:public messaget INST_INDEX_CONST=3 } instruction_sizet; + codet get_array_bounds_check( + const exprt &arraystruct, + const exprt &idx, + const source_locationt& original_sloc); + // return corresponding reference of variable const variablet &find_variable_for_slot( size_t address, @@ -672,7 +677,7 @@ static member_exprt to_member(const exprt &pointer, const exprt &fieldref) fieldref.type()); } -codet get_array_bounds_check( +codet java_bytecode_convert_methodt::get_array_bounds_check( const exprt &arraystruct, const exprt &idx, const source_locationt& original_sloc) @@ -681,22 +686,24 @@ codet get_array_bounds_check( binary_relation_exprt gezero(idx, ID_ge, intzero); const member_exprt length_field(arraystruct, "length", java_int_type()); binary_relation_exprt ltlength(idx, ID_lt, length_field); - code_blockt boundschecks; - boundschecks.add(code_assertt(gezero)); - boundschecks.operands().back().add_source_location()=original_sloc; - boundschecks.operands().back().add_source_location() + code_blockt bounds_checks; + + bounds_checks.add(code_assertt(gezero)); + bounds_checks.operands().back().add_source_location()=original_sloc; + bounds_checks.operands().back().add_source_location() .set_comment("Array index < 0"); - boundschecks.operands().back().add_source_location() + bounds_checks.operands().back().add_source_location() .set_property_class("array-index-oob-low"); - boundschecks.add(code_assertt(ltlength)); - boundschecks.operands().back().add_source_location()=original_sloc; - boundschecks.operands().back().add_source_location() + bounds_checks.add(code_assertt(ltlength)); + + bounds_checks.operands().back().add_source_location()=original_sloc; + bounds_checks.operands().back().add_source_location() .set_comment("Array index >= length"); - boundschecks.operands().back().add_source_location() + bounds_checks.operands().back().add_source_location() .set_property_class("array-index-oob-high"); // TODO make this throw ArrayIndexOutOfBoundsException instead of asserting. - return boundschecks; + return bounds_checks; } /*******************************************************************\ @@ -1235,7 +1242,7 @@ codet java_bytecode_convert_methodt::convert_instructions( { // Remember that this is triggered by an assertion if(statement=="invokespecial" && - as_string(arg0.get(ID_identifier)) + id2string(arg0.get(ID_identifier)) .find("AssertionError")!=std::string::npos) { assertion_failure=true; diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index 09fff0cc4de..3d525d78060 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -210,7 +210,7 @@ exprt::operandst java_build_arguments( { bool is_this=(param_number==0) && parameters[param_number].get_this(); - bool is_default_entry_point=config.main==""; + bool is_default_entry_point(config.main==""); bool is_main=is_default_entry_point; if(!is_main) { From 47bd670f33c3463495e355bfb647b2f38930ceff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 20 Jan 2017 15:33:39 +0100 Subject: [PATCH 075/166] remove cast_if_necessary --- .../java_bytecode_convert_method.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index d84fdba79d9..896a4726fa7 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -317,23 +317,13 @@ static size_t get_variable_slots(const code_typet::parametert ¶m) return count_slots(0, param); } -static bool is_constructor(const class_typet::methodt &method) +bool is_constructor(const class_typet::methodt &method) { const std::string &name(id2string(method.get_name())); const std::string::size_type &npos(std::string::npos); return npos!=name.find("") || npos!=name.find(""); } -static void cast_if_necessary(binary_relation_exprt &condition) -{ - exprt &lhs(condition.lhs()); - exprt &rhs(condition.rhs()); - const typet &lhs_type(lhs.type()); - if(lhs_type==rhs.type()) - return; - rhs=typecast_exprt(rhs, lhs_type); -} - static irep_idt strip_java_namespace_prefix(const irep_idt to_strip) { const auto to_strip_str=id2string(to_strip); @@ -1600,7 +1590,12 @@ codet java_bytecode_convert_methodt::convert_instructions( binary_relation_exprt condition(op[0], cmp_op, op[1]); - cast_if_necessary(condition); + exprt &lhs(condition.lhs()); + exprt &rhs(condition.rhs()); + const typet &lhs_type(lhs.type()); + if(lhs_type!=rhs.type()) + rhs=typecast_exprt(rhs, lhs_type); + code_branch.cond()=condition; code_branch.cond().add_source_location()=i_it->source_location; code_branch.then_case()=code_gotot(label(number)); From 2599f40905977989313e62cadbabec8b68f0dc63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 20 Jan 2017 15:21:27 +0100 Subject: [PATCH 076/166] is_constructor and is_virtual as class methods --- .../java_bytecode_convert_method.cpp | 395 ++++-------------- .../java_bytecode_convert_method_class.h | 34 +- src/java_bytecode/java_bytecode_vtable.cpp | 13 +- 3 files changed, 110 insertions(+), 332 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 896a4726fa7..0d1b432b649 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -55,253 +55,6 @@ class patternt const char *p; }; -class java_bytecode_convert_methodt:public messaget -{ -public: - java_bytecode_convert_methodt( - symbol_tablet &_symbol_table, - message_handlert &_message_handler, - bool _disable_runtime_checks, - size_t _max_array_length): - messaget(_message_handler), - symbol_table(_symbol_table), - disable_runtime_checks(_disable_runtime_checks), - max_array_length(_max_array_length) - { - } - - typedef java_bytecode_parse_treet::methodt methodt; - typedef java_bytecode_parse_treet::instructiont instructiont; - typedef methodt::instructionst instructionst; - - void operator()(const symbolt &class_symbol, const methodt &method) - { - convert(class_symbol, method); - } - -protected: - symbol_tablet &symbol_table; - const bool disable_runtime_checks; - size_t max_array_length; - - irep_idt method_id; - irep_idt current_method; - typet method_return_type; - - class variablet - { - public: - symbol_exprt symbol_expr; - size_t start_pc; - size_t length; - bool is_parameter=false; - }; - - typedef std::vector variablest; - expanding_vector variables; - std::set used_local_names; - bool method_has_this; - - typedef enum instruction_sizet - { - INST_INDEX=2, - INST_INDEX_CONST=3 - } instruction_sizet; - - codet get_array_bounds_check( - const exprt &arraystruct, - const exprt &idx, - const source_locationt& original_sloc); - - // return corresponding reference of variable - const variablet &find_variable_for_slot( - size_t address, - variablest &var_list, - instruction_sizet inst_size) - { - for(const variablet &var : var_list) - { - size_t start_pc=var.start_pc; - size_t length=var.length; - if(address+(size_t)inst_size>=start_pc && - address::max(); - return var_list[list_length]; - } - - // JVM local variables - enum variable_cast_argumentt - { - CAST_AS_NEEDED, - NO_CAST - }; - - const exprt variable( - const exprt &arg, - char type_char, - size_t address, - instruction_sizet inst_size, - variable_cast_argumentt do_cast) - { - irep_idt number=to_constant_expr(arg).get_value(); - - std::size_t number_int=safe_string2size_t(id2string(number)); - typet t=java_type_from_char(type_char); - variablest &var_list=variables[number_int]; - - // search variable in list for correct frame / address if necessary - const variablet &var= - find_variable_for_slot(address, var_list, inst_size); - - if(var.symbol_expr.get_identifier().empty()) - { - // an un-named local variable - irep_idt base_name="anonlocal::"+id2string(number)+type_char; - irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); - - symbol_exprt result(identifier, t); - result.set(ID_C_base_name, base_name); - used_local_names.insert(result); - - return result; - } - else - { - exprt result=var.symbol_expr; - if(!var.is_parameter) - used_local_names.insert(to_symbol_expr(result)); - if(do_cast==CAST_AS_NEEDED && t!=result.type()) - result=typecast_exprt(result, t); - return result; - } - } - - // temporary variables - std::list tmp_vars; - - symbol_exprt tmp_variable(const std::string &prefix, const typet &type) - { - irep_idt base_name=prefix+"_tmp"+std::to_string(tmp_vars.size()); - irep_idt identifier=id2string(current_method)+"::"+id2string(base_name); - - auxiliary_symbolt tmp_symbol; - tmp_symbol.base_name=base_name; - tmp_symbol.is_static_lifetime=false; - tmp_symbol.mode=ID_java; - tmp_symbol.name=identifier; - tmp_symbol.type=type; - symbol_table.add(tmp_symbol); - - symbol_exprt result(identifier, type); - result.set(ID_C_base_name, base_name); - tmp_vars.push_back(result); - - return result; - } - - // JVM program locations - irep_idt label(const irep_idt &address) - { - return "pc"+id2string(address); - } - - // JVM Stack - typedef std::vector stackt; - stackt stack; - - exprt::operandst pop(std::size_t n) - { - if(stack.size() successors; - std::set predecessors; - codet code; - stackt stack; - bool done; - }; - - typedef std::map address_mapt; - - struct block_tree_nodet - { - bool leaf; - std::vector branch_addresses; - std::vector branch; - block_tree_nodet():leaf(false) {} - explicit block_tree_nodet(bool l):leaf(l) {} - static block_tree_nodet get_leaf() { return block_tree_nodet(true); } - }; - - static void replace_goto_target( - codet &repl, - const irep_idt &old_label, - const irep_idt &new_label); - - code_blockt &get_block_for_pcrange( - block_tree_nodet &tree, - code_blockt &this_block, - unsigned address_start, - unsigned address_limit, - unsigned next_block_start_address); - - code_blockt &get_or_create_block_for_pcrange( - block_tree_nodet &tree, - code_blockt &this_block, - unsigned address_start, - unsigned address_limit, - unsigned next_block_start_address, - const address_mapt &amap, - bool allow_merge=true); - - // conversion - void convert(const symbolt &class_symbol, const methodt &); - void convert(const instructiont &); - - codet convert_instructions( - const instructionst &, - const code_typet &); - - const bytecode_infot &get_bytecode_info(const irep_idt &statement); -}; - const size_t SLOTS_PER_INTEGER(1u); const size_t INTEGER_WIDTH(64u); static size_t count_slots( @@ -317,13 +70,6 @@ static size_t get_variable_slots(const code_typet::parametert ¶m) return count_slots(0, param); } -bool is_constructor(const class_typet::methodt &method) -{ - const std::string &name(id2string(method.get_name())); - const std::string::size_type &npos(std::string::npos); - return npos!=name.find("") || npos!=name.find(""); -} - static irep_idt strip_java_namespace_prefix(const irep_idt to_strip) { const auto to_strip_str=id2string(to_strip); @@ -331,47 +77,44 @@ static irep_idt strip_java_namespace_prefix(const irep_idt to_strip) return to_strip_str.substr(6, std::string::npos); } -java_bytecode_convert_methodt::java_bytecode_convert_methodt( - symbol_tablet &_symbol_table, - message_handlert &_message_handler) : - messaget(_message_handler), - symbol_table(_symbol_table) +// name contains or +bool java_bytecode_convert_methodt::is_constructor( + const class_typet::methodt &method) { + const std::string &name(id2string(method.get_name())); + const std::string::size_type &npos(std::string::npos); + return npos!=name.find("") || npos!=name.find(""); } -const exprt java_bytecode_convert_methodt::variable( - const exprt &arg, - char type_char, - size_t address, - variable_cast_argumentt do_cast) +exprt::operandst java_bytecode_convert_methodt::pop(std::size_t n) { - irep_idt number=to_constant_expr(arg).get_value(); + if(stack.size() working_set; bool assertion_failure=false; @@ -1405,7 +1154,7 @@ codet java_bytecode_convert_methodt::convert_instructions( assert(op.size()==1 && results.empty()); exprt var= - variable(arg0, statement[0], i_it->address, INST_INDEX, NO_CAST); + variable(arg0, statement[0], i_it->address, NO_CAST); exprt toassign=op[0]; if('a'==statement[0] && toassign.type()!=var.type()) @@ -1446,7 +1195,7 @@ codet java_bytecode_convert_methodt::convert_instructions( { // load a value from a local variable results[0]= - variable(arg0, statement[0], i_it->address, INST_INDEX, CAST_AS_NEEDED); + variable(arg0, statement[0], i_it->address, CAST_AS_NEEDED); } else if(statement=="ldc" || statement=="ldc_w" || statement=="ldc2" || statement=="ldc2_w") @@ -1666,7 +1415,7 @@ codet java_bytecode_convert_methodt::convert_instructions( { code_assignt code_assign; code_assign.lhs()= - variable(arg0, 'i', i_it->address, INST_INDEX_CONST, NO_CAST); + variable(arg0, 'i', i_it->address, NO_CAST); code_assign.rhs()=plus_exprt( variable(arg0, 'i', i_it->address, CAST_AS_NEEDED), typecast_exprt(arg1, java_int_type())); @@ -2021,17 +1770,19 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!disable_runtime_checks) { // TODO make this throw NegativeArrayIndexException instead. - constant_exprt intzero=as_number(0,java_int_type()); - binary_relation_exprt gezero(op[0],ID_ge,intzero); + constant_exprt intzero=as_number(0, java_int_type()); + binary_relation_exprt gezero(op[0], ID_ge, intzero); code_assertt check(gezero); check.add_source_location().set_comment("Array size < 0"); - check.add_source_location().set_property_class("array-create-negative-size"); + check.add_source_location() + .set_property_class("array-create-negative-size"); checkandcreate.move_to_operands(check); if(max_array_length!=0) { - constant_exprt size_limit=as_number(max_array_length,java_int_type()); - binary_relation_exprt le_max_size(op[0],ID_le,size_limit); + constant_exprt size_limit= + as_number(max_array_length, java_int_type()); + binary_relation_exprt le_max_size(op[0], ID_le, size_limit); code_assumet assume_le_max_size(le_max_size); checkandcreate.move_to_operands(assume_le_max_size); } diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index 003492355d1..d961a7131be 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -27,7 +27,15 @@ class java_bytecode_convert_methodt:public messaget public: java_bytecode_convert_methodt( symbol_tablet &_symbol_table, - message_handlert &_message_handler); + message_handlert &_message_handler, + bool _disable_runtime_checks, + size_t _max_array_length): + messaget(_message_handler), + symbol_table(_symbol_table), + disable_runtime_checks(_disable_runtime_checks), + max_array_length(_max_array_length) + { + } typedef java_bytecode_parse_treet::methodt methodt; typedef java_bytecode_parse_treet::instructiont instructiont; @@ -41,9 +49,11 @@ class java_bytecode_convert_methodt:public messaget } protected: - irep_idt method_id; symbol_tablet &symbol_table; + const bool disable_runtime_checks; + size_t max_array_length; + irep_idt method_id; irep_idt current_method; typet method_return_type; @@ -80,8 +90,21 @@ class java_bytecode_convert_methodt:public messaget std::set used_local_names; bool method_has_this; + typedef enum instruction_sizet + { + INST_INDEX=2, + INST_INDEX_CONST=3 + } instruction_sizet; + + codet get_array_bounds_check( + const exprt &arraystruct, + const exprt &idx, + const source_locationt& original_sloc); + // return corresponding reference of variable - const variablet &find_variable_for_slot(size_t address, variablest &var_list); + const variablet &find_variable_for_slot( + size_t address, + variablest &var_list); // JVM local variables enum variable_cast_argumentt @@ -112,6 +135,8 @@ class java_bytecode_convert_methodt:public messaget void push(const exprt::operandst &o); + bool is_constructor(const class_typet::methodt &method); + struct converted_instructiont { converted_instructiont( @@ -129,7 +154,7 @@ class java_bytecode_convert_methodt:public messaget public: typedef std::map address_mapt; - typedef std::pair method_with_amapt; + typedef std::pair method_with_amapt; typedef cfg_dominators_templatet java_cfg_dominatorst; @@ -180,7 +205,6 @@ class java_bytecode_convert_methodt:public messaget // conversion void convert(const symbolt &class_symbol, const methodt &); - void convert(const instructiont &); codet convert_instructions( const methodt &, diff --git a/src/java_bytecode/java_bytecode_vtable.cpp b/src/java_bytecode/java_bytecode_vtable.cpp index 5be6e9a751b..1af016870f9 100644 --- a/src/java_bytecode/java_bytecode_vtable.cpp +++ b/src/java_bytecode/java_bytecode_vtable.cpp @@ -16,11 +16,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -namespace { -bool is_virtual(const class_typet::methodt &method) { - return method.get_bool(ID_is_virtual) - && !method.get_bool(ID_constructor); -} +namespace +{ const char ID_virtual_name[] = "virtual_name"; @@ -154,6 +151,12 @@ class java_bytecode_vtable_factoryt } } + bool is_virtual(const class_typet::methodt &method) + { + return method.get_bool(ID_is_virtual) + && !method.get_bool(ID_constructor); + } + void create_base_vtable_entries( struct_exprt &vtable_value, const class_typet &class_type, From 6c65dd70b604f4a45492cbe56563f86f322f6f8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Sun, 15 Jan 2017 23:00:09 +0100 Subject: [PATCH 077/166] make param const reference in clean_deref --- src/java_bytecode/java_pointer_casts.cpp | 2 +- src/java_bytecode/java_pointer_casts.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java_bytecode/java_pointer_casts.cpp b/src/java_bytecode/java_pointer_casts.cpp index b8a569f55f4..74587ccabe7 100644 --- a/src/java_bytecode/java_pointer_casts.cpp +++ b/src/java_bytecode/java_pointer_casts.cpp @@ -24,7 +24,7 @@ Function: clean_deref \*******************************************************************/ -exprt clean_deref(const exprt ptr) +exprt clean_deref(const exprt &ptr) { return ptr.id()==ID_address_of ? ptr.op0() diff --git a/src/java_bytecode/java_pointer_casts.h b/src/java_bytecode/java_pointer_casts.h index c07492b3db2..3e0bd6c53d5 100644 --- a/src/java_bytecode/java_pointer_casts.h +++ b/src/java_bytecode/java_pointer_casts.h @@ -9,7 +9,7 @@ Author: DiffBlue #ifndef CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H #define CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H -exprt clean_deref(const exprt ptr); +exprt clean_deref(const exprt &ptr); bool find_superclass_with_type( exprt &ptr, From abccf9e722dbd87503148396f1b8bc8c9614828b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Sun, 15 Jan 2017 23:19:08 +0100 Subject: [PATCH 078/166] irep ID_java_super_method_call --- src/java_bytecode/java_bytecode_convert_method.cpp | 2 +- src/util/irep_ids.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 0d1b432b649..bc17d4b1581 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -1007,7 +1007,7 @@ codet java_bytecode_convert_methodt::convert_instructions( .find("")!=std::string::npos) code_type.set(ID_constructor, true); else - code_type.set("java_super_method_call", true); + code_type.set(ID_java_super_method_call, true); } pointer_typet object_ref_type(thistype); code_typet::parametert this_p(object_ref_type); diff --git a/src/util/irep_ids.txt b/src/util/irep_ids.txt index e6f70ccbf37..e320f329ecf 100644 --- a/src/util/irep_ids.txt +++ b/src/util/irep_ids.txt @@ -735,3 +735,4 @@ high bswap java_bytecode_index java_instanceof +java_super_method_call From 281905f2afc7ae17e8335f4670b986df40727f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Sun, 15 Jan 2017 23:34:54 +0100 Subject: [PATCH 079/166] comments for java object factory --- src/java_bytecode/java_object_factory.cpp | 34 +++++++++++++---------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index c63288efc6f..7ca08d6885e 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -32,7 +32,7 @@ Function: gen_nondet_init \*******************************************************************/ -class gen_nondet_statet +class java_object_factoryt { code_blockt &init_code; std::set recursion_set; @@ -42,12 +42,16 @@ class gen_nondet_statet namespacet ns; public: - gen_nondet_statet(code_blockt& ic, bool ann, size_t mnal, symbol_tablet& st) : - init_code(ic), - assume_non_null(ann), - max_nondet_array_length(mnal), - symbol_table(st), - ns(st) {} + java_object_factoryt( + code_blockt& _init_code, + bool _assume_non_null, + size_t _max_nondet_array_length, + symbol_tablet& _symbol_table) : + init_code(_init_code), + assume_non_null(_assume_non_null), + max_nondet_array_length(_max_nondet_array_length), + symbol_table(_symbol_table), + ns(_symbol_table) {} exprt allocate_object( const exprt&, @@ -70,7 +74,7 @@ class gen_nondet_statet // Returns false if we can't figure out the size of allocate_type. // allocate_type may differ from target_expr, e.g. for target_expr having // type int* and allocate_type being an int[10]. -exprt gen_nondet_statet::allocate_object( +exprt java_object_factoryt::allocate_object( const exprt& target_expr, const typet& allocate_type, const source_locationt &loc, @@ -106,7 +110,7 @@ exprt gen_nondet_statet::allocate_object( malloc_expr.copy_to_operands(object_size); typet result_type=pointer_typet(allocate_type); malloc_expr.type()=result_type; - // Create a symbol for the malloc expression so we can initialise + // Create a symbol for the malloc expression so we can initialize // without having to do it potentially through a double-deref, which // breaks the to-SSA phase. symbolt &malloc_sym=new_tmp_symbol(symbol_table, "malloc_site"); @@ -139,7 +143,7 @@ exprt gen_nondet_statet::allocate_object( // type regardless. Used at the moment for reference arrays, which are // implemented as void* arrays but should be init'd as their true type with // appropriate casts. -void gen_nondet_statet::gen_nondet_init( +void java_object_factoryt::gen_nondet_init( const exprt &expr, bool is_sub, irep_idt class_identifier, @@ -177,7 +181,7 @@ void gen_nondet_statet::gen_nondet_init( code_labelt set_null_label; code_labelt init_done_label; - static unsigned long synthetic_constructor_count=0; + static size_t synthetic_constructor_count=0; if(!assume_non_null) { @@ -323,7 +327,7 @@ static constant_exprt as_number(const mp_integer value, const typet &type) return constant_exprt(binary_width+significant_bits, type); } -void gen_nondet_statet::gen_nondet_array_init( +void java_object_factoryt::gen_nondet_array_init( const exprt &expr, const source_locationt &loc) { @@ -341,7 +345,7 @@ void gen_nondet_statet::gen_nondet_array_init( length_sym.type=java_int_type(); const auto &length_sym_expr=length_sym.symbol_expr(); - // Initialise array with some undetermined length: + // Initialize array with some undetermined length: gen_nondet_init(length_sym_expr, false, irep_idt(), loc, false, false); // Insert assumptions to bound its length: @@ -356,7 +360,7 @@ void gen_nondet_statet::gen_nondet_array_init( side_effect_exprt java_new_array(ID_java_new_array, expr.type()); java_new_array.copy_to_operands(length_sym_expr); - java_new_array.set("skip_initialise", true); + java_new_array.set("skip_initialize", true); java_new_array.type().subtype().set(ID_C_element_type, element_type); codet assign=code_assignt(expr, java_new_array); assign.add_source_location()=loc; @@ -459,7 +463,7 @@ void gen_nondet_init( bool assume_non_null, size_t max_nondet_array_length) { - gen_nondet_statet state( + java_object_factoryt state( init_code, assume_non_null, max_nondet_array_length, From d6f6b64813845fdccba018fb06f6b9803ae30c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Sun, 15 Jan 2017 23:58:37 +0100 Subject: [PATCH 080/166] documentation block gen_nondeet_array_init --- src/java_bytecode/java_object_factory.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 7ca08d6885e..76169197eeb 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -327,6 +327,20 @@ static constant_exprt as_number(const mp_integer value, const typet &type) return constant_exprt(binary_width+significant_bits, type); } +/*******************************************************************\ + +Function: gen_nondet_array_init + + Inputs: + + Outputs: + + Purpose: create code to initialize a Java array with size + `max_nondet_array_length`, loop over elements and initialize + them + +\*******************************************************************/ + void java_object_factoryt::gen_nondet_array_init( const exprt &expr, const source_locationt &loc) From 520cfccbd7a05bc61cd2095ba7919fe0053b80a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 16 Jan 2017 00:23:23 +0100 Subject: [PATCH 081/166] remove default values from object factory --- src/java_bytecode/java_object_factory.cpp | 2 +- src/java_bytecode/java_object_factory.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 76169197eeb..f9a620ede7c 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -444,7 +444,7 @@ void java_object_factoryt::gen_nondet_array_init( loc, false, true, - /*override_type=*/&element_type); + &element_type); exprt java_one=as_number(1, java_int_type()); code_assignt incr(counter_expr, plus_exprt(counter_expr, java_one)); diff --git a/src/java_bytecode/java_object_factory.h b/src/java_bytecode/java_object_factory.h index a868a2ae200..7807e176749 100644 --- a/src/java_bytecode/java_object_factory.h +++ b/src/java_bytecode/java_object_factory.h @@ -25,9 +25,9 @@ void gen_nondet_init( code_blockt &init_code, symbol_tablet &symbol_table, const source_locationt &, - bool skip_classid=false, - bool create_dynamic_objects=false, - bool assume_non_null=false, + bool skip_classid, + bool create_dynamic_objects, + bool assume_non_null, size_t max_nondet_array_length=5); exprt get_nondet_bool(const typet&); From 64d2f1e55047c064a68cc76efd427be602a577c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Tue, 17 Jan 2017 11:02:25 +0100 Subject: [PATCH 082/166] export as_number to java_utils.cpp --- src/java_bytecode/Makefile | 2 +- .../java_bytecode_convert_method.cpp | 18 +++++------------ src/java_bytecode/java_object_factory.cpp | 11 +--------- src/java_bytecode/java_utils.cpp | 20 +++++++++++++++++++ src/java_bytecode/java_utils.h | 18 +++++++++++++++++ 5 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 src/java_bytecode/java_utils.cpp create mode 100644 src/java_bytecode/java_utils.h diff --git a/src/java_bytecode/Makefile b/src/java_bytecode/Makefile index 66ad1003cac..e27bc3e038d 100644 --- a/src/java_bytecode/Makefile +++ b/src/java_bytecode/Makefile @@ -6,7 +6,7 @@ SRC = java_bytecode_language.cpp java_bytecode_parse_tree.cpp \ java_root_class.cpp java_bytecode_parser.cpp bytecode_info.cpp \ java_class_loader.cpp jar_file.cpp java_object_factory.cpp \ java_bytecode_convert_method.cpp java_local_variable_table.cpp \ - java_pointer_casts.cpp + java_pointer_casts.cpp java_utils.cpp INCLUDES= -I .. diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index bc17d4b1581..13656b3d028 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -26,6 +26,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_bytecode_convert_method_class.h" #include "bytecode_info.h" #include "java_types.h" +#include "java_utils.h" #include #include @@ -394,14 +395,6 @@ static irep_idt get_if_cmp_operator(const irep_idt &stmt) throw "unhandled java comparison instruction"; } -static constant_exprt as_number(const mp_integer value, const typet &type) -{ - const std::size_t java_int_width(type.get_unsigned_int(ID_width)); - const std::string significant_bits(integer2string(value, 2)); - std::string binary_width(java_int_width-significant_bits.length(), '0'); - return constant_exprt(binary_width+=significant_bits, type); -} - static member_exprt to_member(const exprt &pointer, const exprt &fieldref) { symbol_typet class_type(fieldref.get(ID_class)); @@ -1724,7 +1717,7 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!i_it->source_location.get_line().empty()) java_new_array.add_source_location()=i_it->source_location; - code_blockt check_and_create; + c=code_blockt(); if(!disable_runtime_checks) { // TODO make this throw NegativeArrayIndexException instead. @@ -1734,18 +1727,17 @@ codet java_bytecode_convert_methodt::convert_instructions( check.add_source_location().set_comment("Array size < 0"); check.add_source_location() .set_property_class("array-create-negative-size"); - check_and_create.move_to_operands(check); + c.move_to_operands(check); } if(max_array_length!=0) { constant_exprt size_limit=as_number(max_array_length, java_int_type()); binary_relation_exprt le_max_size(op[0], ID_le, size_limit); code_assumet assume_le_max_size(le_max_size); - check_and_create.move_to_operands(assume_le_max_size); + c.move_to_operands(assume_le_max_size); } const exprt tmp=tmp_variable("newarray", ref_type); - check_and_create.copy_to_operands(code_assignt(tmp, java_new_array)); - c=std::move(check_and_create); + c.copy_to_operands(code_assignt(tmp, java_new_array)); results[0]=tmp; } else if(statement=="multianewarray") diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index f9a620ede7c..5699835800b 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -19,6 +19,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_object_factory.h" #include "java_types.h" +#include "java_utils.h" /*******************************************************************\ @@ -317,16 +318,6 @@ void java_object_factoryt::gen_nondet_init( } } -// Borrowed from java_bytecode_convert.cpp -- todo find a sensible place to -// factor this. -static constant_exprt as_number(const mp_integer value, const typet &type) -{ - const size_t java_int_width(type.get_unsigned_int(ID_width)); - const std::string significant_bits(integer2string(value, 2)); - std::string binary_width(java_int_width-significant_bits.length(), '0'); - return constant_exprt(binary_width+significant_bits, type); -} - /*******************************************************************\ Function: gen_nondet_array_init diff --git a/src/java_bytecode/java_utils.cpp b/src/java_bytecode/java_utils.cpp new file mode 100644 index 00000000000..94b52f11e23 --- /dev/null +++ b/src/java_bytecode/java_utils.cpp @@ -0,0 +1,20 @@ +/*******************************************************************\ + +Module: JAVA Bytecode Language Conversion + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + +#include + +#include "java_utils.h" +#include "java_types.h" + +constant_exprt as_number(const mp_integer value, const typet &type) +{ + const size_t java_int_width(type.get_unsigned_int(ID_width)); + const std::string significant_bits(integer2string(value, 2)); + std::string binary_width(java_int_width-significant_bits.length(), '0'); + return constant_exprt(binary_width+significant_bits, type); +} diff --git a/src/java_bytecode/java_utils.h b/src/java_bytecode/java_utils.h new file mode 100644 index 00000000000..d01d93f2aca --- /dev/null +++ b/src/java_bytecode/java_utils.h @@ -0,0 +1,18 @@ +/*******************************************************************\ + +Module: JAVA Bytecode Language Conversion + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + +#ifndef CPROVER_JAVA_BYTECODE_JAVA_UTILS_H +#define CPROVER_JAVA_BYTECODE_JAVA_UTILS_H + +#include +#include +#include + +constant_exprt as_number(const mp_integer value, const typet &type); + +#endif // CPROVER_JAVA_BYTECODE_JAVA_UTILS_H From ecb6cca506f854e846583fddee2cfc7bbd1d17d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 20 Jan 2017 17:18:10 +0100 Subject: [PATCH 083/166] take tautschnig's comments into account --- src/java_bytecode/expr2java.cpp | 14 ++-- src/java_bytecode/expr2java.h | 7 +- .../java_bytecode_convert_class.cpp | 11 ++- .../java_bytecode_convert_method.cpp | 50 ++++++-------- src/java_bytecode/java_bytecode_language.h | 4 +- src/java_bytecode/java_bytecode_parser.cpp | 6 +- .../java_bytecode_typecheck_expr.cpp | 6 +- src/java_bytecode/java_entry_point.cpp | 22 +++--- src/java_bytecode/java_object_factory.cpp | 68 ++++++++++++------- src/java_bytecode/java_object_factory.h | 6 +- src/java_bytecode/java_pointer_casts.cpp | 5 +- src/java_bytecode/java_pointer_casts.h | 2 - src/java_bytecode/java_utils.cpp | 20 ------ src/java_bytecode/java_utils.h | 18 ----- src/util/json_expr.cpp | 1 - 15 files changed, 105 insertions(+), 135 deletions(-) delete mode 100644 src/java_bytecode/java_utils.cpp delete mode 100644 src/java_bytecode/java_utils.h diff --git a/src/java_bytecode/expr2java.cpp b/src/java_bytecode/expr2java.cpp index 505e7425921..74211dc5ab7 100644 --- a/src/java_bytecode/expr2java.cpp +++ b/src/java_bytecode/expr2java.cpp @@ -15,6 +15,7 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include +#include #include #include "java_types.h" @@ -216,7 +217,8 @@ std::string expr2javat::convert_constant( dest.reserve(char_representation_length); mp_integer int_value; - to_integer(src, int_value); + if(!to_integer(src, int_value)) + assert(false); dest+="(char)'"; @@ -238,7 +240,8 @@ std::string expr2javat::convert_constant( { // No byte-literals in Java, so just cast: mp_integer int_value; - to_integer(src, int_value); + if(!to_integer(src, int_value)) + assert(false); std::string dest="(byte)"; dest+=integer2string(int_value); return dest; @@ -247,7 +250,8 @@ std::string expr2javat::convert_constant( { // No short-literals in Java, so just cast: mp_integer int_value; - to_integer(src, int_value); + if(!to_integer(src, int_value)) + assert(false); std::string dest="(short)"; dest+=integer2string(int_value); return dest; @@ -482,7 +486,7 @@ std::string expr2javat::convert( const typet &type=ns.follow(src.type()); if(src.id()=="java-this") return convert_java_this(src, precedence=15); - if(src.id()=="java_instanceof") + if(src.id()==ID_java_instanceof) return convert_java_instanceof(src, precedence=15); else if(src.id()==ID_side_effect && (src.get(ID_statement)==ID_java_new || @@ -506,7 +510,7 @@ std::string expr2javat::convert( ")"; } else if(src.id()==ID_java_string_literal) - return '"'+id2string(src.get(ID_value))+'"'; // TODO: add escaping as needed + return '"'+MetaString(src.get_string(ID_value))+'"'; else if(src.id()==ID_constant && (type.id()==ID_bool || type.id()==ID_c_bool)) { if(src.is_true()) diff --git a/src/java_bytecode/expr2java.h b/src/java_bytecode/expr2java.h index a304f077288..d7889dc73a6 100644 --- a/src/java_bytecode/expr2java.h +++ b/src/java_bytecode/expr2java.h @@ -12,10 +12,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include -class exprt; -class namespacet; -class typet; - class expr2javat:public expr2ct { public: @@ -56,7 +52,8 @@ class expr2javat:public expr2ct const std::string &declarator); // length of string representation of Java Char - const std::size_t char_representation_length=14; + // representation is '\u0000' + const std::size_t char_representation_length=8; }; std::string expr2java(const exprt &expr, const namespacet &ns); diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 320f3a95ba9..049f6b4ead1 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -173,8 +173,8 @@ void java_bytecode_convert_classt::generate_class_stub( if(symbol_table.move(new_symbol, class_symbol)) { - warning() << "stub class symbol "+ - id2string(new_symbol.name)+" already exists"; + warning() << "stub class symbol " << new_symbol.name + << " already exists" << eom; } else { @@ -225,10 +225,7 @@ void java_bytecode_convert_classt::convert( symbol_table.symbols.erase(s_it); // erase, we stubbed it if(symbol_table.add(new_symbol)) - { - error() << "failed to add static field symbol" << eom; - throw 0; - } + assert(false && "failed to add static field symbol"); } else { @@ -276,6 +273,8 @@ void java_bytecode_convert_classt::add_array_types() // we have the base class, java.lang.Object, length and data // of appropriate type struct_type.set_tag(symbol_type.get_identifier()); + + struct_type.components().reserve(3); struct_typet::componentt comp0("@java.lang.Object", symbol_typet("java::java.lang.Object")); struct_type.components().push_back(comp0); diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 13656b3d028..0d0cd14028a 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -26,7 +26,6 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_bytecode_convert_method_class.h" #include "bytecode_info.h" #include "java_types.h" -#include "java_utils.h" #include #include @@ -415,7 +414,7 @@ codet java_bytecode_convert_methodt::get_array_bounds_check( const exprt &idx, const source_locationt& original_sloc) { - constant_exprt intzero=as_number(0, java_int_type()); + constant_exprt intzero=from_integer(0, java_int_type()); binary_relation_exprt gezero(idx, ID_ge, intzero); const member_exprt length_field(arraystruct, "length", java_int_type()); binary_relation_exprt ltlength(idx, ID_lt, length_field); @@ -937,7 +936,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // The stack isn't modified. // TODO: convert assertions to exceptions. assert(op.size()==1 && results.size()==1); - binary_predicate_exprt check(op[0], "java_instanceof", arg0); + binary_predicate_exprt check(op[0], ID_java_instanceof, arg0); c=code_assertt(check); c.add_source_location().set_comment("Dynamic cast check"); c.add_source_location().set_property_class("bad-dynamic-cast"); @@ -1011,12 +1010,10 @@ codet java_bytecode_convert_methodt::convert_instructions( } code_function_callt call; - source_locationt loc; - loc=i_it->source_location; + source_locationt loc=i_it->source_location; loc.set_function(method_id); - source_locationt &source_loc=loc; - call.add_source_location()=source_loc; + call.add_source_location()=loc; call.arguments()=pop(parameters.size()); // double-check a bit @@ -1089,7 +1086,7 @@ codet java_bytecode_convert_methodt::convert_instructions( call.function()=symbol_exprt(arg0.get(ID_identifier), arg0.type()); } - call.function().add_source_location()=source_loc; + call.function().add_source_location()=loc; c=call; } else if(statement=="return") @@ -1245,7 +1242,7 @@ codet java_bytecode_convert_methodt::convert_instructions( irep_idt number=to_constant_expr(arg0).get_value(); code_gotot code_goto(label(number)); c=code_goto; - results[0]=as_number( + results[0]=from_integer( std::next(i_it)->address, pointer_typet(void_typet(), 64)); } @@ -1267,9 +1264,8 @@ codet java_bytecode_convert_methodt::convert_instructions( branches.move_to_operands(g); else { - code_ifthenelset - branch; - auto address_ptr=as_number( + code_ifthenelset branch; + auto address_ptr=from_integer( jsr_ret_targets[idx], pointer_typet(void_typet(), 64)); branch.cond()=equal_exprt(retvar, address_ptr); @@ -1311,9 +1307,9 @@ codet java_bytecode_convert_methodt::convert_instructions( } else { - const size_t value(arg0.get_unsigned_int(ID_value)); + const unsigned value(arg0.get_unsigned_int(ID_value)); const typet type=java_type_from_char(statement[0]); - results[0]=as_number(value, type); + results[0]=from_integer(value, type); } } else if(statement==patternt("?ipush")) @@ -1326,8 +1322,7 @@ codet java_bytecode_convert_methodt::convert_instructions( irep_idt number=to_constant_expr(arg0).get_value(); assert(op.size()==2 && results.empty()); - code_ifthenelset - code_branch; + code_ifthenelset code_branch; const irep_idt cmp_op=get_if_cmp_operator(statement); binary_relation_exprt condition(op[0], cmp_op, op[1]); @@ -1360,8 +1355,7 @@ codet java_bytecode_convert_methodt::convert_instructions( irep_idt number=to_constant_expr(arg0).get_value(); assert(op.size()==1 && results.empty()); - code_ifthenelset - code_branch; + code_ifthenelset code_branch; code_branch.cond()= binary_relation_exprt(op[0], id, gen_zero(op[0].type())); code_branch.cond().add_source_location()=i_it->source_location; @@ -1378,8 +1372,7 @@ codet java_bytecode_convert_methodt::convert_instructions( { irep_idt number=to_constant_expr(arg0).get_value(); assert(op.size()==1 && results.empty()); - code_ifthenelset - code_branch; + code_ifthenelset code_branch; const typecast_exprt lhs(op[0], pointer_typet(empty_typet())); const exprt rhs(gen_zero(lhs.type())); code_branch.cond()=binary_relation_exprt(lhs, ID_notequal, rhs); @@ -1393,8 +1386,7 @@ codet java_bytecode_convert_methodt::convert_instructions( { assert(op.size()==1 && results.empty()); irep_idt number=to_constant_expr(arg0).get_value(); - code_ifthenelset - code_branch; + code_ifthenelset code_branch; const typecast_exprt lhs(op[0], pointer_typet(empty_typet())); const exprt rhs(gen_zero(lhs.type())); code_branch.cond()=binary_relation_exprt(lhs, ID_equal, rhs); @@ -1506,7 +1498,7 @@ codet java_bytecode_convert_methodt::convert_instructions( results[0]= if_exprt( binary_relation_exprt(op[0], ID_equal, op[1]), - gen_zero(t), + from_integer(0, t), greater); } else if(statement==patternt("?cmp?")) @@ -1637,11 +1629,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // set $assertionDisabled to false if(field_name.find("$assertionsDisabled")!=std::string::npos) - { - exprt e; - e.make_false(); - c=code_assignt(symbol_expr, e); - } + c=code_assignt(symbol_expr, false_exprt()); } else if(statement=="putfield") { @@ -1721,7 +1709,7 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!disable_runtime_checks) { // TODO make this throw NegativeArrayIndexException instead. - constant_exprt intzero=as_number(0, java_int_type()); + constant_exprt intzero=from_integer(0, java_int_type()); binary_relation_exprt gezero(op[0], ID_ge, intzero); code_assertt check(gezero); check.add_source_location().set_comment("Array size < 0"); @@ -1731,7 +1719,7 @@ codet java_bytecode_convert_methodt::convert_instructions( } if(max_array_length!=0) { - constant_exprt size_limit=as_number(max_array_length, java_int_type()); + constant_exprt size_limit=from_integer(max_array_length, java_int_type()); binary_relation_exprt le_max_size(op[0], ID_le, size_limit); code_assumet assume_le_max_size(le_max_size); c.move_to_operands(assume_le_max_size); @@ -1750,7 +1738,7 @@ codet java_bytecode_convert_methodt::convert_instructions( op=pop(dimension); assert(results.size()==1); - const pointer_typet ref_type=pointer_typet(arg0.type()); + const pointer_typet ref_type(arg0.type()); side_effect_exprt java_new_array(ID_java_new_array, ref_type); java_new_array.operands()=op; diff --git a/src/java_bytecode/java_bytecode_language.h b/src/java_bytecode/java_bytecode_language.h index 834f6d60544..a62aca0c887 100644 --- a/src/java_bytecode/java_bytecode_language.h +++ b/src/java_bytecode/java_bytecode_language.h @@ -14,6 +14,8 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_class_loader.h" +#define MAX_NONDET_ARRAY_LENGTH_DEFAULT 5 + class java_bytecode_languaget:public languaget { public: @@ -39,7 +41,7 @@ class java_bytecode_languaget:public languaget virtual ~java_bytecode_languaget(); java_bytecode_languaget(): - max_nondet_array_length(5), + max_nondet_array_length(MAX_NONDET_ARRAY_LENGTH_DEFAULT), max_user_array_length(0) { } bool from_expr( diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index c025a4ad268..c72105581f0 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -1449,7 +1449,7 @@ void java_bytecode_parsert::rclass_attribute(classt &parsed_class) u2 sourcefile_index=read_u2(); irep_idt sourcefile_name; - std::string fqn=std::string(id2string(parsed_class.name)); + std::string fqn(id2string(parsed_class.name)); size_t last_index=fqn.find_last_of("."); if(last_index==std::string::npos) sourcefile_name=pool_entry(sourcefile_index).s; @@ -1457,8 +1457,8 @@ void java_bytecode_parsert::rclass_attribute(classt &parsed_class) { std::string packageName=fqn.substr(0, last_index+1); std::replace(packageName.begin(), packageName.end(), '.', '/'); - const std::string &fullFileName= - std::string(packageName+id2string(pool_entry(sourcefile_index).s)); + const std::string + &fullFileName=(packageName+id2string(pool_entry(sourcefile_index).s)); sourcefile_name=fullFileName; } diff --git a/src/java_bytecode/java_bytecode_typecheck_expr.cpp b/src/java_bytecode/java_bytecode_typecheck_expr.cpp index d1bb21eea0d..5c234378936 100644 --- a/src/java_bytecode/java_bytecode_typecheck_expr.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_expr.cpp @@ -93,9 +93,9 @@ void java_bytecode_typecheckt::typecheck_expr_java_new_array( static void escape_non_alnum(std::string& toescape) { - for(size_t idx=0, lim=toescape.size(); idx!=lim; ++idx) - if(!isalnum(toescape[idx])) - toescape[idx]='_'; + for(auto &ch : toescape) + if(!isalnum(ch)) + ch='_'; } /*******************************************************************\ diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index 3d525d78060..ef0d35b15c3 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -92,10 +92,7 @@ static bool should_init_symbol(const symbolt& sym) sym.mode==ID_java) return true; - if(has_prefix(id2string(sym.name), "java::java.lang.String.Literal")) - return true; - - return false; + return has_prefix(id2string(sym.name), "java::java.lang.String.Literal"); } bool java_static_lifetime_init( @@ -112,8 +109,7 @@ bool java_static_lifetime_init( // external. Iterate over a copy of the symtab, as its iterators are // invalidated by object_factory: - std::vector symnames; - symnames.reserve(symbol_table.symbols.size()); + std::list symnames; for(const auto& entry : symbol_table.symbols) symnames.push_back(entry.first); @@ -144,7 +140,8 @@ bool java_static_lifetime_init( allow_null, symbol_table, max_nondet_array_length, - source_location); + source_location, + message_handler); code_assignt assignment(sym.symbol_expr(), newsym); code_block.add(assignment); } @@ -196,7 +193,8 @@ exprt::operandst java_build_arguments( code_blockt &init_code, symbol_tablet &symbol_table, bool assume_init_pointers_not_null, - unsigned max_nondet_array_length) + unsigned max_nondet_array_length, + message_handlert &message_handler) { const code_typet::parameterst ¶meters= to_code_type(function.type).parameters(); @@ -234,7 +232,8 @@ exprt::operandst java_build_arguments( allow_null, symbol_table, max_nondet_array_length, - function.location); + function.location, + message_handler); const symbolt &p_symbol= symbol_table.lookup(parameters[param_number].get_identifier()); @@ -459,7 +458,7 @@ main_function_resultt get_main_symbol( if(matches.empty()) { // Not found, silently ignore - res.main_function=symbolt(); + res.main_function=symbol; res.error_found=false; res.stop_convert=true; return res; @@ -596,7 +595,8 @@ bool java_entry_point( init_code, symbol_table, assume_init_pointers_not_null, - max_nondet_array_length); + max_nondet_array_length, + message_handler); call_main.arguments()=main_arguments; init_code.move_to_operands(call_main); diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 5699835800b..7aa6d13ead6 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -9,17 +9,20 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include #include #include +#include #include #include #include #include +#include + #include "java_object_factory.h" #include "java_types.h" -#include "java_utils.h" /*******************************************************************\ @@ -33,13 +36,14 @@ Function: gen_nondet_init \*******************************************************************/ -class java_object_factoryt +class java_object_factoryt:public messaget { code_blockt &init_code; std::set recursion_set; bool assume_non_null; size_t max_nondet_array_length; symbol_tablet &symbol_table; + message_handlert &message_handler; namespacet ns; public: @@ -47,12 +51,15 @@ class java_object_factoryt code_blockt& _init_code, bool _assume_non_null, size_t _max_nondet_array_length, - symbol_tablet& _symbol_table) : + symbol_tablet &_symbol_table, + message_handlert &_message_handler): init_code(_init_code), assume_non_null(_assume_non_null), max_nondet_array_length(_max_nondet_array_length), symbol_table(_symbol_table), - ns(_symbol_table) {} + message_handler(_message_handler), + ns(_symbol_table) + {} exprt allocate_object( const exprt&, @@ -69,7 +76,8 @@ class java_object_factoryt const source_locationt &loc, bool skip_classid, bool create_dynamic_objects, - const typet *override_type=0); + bool override=false, + const typet &override_type=empty_typet()); }; // Returns false if we can't figure out the size of allocate_type. @@ -151,10 +159,11 @@ void java_object_factoryt::gen_nondet_init( const source_locationt &loc, bool skip_classid, bool create_dynamic_objects, - const typet *override_type) + bool override, + const typet &override_type) { const typet &type= - override_type ? ns.follow(*override_type) : ns.follow(expr.type()); + override ? ns.follow(override_type) : ns.follow(expr.type()); if(type.id()==ID_pointer) { @@ -199,17 +208,15 @@ void java_object_factoryt::gen_nondet_init( code_assignt(expr, null_pointer_exprt(pointer_type)); set_null_inst.add_source_location()=loc; - std::ostringstream fresh_label_oss; - fresh_label_oss<<"post_synthetic_malloc_" - <<(++synthetic_constructor_count); - std::string fresh_label=fresh_label_oss.str(); + std::string fresh_label= + "post_synthetic_malloc_"+std::to_string(++synthetic_constructor_count); set_null_label=code_labelt(fresh_label, set_null_inst); init_done_label=code_labelt(fresh_label+"_init_done", code_skipt()); - code_ifthenelset - null_check; - exprt null_return=constant_exprt("0", returns_null_sym.type); + code_ifthenelset null_check; + exprt null_return= + zero_initializer(returns_null_sym.type, loc, ns, message_handler); null_check.cond()= notequal_exprt(returns_null, null_return); null_check.then_case()=code_gotot(fresh_label); @@ -343,7 +350,7 @@ void java_object_factoryt::gen_nondet_array_init( const typet &element_type= static_cast(expr.type().subtype().find(ID_C_element_type)); - auto max_length_expr=as_number(max_nondet_array_length, java_int_type()); + auto max_length_expr=from_integer(max_nondet_array_length, java_int_type()); typet allocate_type; symbolt &length_sym=new_tmp_symbol(symbol_table, "nondet_array_length"); @@ -355,7 +362,7 @@ void java_object_factoryt::gen_nondet_array_init( // Insert assumptions to bound its length: binary_relation_exprt - assume1(length_sym_expr, ID_ge, as_number(0, java_int_type())); + assume1(length_sym_expr, ID_ge, from_integer(0, java_int_type())); binary_relation_exprt assume2(length_sym_expr, ID_le, max_length_expr); code_assumet assume_inst1(assume1); @@ -395,7 +402,7 @@ void java_object_factoryt::gen_nondet_array_init( counter.type=length_sym_expr.type(); exprt counter_expr=counter.symbol_expr(); - exprt java_zero=as_number(0, java_int_type()); + exprt java_zero=from_integer(0, java_int_type()); init_code.copy_to_operands(code_assignt(counter_expr, java_zero)); std::string head_name=as_string(counter.base_name)+"_header"; @@ -408,8 +415,7 @@ void java_object_factoryt::gen_nondet_array_init( code_labelt init_done_label(done_name, code_skipt()); code_gotot goto_done(done_name); - code_ifthenelset - done_test; + code_ifthenelset done_test; done_test.cond()=equal_exprt(counter_expr, length_sym_expr); done_test.then_case()=goto_done; @@ -417,8 +423,7 @@ void java_object_factoryt::gen_nondet_array_init( // Add a redundant if(counter == max_length) break that is easier for the // unwinder to understand. - code_ifthenelset - max_test; + code_ifthenelset max_test; max_test.cond()=equal_exprt(counter_expr, max_length_expr); max_test.then_case()=goto_done; @@ -435,9 +440,10 @@ void java_object_factoryt::gen_nondet_array_init( loc, false, true, - &element_type); + true, + element_type); - exprt java_one=as_number(1, java_int_type()); + exprt java_one=from_integer(1, java_int_type()); code_assignt incr(counter_expr, plus_exprt(counter_expr, java_one)); init_code.move_to_operands(incr); @@ -466,14 +472,22 @@ void gen_nondet_init( bool skip_classid, bool create_dyn_objs, bool assume_non_null, + message_handlert &message_handler, size_t max_nondet_array_length) { java_object_factoryt state( init_code, assume_non_null, max_nondet_array_length, - symbol_table); - state.gen_nondet_init(expr, false, "", loc, skip_classid, create_dyn_objs); + symbol_table, + message_handler); + state.gen_nondet_init( + expr, + false, + "", + loc, + skip_classid, + create_dyn_objs); } /*******************************************************************\ @@ -543,7 +557,8 @@ exprt object_factory( bool allow_null, symbol_tablet &symbol_table, size_t max_nondet_array_length, - const source_locationt &loc) + const source_locationt &loc, + message_handlert &message_handler) { if(type.id()==ID_pointer) { @@ -562,6 +577,7 @@ exprt object_factory( false, false, !allow_null, + message_handler, max_nondet_array_length); return object; diff --git a/src/java_bytecode/java_object_factory.h b/src/java_bytecode/java_object_factory.h index 7807e176749..13d933d9da5 100644 --- a/src/java_bytecode/java_object_factory.h +++ b/src/java_bytecode/java_object_factory.h @@ -9,6 +9,7 @@ Author: Daniel Kroening, kroening@kroening.com #ifndef CPROVER_JAVA_BYTECODE_JAVA_OBJECT_FACTORY_H #define CPROVER_JAVA_BYTECODE_JAVA_OBJECT_FACTORY_H +#include #include #include @@ -18,7 +19,8 @@ exprt object_factory( bool allow_null, symbol_tablet &symbol_table, size_t max_nondet_array_length, - const source_locationt &); + const source_locationt &, + message_handlert &message_handler); void gen_nondet_init( const exprt &expr, @@ -28,8 +30,10 @@ void gen_nondet_init( bool skip_classid, bool create_dynamic_objects, bool assume_non_null, + message_handlert &message_handler, size_t max_nondet_array_length=5); + exprt get_nondet_bool(const typet&); symbolt &new_tmp_symbol( diff --git a/src/java_bytecode/java_pointer_casts.cpp b/src/java_bytecode/java_pointer_casts.cpp index 74587ccabe7..135e4705cb2 100644 --- a/src/java_bytecode/java_pointer_casts.cpp +++ b/src/java_bytecode/java_pointer_casts.cpp @@ -24,7 +24,7 @@ Function: clean_deref \*******************************************************************/ -exprt clean_deref(const exprt &ptr) +static exprt clean_deref(const exprt &ptr) { return ptr.id()==ID_address_of ? ptr.op0() @@ -50,6 +50,7 @@ bool find_superclass_with_type( const typet &target_type, const namespacet &ns) { + assert(ptr.type().id()==ID_pointer); while(true) { const typet ptr_base=ns.follow(ptr.type().subtype()); @@ -59,7 +60,7 @@ bool find_superclass_with_type( const struct_typet &base_struct=to_struct_type(ptr_base); - if(base_struct.components().size()==0) + if(base_struct.components().empty()) return false; const typet &first_field_type= diff --git a/src/java_bytecode/java_pointer_casts.h b/src/java_bytecode/java_pointer_casts.h index 3e0bd6c53d5..7b5d23a3c8a 100644 --- a/src/java_bytecode/java_pointer_casts.h +++ b/src/java_bytecode/java_pointer_casts.h @@ -9,8 +9,6 @@ Author: DiffBlue #ifndef CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H #define CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H -exprt clean_deref(const exprt &ptr); - bool find_superclass_with_type( exprt &ptr, const typet &target_type, diff --git a/src/java_bytecode/java_utils.cpp b/src/java_bytecode/java_utils.cpp deleted file mode 100644 index 94b52f11e23..00000000000 --- a/src/java_bytecode/java_utils.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/*******************************************************************\ - -Module: JAVA Bytecode Language Conversion - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#include - -#include "java_utils.h" -#include "java_types.h" - -constant_exprt as_number(const mp_integer value, const typet &type) -{ - const size_t java_int_width(type.get_unsigned_int(ID_width)); - const std::string significant_bits(integer2string(value, 2)); - std::string binary_width(java_int_width-significant_bits.length(), '0'); - return constant_exprt(binary_width+significant_bits, type); -} diff --git a/src/java_bytecode/java_utils.h b/src/java_bytecode/java_utils.h deleted file mode 100644 index d01d93f2aca..00000000000 --- a/src/java_bytecode/java_utils.h +++ /dev/null @@ -1,18 +0,0 @@ -/*******************************************************************\ - -Module: JAVA Bytecode Language Conversion - -Author: Daniel Kroening, kroening@kroening.com - -\*******************************************************************/ - -#ifndef CPROVER_JAVA_BYTECODE_JAVA_UTILS_H -#define CPROVER_JAVA_BYTECODE_JAVA_UTILS_H - -#include -#include -#include - -constant_exprt as_number(const mp_integer value, const typet &type); - -#endif // CPROVER_JAVA_BYTECODE_JAVA_UTILS_H diff --git a/src/util/json_expr.cpp b/src/util/json_expr.cpp index 4d9f7b5aa54..c44769fceda 100644 --- a/src/util/json_expr.cpp +++ b/src/util/json_expr.cpp @@ -16,7 +16,6 @@ Author: Peter Schrammel #include "config.h" #include "json_expr.h" -#include /*******************************************************************\ Function: json From 06942df96cfbcca1d328dd1b0bf41a758f5a579c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 23 Jan 2017 11:10:19 +0100 Subject: [PATCH 084/166] remove namespace from vtable --- src/java_bytecode/java_bytecode_vtable.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/java_bytecode/java_bytecode_vtable.cpp b/src/java_bytecode/java_bytecode_vtable.cpp index 1af016870f9..be0cf2a15b8 100644 --- a/src/java_bytecode/java_bytecode_vtable.cpp +++ b/src/java_bytecode/java_bytecode_vtable.cpp @@ -16,9 +16,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -namespace -{ - const char ID_virtual_name[] = "virtual_name"; class is_virtual_name_equalt { @@ -213,7 +210,6 @@ class java_bytecode_vtable_factoryt } }; -} /******************************************************************* From 7d2a303b83d64ee98cca060c01c77d10b5d15bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 23 Jan 2017 11:34:38 +0100 Subject: [PATCH 085/166] remove const_cast --- src/java_bytecode/java_bytecode_typecheck_expr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java_bytecode/java_bytecode_typecheck_expr.cpp b/src/java_bytecode/java_bytecode_typecheck_expr.cpp index 5c234378936..0c5e8002af0 100644 --- a/src/java_bytecode/java_bytecode_typecheck_expr.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_expr.cpp @@ -235,7 +235,7 @@ void java_bytecode_typecheckt::typecheck_expr_member(member_exprt &expr) while(1) { - typet &base_type=const_cast(ns.follow(expr.struct_op().type())); + typet base_type(ns.follow(expr.struct_op().type())); if(base_type.id()!=ID_struct) break; // give up From f73048fc27030e5ba92f36e3a7932e9bfcd60fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 23 Jan 2017 14:32:19 +0100 Subject: [PATCH 086/166] add java_utils.cpp --- src/java_bytecode/java_object_factory.cpp | 6 ++---- src/java_bytecode/java_utils.cpp | 21 +++++++++++++++++++++ src/java_bytecode/java_utils.h | 16 ++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 src/java_bytecode/java_utils.cpp create mode 100644 src/java_bytecode/java_utils.h diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 7aa6d13ead6..3cff49703fd 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -23,6 +23,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_object_factory.h" #include "java_types.h" +#include "java_utils.h" /*******************************************************************\ @@ -223,11 +224,8 @@ void java_object_factoryt::gen_nondet_init( init_code.move_to_operands(null_check); } - if(subtype.id()==ID_struct && - has_prefix(id2string(to_struct_type(subtype).get_tag()), "java::array[")) - { + if(java_is_array_type(subtype)) gen_nondet_array_init(expr, loc); - } else { exprt allocated= diff --git a/src/java_bytecode/java_utils.cpp b/src/java_bytecode/java_utils.cpp new file mode 100644 index 00000000000..2e84c77f870 --- /dev/null +++ b/src/java_bytecode/java_utils.cpp @@ -0,0 +1,21 @@ +/*******************************************************************\ + +Module: + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + +#include +#include + +#include "java_utils.h" + +bool java_is_array_type(const typet &type) +{ + if(type.id()!=ID_struct) + return false; + return has_prefix(id2string( + to_struct_type(type).get_tag()), + "java::array["); +} diff --git a/src/java_bytecode/java_utils.h b/src/java_bytecode/java_utils.h new file mode 100644 index 00000000000..ec7e6a9ad8e --- /dev/null +++ b/src/java_bytecode/java_utils.h @@ -0,0 +1,16 @@ +/*******************************************************************\ + +Module: + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + +#include + +#ifndef CPROVER_JAVA_BYTECODE_JAVA_UTILS_H +#define CPROVER_JAVA_BYTECODE_JAVA_UTILS_H + +bool java_is_array_type(const typet &type); + +#endif // CPROVER_JAVA_BYTECODE_JAVA_UTILS_H From a0e5510efe08350b3aed74029e1462a8c08ab421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 23 Jan 2017 13:52:27 +0100 Subject: [PATCH 087/166] Peter's comments --- src/java_bytecode/expr2java.cpp | 2 +- .../java_bytecode_convert_method.cpp | 12 +++---- .../java_bytecode_convert_method_class.h | 2 +- src/java_bytecode/java_bytecode_parser.cpp | 10 +++--- src/java_bytecode/java_entry_point.cpp | 4 +-- src/java_bytecode/java_object_factory.cpp | 32 +++++++++++++------ src/java_bytecode/java_pointer_casts.cpp | 1 - src/util/json_expr.cpp | 2 +- 8 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/java_bytecode/expr2java.cpp b/src/java_bytecode/expr2java.cpp index 74211dc5ab7..8b5966b8afe 100644 --- a/src/java_bytecode/expr2java.cpp +++ b/src/java_bytecode/expr2java.cpp @@ -50,7 +50,7 @@ std::string expr2javat::convert_code_function_call( unsigned p; std::string lhs_str=convert(src.lhs(), p); - // TODO: ggf. Klammern je nach p + // TODO: if necessery add parentheses, dependent on p dest+=lhs_str; dest+='='; } diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 0d0cd14028a..fd95df405ed 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -425,14 +425,14 @@ codet java_bytecode_convert_methodt::get_array_bounds_check( bounds_checks.operands().back().add_source_location() .set_comment("Array index < 0"); bounds_checks.operands().back().add_source_location() - .set_property_class("array-index-oob-low"); + .set_property_class("array-index-out-of-bounds-low"); bounds_checks.add(code_assertt(ltlength)); bounds_checks.operands().back().add_source_location()=original_sloc; bounds_checks.operands().back().add_source_location() .set_comment("Array index >= length"); bounds_checks.operands().back().add_source_location() - .set_property_class("array-index-oob-high"); + .set_property_class("array-index-out-of-bounds-high"); // TODO make this throw ArrayIndexOutOfBoundsException instead of asserting. return bounds_checks; @@ -795,9 +795,9 @@ codet java_bytecode_convert_methodt::convert_instructions( if(i_it->statement=="jsr" || i_it->statement=="jsr_w") { - instructionst::const_iterator next=i_it; + instructionst::const_iterator next=i_it+1; assert( - ++next!=instructions.end() && + next!=instructions.end() && "jsr without valid return address?"); targets.insert(next->address); jsr_ret_targets.push_back(next->address); @@ -1750,7 +1750,7 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!disable_runtime_checks) { // TODO make this throw NegativeArrayIndexException instead. - constant_exprt intzero=as_number(0, java_int_type()); + constant_exprt intzero=from_integer(0, java_int_type()); binary_relation_exprt gezero(op[0], ID_ge, intzero); code_assertt check(gezero); check.add_source_location().set_comment("Array size < 0"); @@ -1761,7 +1761,7 @@ codet java_bytecode_convert_methodt::convert_instructions( if(max_array_length!=0) { constant_exprt size_limit= - as_number(max_array_length, java_int_type()); + from_integer(max_array_length, java_int_type()); binary_relation_exprt le_max_size(op[0], ID_le, size_limit); code_assumet assume_le_max_size(le_max_size); checkandcreate.move_to_operands(assume_le_max_size); diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index d961a7131be..8aa79c7bd2b 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -51,7 +51,7 @@ class java_bytecode_convert_methodt:public messaget protected: symbol_tablet &symbol_table; const bool disable_runtime_checks; - size_t max_array_length; + const size_t max_array_length; irep_idt method_id; irep_idt current_method; diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index c72105581f0..93f082ecb7d 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -1455,11 +1455,11 @@ void java_bytecode_parsert::rclass_attribute(classt &parsed_class) sourcefile_name=pool_entry(sourcefile_index).s; else { - std::string packageName=fqn.substr(0, last_index+1); - std::replace(packageName.begin(), packageName.end(), '.', '/'); - const std::string - &fullFileName=(packageName+id2string(pool_entry(sourcefile_index).s)); - sourcefile_name=fullFileName; + std::string package_name=fqn.substr(0, last_index+1); + std::replace(package_name.begin(), package_name.end(), '.', '/'); + const std::string &full_file_name= + package_name+id2string(pool_entry(sourcefile_index).s); + sourcefile_name=full_file_name; } for(methodst::iterator m_it=parsed_class.methods.begin(); diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index ef0d35b15c3..d560bb234fa 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -105,12 +105,12 @@ bool java_static_lifetime_init( symbolt &initialize_symbol=symbol_table.lookup(INITIALIZE); code_blockt &code_block=to_code_block(to_code(initialize_symbol.value)); - // W need to zero out all static variables, or nondet-initialize if they're + // We need to zero out all static variables, or nondet-initialize if they're // external. Iterate over a copy of the symtab, as its iterators are // invalidated by object_factory: std::list symnames; - for(const auto& entry : symbol_table.symbols) + for(const auto &entry : symbol_table.symbols) symnames.push_back(entry.first); for(const auto& symname : symnames) diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 3cff49703fd..a02da1a43f0 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -81,17 +81,30 @@ class java_object_factoryt:public messaget const typet &override_type=empty_typet()); }; -// Returns false if we can't figure out the size of allocate_type. -// allocate_type may differ from target_expr, e.g. for target_expr having -// type int* and allocate_type being an int[10]. + +/*******************************************************************\ + +Function: gen_nondet_array_init + + Inputs: the target expression, desired object type, source location + and Boolean whether to create a dynamic object + + Outputs: the allocated object + + Purpose: Returns false if we can't figure out the size of allocate_type. + allocate_type may differ from target_expr, e.g. for target_expr + having type int* and allocate_type being an int[10]. + +\*******************************************************************/ + exprt java_object_factoryt::allocate_object( - const exprt& target_expr, - const typet& allocate_type, + const exprt &target_expr, + const typet &allocate_type, const source_locationt &loc, bool create_dynamic_objects) { - const typet& allocate_type_resolved=ns.follow(allocate_type); - const typet& target_type=ns.follow(target_expr.type().subtype()); + const typet &allocate_type_resolved=ns.follow(allocate_type); + const typet &target_type=ns.follow(target_expr.type().subtype()); bool cast_needed=allocate_type_resolved!=target_type; if(!create_dynamic_objects) { @@ -197,7 +210,7 @@ void java_object_factoryt::gen_nondet_init( if(!assume_non_null) { auto returns_null_sym= - new_tmp_symbol(symbol_table, "opaque_returns_null"); + new_tmp_symbol(symbol_table, "opaque_returns_null"); returns_null_sym.type=c_bool_typet(1); auto returns_null=returns_null_sym.symbol_expr(); auto assign_returns_null= @@ -449,7 +462,6 @@ void java_object_factoryt::gen_nondet_array_init( init_code.move_to_operands(init_done_label); } - /*******************************************************************\ Function: gen_nondet_init @@ -502,7 +514,7 @@ Function: new_tmp_symbol symbolt &new_tmp_symbol(symbol_tablet &symbol_table, const std::string& prefix) { - static size_t temporary_counter=0; + static size_t temporary_counter=0; // TODO change this auxiliary_symbolt new_symbol; symbolt *symbol_ptr; diff --git a/src/java_bytecode/java_pointer_casts.cpp b/src/java_bytecode/java_pointer_casts.cpp index 135e4705cb2..934e6cfb135 100644 --- a/src/java_bytecode/java_pointer_casts.cpp +++ b/src/java_bytecode/java_pointer_casts.cpp @@ -44,7 +44,6 @@ Function: find_superclass_with_type \*******************************************************************/ - bool find_superclass_with_type( exprt &ptr, const typet &target_type, diff --git a/src/util/json_expr.cpp b/src/util/json_expr.cpp index c44769fceda..7d52ca93c31 100644 --- a/src/util/json_expr.cpp +++ b/src/util/json_expr.cpp @@ -265,7 +265,7 @@ json_objectt json( if(expr.get(ID_value)==ID_NULL) result["data"]=json_stringt("NULL"); } - else if(type.id()==ID_bool || type.id()==ID_c_bool) + else if(type.id()==ID_bool) { result["name"]=json_stringt("boolean"); result["binary"]=json_stringt(expr.is_true()?"1":"0"); From 51751cebfe114d908c53970fda3b298f014ab39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 23 Jan 2017 15:03:54 +0100 Subject: [PATCH 088/166] remove superfluous std::move from conversion --- .../java_bytecode_convert_method.cpp | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index fd95df405ed..7d6140966d5 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -1124,18 +1124,17 @@ codet java_bytecode_convert_methodt::convert_instructions( typet element_type=data_ptr.type().subtype(); const dereference_exprt element(data_plus_offset, element_type); - code_blockt assert_and_put; + c=code_blockt(); if(!disable_runtime_checks) { codet bounds_check= get_array_bounds_check(deref, op[1], i_it->source_location); bounds_check.add_source_location()=i_it->source_location; - assert_and_put.move_to_operands(bounds_check); + c.move_to_operands(bounds_check); } code_assignt array_put(element, op[2]); array_put.add_source_location()=i_it->source_location; - assert_and_put.move_to_operands(array_put); - c=std::move(assert_and_put); + c.move_to_operands(array_put); c.add_source_location()=i_it->source_location; } else if(statement==patternt("?store")) @@ -1174,10 +1173,8 @@ codet java_bytecode_convert_methodt::convert_instructions( if(!disable_runtime_checks) { - codet bounds_check= - get_array_bounds_check(deref, op[1], i_it->source_location); - bounds_check.add_source_location()=i_it->source_location; - c=std::move(bounds_check); + c=get_array_bounds_check(deref, op[1], i_it->source_location); + c.add_source_location()=i_it->source_location; } results[0]=java_bytecode_promotion(element); } @@ -1252,7 +1249,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // and write something like: // if(retaddr==5) goto 5; else if(retaddr==10) goto 10; ... assert(op.empty() && results.empty()); - code_blockt branches; + c=code_blockt(); auto retvar=variable(arg0, 'a', i_it->address, NO_CAST); assert(!jsr_ret_targets.empty()); for(size_t idx=0, idxlim=jsr_ret_targets.size(); idx!=idxlim; ++idx) @@ -1261,7 +1258,7 @@ codet java_bytecode_convert_methodt::convert_instructions( code_gotot g(label(number)); g.add_source_location()=i_it->source_location; if(idx==idxlim-1) - branches.move_to_operands(g); + c.move_to_operands(g); else { code_ifthenelset branch; @@ -1272,10 +1269,9 @@ codet java_bytecode_convert_methodt::convert_instructions( branch.cond().add_source_location()=i_it->source_location; branch.then_case()=g; branch.add_source_location()=i_it->source_location; - branches.move_to_operands(branch); + c.move_to_operands(branch); } } - c=std::move(branches); } else if(statement=="iconst_m1") { From 85de00e499264b280c4640ea061c89f76b60d7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 23 Jan 2017 16:45:59 +0100 Subject: [PATCH 089/166] adapt NullPointer[1-4] regression tests --- regression/cbmc-java/NullPointer1/test.desc | 2 +- regression/cbmc-java/NullPointer2/test.desc | 2 +- regression/cbmc-java/NullPointer3/test.desc | 2 +- regression/cbmc-java/NullPointer4/test.desc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/regression/cbmc-java/NullPointer1/test.desc b/regression/cbmc-java/NullPointer1/test.desc index bf4dc51e8da..0394ce544f3 100644 --- a/regression/cbmc-java/NullPointer1/test.desc +++ b/regression/cbmc-java/NullPointer1/test.desc @@ -3,7 +3,7 @@ NullPointer1.class --pointer-check --stop-on-fail ^EXIT=10$ ^SIGNAL=0$ -^ file NullPointer1.java line 16$ +^ file NullPointer1.java line 16 function java::NullPointer1.main:(\[Ljava/lang/String;)V$ ^VERIFICATION FAILED$ -- ^warning: ignoring diff --git a/regression/cbmc-java/NullPointer2/test.desc b/regression/cbmc-java/NullPointer2/test.desc index 8bf602bc2af..a794ca8ac88 100644 --- a/regression/cbmc-java/NullPointer2/test.desc +++ b/regression/cbmc-java/NullPointer2/test.desc @@ -3,7 +3,7 @@ NullPointer2.class --pointer-check --stop-on-fail ^EXIT=10$ ^SIGNAL=0$ -^ file NullPointer2.java line 9$ +^ file NullPointer2.java line 9 function java::NullPointer2.main:(\[Ljava/lang/String;)V bytecode_index 1$ ^VERIFICATION FAILED$ -- ^warning: ignoring diff --git a/regression/cbmc-java/NullPointer3/test.desc b/regression/cbmc-java/NullPointer3/test.desc index d422f43b99d..f4956e75540 100644 --- a/regression/cbmc-java/NullPointer3/test.desc +++ b/regression/cbmc-java/NullPointer3/test.desc @@ -3,7 +3,7 @@ NullPointer3.class --pointer-check --stop-on-fail ^EXIT=10$ ^SIGNAL=0$ -^ file NullPointer3.java line 5$ +^ file NullPointer3.java line 5 function java::NullPointer3.main:(\[Ljava/lang/String;)V bytecode_index 1$ ^VERIFICATION FAILED$ -- ^warning: ignoring diff --git a/regression/cbmc-java/NullPointer4/test.desc b/regression/cbmc-java/NullPointer4/test.desc index 788cb61fdf1..653f7cf47bd 100644 --- a/regression/cbmc-java/NullPointer4/test.desc +++ b/regression/cbmc-java/NullPointer4/test.desc @@ -3,7 +3,7 @@ NullPointer4.class --pointer-check --stop-on-fail ^EXIT=10$ ^SIGNAL=0$ -^ file NullPointer4.java line 6$ +^ file NullPointer4.java line 6 function java::NullPointer4.main:(\[Ljava/lang/String;)V$ ^VERIFICATION FAILED$ -- ^warning: ignoring From 494436a702f68727d555860cb441440d4262a3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 23 Jan 2017 17:13:23 +0100 Subject: [PATCH 090/166] default ctor for java_convert_methodt::variablet --- src/java_bytecode/java_bytecode_convert_method.cpp | 9 +++++---- src/java_bytecode/java_bytecode_convert_method_class.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 7d6140966d5..a2ca21ef80d 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -412,7 +412,7 @@ static member_exprt to_member(const exprt &pointer, const exprt &fieldref) codet java_bytecode_convert_methodt::get_array_bounds_check( const exprt &arraystruct, const exprt &idx, - const source_locationt& original_sloc) + const source_locationt &original_sloc) { constant_exprt intzero=from_integer(0, java_int_type()); binary_relation_exprt gezero(idx, ID_ge, intzero); @@ -1619,7 +1619,7 @@ codet java_bytecode_convert_methodt::convert_instructions( { assert(op.empty() && results.size()==1); symbol_exprt symbol_expr(arg0.type()); - const auto& field_name=arg0.get_string(ID_component_name); + const auto &field_name=arg0.get_string(ID_component_name); symbol_expr.set_identifier(arg0.get_string(ID_class)+"."+field_name); results[0]=java_bytecode_promotion(symbol_expr); @@ -1636,7 +1636,7 @@ codet java_bytecode_convert_methodt::convert_instructions( { assert(op.size()==1 && results.empty()); symbol_exprt symbol_expr(arg0.type()); - const auto& field_name=arg0.get_string(ID_component_name); + const auto &field_name=arg0.get_string(ID_component_name); symbol_expr.set_identifier(arg0.get_string(ID_class)+"."+field_name); c=code_assignt(symbol_expr, op[0]); } @@ -1715,7 +1715,8 @@ codet java_bytecode_convert_methodt::convert_instructions( } if(max_array_length!=0) { - constant_exprt size_limit=from_integer(max_array_length, java_int_type()); + constant_exprt size_limit= + from_integer(max_array_length, java_int_type()); binary_relation_exprt le_max_size(op[0], ID_le, size_limit); code_assumet assume_le_max_size(le_max_size); c.move_to_operands(assume_le_max_size); diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index 8aa79c7bd2b..ca4efee46e3 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -82,7 +82,7 @@ class java_bytecode_convert_methodt:public messaget size_t length; bool is_parameter; std::vector holes; - variablet() : symbol_expr(), is_parameter(false) {} + variablet() : symbol_expr(), start_pc(0), length(0), is_parameter(false) {} }; typedef std::vector variablest; From c54f78a0aeee6a5d733f01bf47b46104188ac418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Tue, 24 Jan 2017 00:10:35 +0100 Subject: [PATCH 091/166] take tautschnig's comments into account --- src/java_bytecode/expr2java.cpp | 2 +- src/java_bytecode/java_bytecode_language.cpp | 16 ++++---- .../java_bytecode_typecheck_expr.cpp | 4 +- src/java_bytecode/java_entry_point.cpp | 40 +++++++++---------- src/java_bytecode/java_object_factory.cpp | 2 +- src/util/json_expr.cpp | 1 + 6 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/java_bytecode/expr2java.cpp b/src/java_bytecode/expr2java.cpp index 8b5966b8afe..1da34a5bd37 100644 --- a/src/java_bytecode/expr2java.cpp +++ b/src/java_bytecode/expr2java.cpp @@ -95,7 +95,7 @@ std::string expr2javat::convert_code_function_call( first=false; else dest+=", "; - // TODO: ggf. Klammern je nach p + // TODO: if necessery add parentheses, dependent on p dest+=arg_str; } } diff --git a/src/java_bytecode/java_bytecode_language.cpp b/src/java_bytecode/java_bytecode_language.cpp index 20b996999d5..4a38e1cf9da 100644 --- a/src/java_bytecode/java_bytecode_language.cpp +++ b/src/java_bytecode/java_bytecode_language.cpp @@ -239,15 +239,13 @@ bool java_bytecode_languaget::final(symbol_tablet &symbol_table) symbolt entry=res.main_function; - if(java_entry_point( - symbol_table, - main_class, - get_message_handler(), - assume_inputs_non_null, - max_nondet_array_length)) - return true; - - return false; + return( + java_entry_point( + symbol_table, + main_class, + get_message_handler(), + assume_inputs_non_null, + max_nondet_array_length)); } /*******************************************************************\ diff --git a/src/java_bytecode/java_bytecode_typecheck_expr.cpp b/src/java_bytecode/java_bytecode_typecheck_expr.cpp index 0c5e8002af0..069aee1830b 100644 --- a/src/java_bytecode/java_bytecode_typecheck_expr.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_expr.cpp @@ -94,8 +94,8 @@ void java_bytecode_typecheckt::typecheck_expr_java_new_array( static void escape_non_alnum(std::string& toescape) { for(auto &ch : toescape) - if(!isalnum(ch)) - ch='_'; + if(!isalnum(ch)) + ch='_'; } /*******************************************************************\ diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index d560bb234fa..67fc10a2fd1 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -10,6 +10,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include #include #include @@ -71,18 +72,6 @@ static void create_initialize(symbol_tablet &symbol_table) } -/*******************************************************************\ - -Function: java_static_lifetime_init - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - static bool should_init_symbol(const symbolt& sym) { if(sym.type.id()!=ID_code && @@ -95,6 +84,18 @@ static bool should_init_symbol(const symbolt& sym) return has_prefix(id2string(sym.name), "java::java.lang.String.Literal"); } +/*******************************************************************\ + +Function: java_static_lifetime_init + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + bool java_static_lifetime_init( symbol_tablet &symbol_table, const source_locationt &source_location, @@ -126,12 +127,11 @@ bool java_static_lifetime_init( std::string namestr=id2string(sym.symbol_expr().get_identifier()); const std::string suffix="@class_model"; // Static '.class' fields are always non-null. - if(namestr.size()>=suffix.size() && - namestr.substr(namestr.size()-suffix.size())==suffix) + if(has_suffix(namestr, suffix)) allow_null=false; if(allow_null && has_prefix( - namestr, - "java::java.lang.String.Literal")) + namestr, + "java::java.lang.String.Literal")) allow_null=false; } auto newsym=object_factory( @@ -208,7 +208,7 @@ exprt::operandst java_build_arguments( { bool is_this=(param_number==0) && parameters[param_number].get_this(); - bool is_default_entry_point(config.main==""); + bool is_default_entry_point(config.main.empty()); bool is_main=is_default_entry_point; if(!is_main) { @@ -244,7 +244,7 @@ exprt::operandst java_build_arguments( input.op0()=address_of_exprt( index_exprt( string_constantt(p_symbol.base_name), - gen_zero(index_type()))); + from_integer(0, index_type()))); input.op1()=main_arguments[param_number]; input.add_source_location()=function.location; @@ -293,7 +293,7 @@ void java_record_outputs( address_of_exprt( index_exprt( string_constantt(return_symbol.base_name), - gen_zero(index_type()))); + from_integer(0, index_type()))); output.op1()=return_symbol.symbol_expr(); output.add_source_location()=function.location; @@ -316,7 +316,7 @@ void java_record_outputs( address_of_exprt( index_exprt( string_constantt(p_symbol.base_name), - gen_zero(index_type()))); + from_integer(0, index_type()))); output.op1()=main_arguments[param_number]; output.add_source_location()=function.location; diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index a02da1a43f0..c9530c59a19 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -514,7 +514,7 @@ Function: new_tmp_symbol symbolt &new_tmp_symbol(symbol_tablet &symbol_table, const std::string& prefix) { - static size_t temporary_counter=0; // TODO change this + static size_t temporary_counter=0; // TODO encapsulate as class variable auxiliary_symbolt new_symbol; symbolt *symbol_ptr; diff --git a/src/util/json_expr.cpp b/src/util/json_expr.cpp index 7d52ca93c31..77f58eb0e18 100644 --- a/src/util/json_expr.cpp +++ b/src/util/json_expr.cpp @@ -16,6 +16,7 @@ Author: Peter Schrammel #include "config.h" #include "json_expr.h" + /*******************************************************************\ Function: json From 1aa5bfd25e15f3a1c88afce8414418571cf7f268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Tue, 24 Jan 2017 15:05:32 +0100 Subject: [PATCH 092/166] assert known Java object size --- src/java_bytecode/java_bytecode_convert_class.cpp | 2 -- src/java_bytecode/java_object_factory.cpp | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 049f6b4ead1..113a8b9422d 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -6,8 +6,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#define DEBUG - #ifdef DEBUG #include #endif diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index c9530c59a19..50e5872abcb 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -126,8 +126,9 @@ exprt java_object_factoryt::allocate_object( // build size expression exprt object_size=size_of_expr(allocate_type, namespacet(symbol_table)); - if(allocate_type.id()!=ID_empty && !object_size.is_nil()) + if(allocate_type.id()!=ID_empty) { + assert(!object_size.is_nil() && "size of Java objects should be known"); // malloc expression exprt malloc_expr=side_effect_exprt(ID_malloc); malloc_expr.copy_to_operands(object_size); From 7c89802aa21627dd24b0665fffdbb18640c3e634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Tue, 24 Jan 2017 15:16:01 +0100 Subject: [PATCH 093/166] remove unused skip_initialize --- src/java_bytecode/java_object_factory.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index 50e5872abcb..bec79c87e55 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -384,7 +384,6 @@ void java_object_factoryt::gen_nondet_array_init( side_effect_exprt java_new_array(ID_java_new_array, expr.type()); java_new_array.copy_to_operands(length_sym_expr); - java_new_array.set("skip_initialize", true); java_new_array.type().subtype().set(ID_C_element_type, element_type); codet assign=code_assignt(expr, java_new_array); assign.add_source_location()=loc; From 950a20237fdf23a8e3c051b1980a8e0a9f478648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Tue, 24 Jan 2017 18:30:04 +0100 Subject: [PATCH 094/166] remove TODOs from expr2java --- src/java_bytecode/expr2java.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/java_bytecode/expr2java.cpp b/src/java_bytecode/expr2java.cpp index 1da34a5bd37..7fb050dddad 100644 --- a/src/java_bytecode/expr2java.cpp +++ b/src/java_bytecode/expr2java.cpp @@ -50,7 +50,6 @@ std::string expr2javat::convert_code_function_call( unsigned p; std::string lhs_str=convert(src.lhs(), p); - // TODO: if necessery add parentheses, dependent on p dest+=lhs_str; dest+='='; } @@ -95,7 +94,6 @@ std::string expr2javat::convert_code_function_call( first=false; else dest+=", "; - // TODO: if necessery add parentheses, dependent on p dest+=arg_str; } } From e3cf2ce482813a7a8f61a351ca25019a600ddf07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Tue, 24 Jan 2017 18:44:17 +0100 Subject: [PATCH 095/166] beautification --- .../java_bytecode_convert_method_class.h | 14 +++++++------- src/java_bytecode/java_bytecode_language.cpp | 2 +- src/java_bytecode/java_bytecode_language.h | 5 +++-- src/java_bytecode/java_bytecode_parser.cpp | 4 ++-- .../java_bytecode_typecheck_expr.cpp | 2 +- src/java_bytecode/java_entry_point.cpp | 10 +++++----- src/java_bytecode/java_local_variable_table.cpp | 16 ++++++++-------- src/java_bytecode/java_object_factory.cpp | 10 +++++----- src/java_bytecode/java_object_factory.h | 4 ++-- src/java_bytecode/java_pointer_casts.cpp | 2 +- 10 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index ca4efee46e3..b5ee7b28f55 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -99,7 +99,7 @@ class java_bytecode_convert_methodt:public messaget codet get_array_bounds_check( const exprt &arraystruct, const exprt &idx, - const source_locationt& original_sloc); + const source_locationt &original_sloc); // return corresponding reference of variable const variablet &find_variable_for_slot( @@ -160,17 +160,17 @@ class java_bytecode_convert_methodt:public messaget protected: void find_initialisers( - local_variable_table_with_holest& vars, - const address_mapt& amap, - const java_cfg_dominatorst& doms); + local_variable_table_with_holest &vars, + const address_mapt &amap, + const java_cfg_dominatorst &doms); void find_initialisers_for_slot( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, - const address_mapt& amap, - const java_cfg_dominatorst& doms); + const address_mapt &amap, + const java_cfg_dominatorst &doms); - void setup_local_variables(const methodt& m, const address_mapt& amap); + void setup_local_variables(const methodt &m, const address_mapt &amap); struct block_tree_nodet { diff --git a/src/java_bytecode/java_bytecode_language.cpp b/src/java_bytecode/java_bytecode_language.cpp index 4a38e1cf9da..1d9d9f57b41 100644 --- a/src/java_bytecode/java_bytecode_language.cpp +++ b/src/java_bytecode/java_bytecode_language.cpp @@ -36,7 +36,7 @@ Function: java_bytecode_languaget::get_language_options \*******************************************************************/ -void java_bytecode_languaget::get_language_options(const cmdlinet& cmd) +void java_bytecode_languaget::get_language_options(const cmdlinet &cmd) { disable_runtime_checks=cmd.isset("disable-runtime-check"); assume_inputs_non_null=cmd.isset("java-assume-inputs-non-null"); diff --git a/src/java_bytecode/java_bytecode_language.h b/src/java_bytecode/java_bytecode_language.h index a62aca0c887..be43a606a8f 100644 --- a/src/java_bytecode/java_bytecode_language.h +++ b/src/java_bytecode/java_bytecode_language.h @@ -19,7 +19,7 @@ Author: Daniel Kroening, kroening@kroening.com class java_bytecode_languaget:public languaget { public: - virtual void get_language_options(const cmdlinet&); + virtual void get_language_options(const cmdlinet &); virtual bool preprocess( std::istream &instream, @@ -42,7 +42,8 @@ class java_bytecode_languaget:public languaget virtual ~java_bytecode_languaget(); java_bytecode_languaget(): max_nondet_array_length(MAX_NONDET_ARRAY_LENGTH_DEFAULT), - max_user_array_length(0) { } + max_user_array_length(0) + {} bool from_expr( const exprt &expr, diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 93f082ecb7d..8fdcb6007d6 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -352,7 +352,7 @@ void java_bytecode_parsert::get_class_refs() } break; - default:{}; + default:{} } } @@ -1243,7 +1243,7 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) } void java_bytecode_parsert::read_verification_type_info( - methodt::verification_type_infot& v) + methodt::verification_type_infot &v) { u1 tag=read_u1(); switch(tag) diff --git a/src/java_bytecode/java_bytecode_typecheck_expr.cpp b/src/java_bytecode/java_bytecode_typecheck_expr.cpp index 069aee1830b..941871d5cd3 100644 --- a/src/java_bytecode/java_bytecode_typecheck_expr.cpp +++ b/src/java_bytecode/java_bytecode_typecheck_expr.cpp @@ -91,7 +91,7 @@ void java_bytecode_typecheckt::typecheck_expr_java_new_array( typecheck_type(type); } -static void escape_non_alnum(std::string& toescape) +static void escape_non_alnum(std::string &toescape) { for(auto &ch : toescape) if(!isalnum(ch)) diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index 67fc10a2fd1..e2c71735fec 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -72,7 +72,7 @@ static void create_initialize(symbol_tablet &symbol_table) } -static bool should_init_symbol(const symbolt& sym) +static bool should_init_symbol(const symbolt &sym) { if(sym.type.id()!=ID_code && sym.is_lvalue && @@ -110,13 +110,13 @@ bool java_static_lifetime_init( // external. Iterate over a copy of the symtab, as its iterators are // invalidated by object_factory: - std::list symnames; + std::list symbol_names; for(const auto &entry : symbol_table.symbols) - symnames.push_back(entry.first); + symbol_names.push_back(entry.first); - for(const auto& symname : symnames) + for(const auto &symname : symbol_names) { - const symbolt& sym=symbol_table.lookup(symname); + const symbolt &sym=symbol_table.lookup(symname); if(should_init_symbol(sym)) { if(sym.value.is_nil() && sym.type!=empty_typet()) diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index dd9e8eee4d1..19580d15094 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -156,9 +156,9 @@ Function: gather_transitive_predecessors \*******************************************************************/ static void gather_transitive_predecessors( - local_variable_with_holest* start, + local_variable_with_holest *start, const predecessor_mapt &predecessor_map, - std::set& result) + std::set &result) { if(!result.insert(start).second) return; @@ -251,7 +251,7 @@ Function: populate_variable_address_map static void populate_variable_address_map( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, - std::vector& live_variable_at_address) + std::vector &live_variable_at_address) { for(auto it=firstvar, itend=varlimit; it!=itend; ++it) { @@ -298,7 +298,7 @@ Function: populate_predecessor_map static void populate_predecessor_map( local_variable_table_with_holest::iterator firstvar, local_variable_table_with_holest::iterator varlimit, - const std::vector& live_variable_at_address, + const std::vector &live_variable_at_address, const address_mapt &amap, predecessor_mapt &predecessor_map, message_handlert &msg_handler) @@ -480,7 +480,7 @@ Function: populate_live_range_holes static void populate_live_range_holes( local_variable_with_holest &merge_into, - const std::set& merge_vars, + const std::set &merge_vars, unsigned expanded_live_range_start) { std::vector sorted_by_startpc( @@ -518,7 +518,7 @@ Function: merge_variable_table_entries static void merge_variable_table_entries( local_variable_with_holest &merge_into, - const std::set& merge_vars, + const std::set &merge_vars, const java_cfg_dominatorst &dominator_analysis, std::ostream &debug_out) { @@ -729,7 +729,7 @@ Function: cleanup_var_table \*******************************************************************/ static void cleanup_var_table( - std::vector& vars_with_holes) + std::vector &vars_with_holes) { size_t toremove=0; for(size_t i=0; i<(vars_with_holes.size()-toremove); ++i) @@ -795,7 +795,7 @@ void java_bytecode_convert_methodt::setup_local_variables( // to calculate which variable to use, one uses the address of the instruction // that uses the variable, the size of the instruction and the start_pc / // length values in the local variable table - for(const auto & v : vars_with_holes) + for(const auto &v : vars_with_holes) { if(v.var.start_pc==0) // Parameter? continue; diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index bec79c87e55..f8f3d98748f 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -49,7 +49,7 @@ class java_object_factoryt:public messaget public: java_object_factoryt( - code_blockt& _init_code, + code_blockt &_init_code, bool _assume_non_null, size_t _max_nondet_array_length, symbol_tablet &_symbol_table, @@ -63,8 +63,8 @@ class java_object_factoryt:public messaget {} exprt allocate_object( - const exprt&, - const typet&, + const exprt &, + const typet &, const source_locationt &, bool create_dynamic_objects); @@ -512,7 +512,7 @@ Function: new_tmp_symbol \*******************************************************************/ -symbolt &new_tmp_symbol(symbol_tablet &symbol_table, const std::string& prefix) +symbolt &new_tmp_symbol(symbol_tablet &symbol_table, const std::string &prefix) { static size_t temporary_counter=0; // TODO encapsulate as class variable @@ -542,7 +542,7 @@ Function: get_nondet_bool \*******************************************************************/ -exprt get_nondet_bool(const typet& type) +exprt get_nondet_bool(const typet &type) { // We force this to 0 and 1 and won't consider // other values. diff --git a/src/java_bytecode/java_object_factory.h b/src/java_bytecode/java_object_factory.h index 13d933d9da5..d111948e365 100644 --- a/src/java_bytecode/java_object_factory.h +++ b/src/java_bytecode/java_object_factory.h @@ -34,10 +34,10 @@ void gen_nondet_init( size_t max_nondet_array_length=5); -exprt get_nondet_bool(const typet&); +exprt get_nondet_bool(const typet &); symbolt &new_tmp_symbol( symbol_tablet &symbol_table, - const std::string& prefix="tmp_object_factory"); + const std::string &prefix="tmp_object_factory"); #endif // CPROVER_JAVA_BYTECODE_JAVA_OBJECT_FACTORY_H diff --git a/src/java_bytecode/java_pointer_casts.cpp b/src/java_bytecode/java_pointer_casts.cpp index 934e6cfb135..174bad0a9b1 100644 --- a/src/java_bytecode/java_pointer_casts.cpp +++ b/src/java_bytecode/java_pointer_casts.cpp @@ -89,7 +89,7 @@ Function: look_through_casts \*******************************************************************/ -static const exprt& look_through_casts(const exprt& in) +static const exprt &look_through_casts(const exprt &in) { if(in.id()==ID_typecast) { From 48b00d63708d13db9c5383d918a39f5f9a8e8643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Tue, 24 Jan 2017 18:48:30 +0100 Subject: [PATCH 096/166] change "* "->" *", too --- .../java_local_variable_table.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/java_bytecode/java_local_variable_table.cpp b/src/java_bytecode/java_local_variable_table.cpp index 19580d15094..3cfb5030136 100644 --- a/src/java_bytecode/java_local_variable_table.cpp +++ b/src/java_bytecode/java_local_variable_table.cpp @@ -109,8 +109,8 @@ static bool lt_index( return a.var.indexvar.start_pcvar.start_pc; } @@ -118,8 +118,8 @@ static bool lt_startpc( // The predecessor map, and a top-sorting comparator: typedef std::map< - local_variable_with_holest*, - std::set > + local_variable_with_holest *, + std::set > predecessor_mapt; struct is_predecessor_oft @@ -129,8 +129,8 @@ struct is_predecessor_oft explicit is_predecessor_oft(const predecessor_mapt &_order) : order(_order) {} bool operator()( - local_variable_with_holest* a, - local_variable_with_holest* b) const + local_variable_with_holest *a, + local_variable_with_holest *b) const { auto findit=order.find(a); if(findit==order.end()) @@ -483,7 +483,7 @@ static void populate_live_range_holes( const std::set &merge_vars, unsigned expanded_live_range_start) { - std::vector sorted_by_startpc( + std::vector sorted_by_startpc( merge_vars.begin(), merge_vars.end()); std::sort(sorted_by_startpc.begin(), sorted_by_startpc.end(), lt_startpc); @@ -591,7 +591,7 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( // Build a simple map from instruction PC to the variable // live in this slot at that PC, and a map from each variable // to variables that flow into it: - std::vector live_variable_at_address; + std::vector live_variable_at_address; populate_variable_address_map(firstvar, varlimit, live_variable_at_address); // Now find variables that flow together by @@ -612,14 +612,14 @@ void java_bytecode_convert_methodt::find_initialisers_for_slot( // Take the transitive closure of the predecessor map: for(auto &kv : predecessor_map) { - std::set closed_preds; + std::set closed_preds; gather_transitive_predecessors(kv.first, predecessor_map, closed_preds); kv.second=std::move(closed_preds); } // Top-sort so that we get the bottom variables first: is_predecessor_oft comp(predecessor_map); - std::vector topsorted_vars; + std::vector topsorted_vars; for(auto it=firstvar, itend=varlimit; it!=itend; ++it) topsorted_vars.push_back(&*it); From 8786af724333895bc4ea4f7ac0d0d92ae3b0a7a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Wed, 25 Jan 2017 21:32:45 +0100 Subject: [PATCH 097/166] adapt NullPointer2 regression test --- regression/cbmc-java/NullPointer2/test.desc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression/cbmc-java/NullPointer2/test.desc b/regression/cbmc-java/NullPointer2/test.desc index a794ca8ac88..f89103d5f52 100644 --- a/regression/cbmc-java/NullPointer2/test.desc +++ b/regression/cbmc-java/NullPointer2/test.desc @@ -3,7 +3,7 @@ NullPointer2.class --pointer-check --stop-on-fail ^EXIT=10$ ^SIGNAL=0$ -^ file NullPointer2.java line 9 function java::NullPointer2.main:(\[Ljava/lang/String;)V bytecode_index 1$ +^ file NullPointer2.java line 9 function java::NullPointer2.main:(\[Ljava/lang/String;)V$ ^VERIFICATION FAILED$ -- ^warning: ignoring From 4669ef3d46c3f52136d5ea8f913b97774691ad33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Wed, 25 Jan 2017 22:14:23 +0100 Subject: [PATCH 098/166] adapt interface in CEGIS with default values --- src/cegis/refactor/constraint/constraint_factory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cegis/refactor/constraint/constraint_factory.cpp b/src/cegis/refactor/constraint/constraint_factory.cpp index abe6d33e4fa..42a2c324f71 100644 --- a/src/cegis/refactor/constraint/constraint_factory.cpp +++ b/src/cegis/refactor/constraint/constraint_factory.cpp @@ -41,7 +41,7 @@ void create_or_redirect_entry(symbol_tablet &st, goto_functionst &gf) if (fmap.end() == it) { config.main=CONSTRAINT_CALLER; - assert(!java_entry_point(st, ID_empty, msg)); + assert(!java_entry_point(st, ID_empty, msg, false, 0)); goto_convert(CPROVER_INIT, st, gf, msg); goto_convert(goto_functionst::entry_point(), st, gf, msg); } else From 0230b0d09d892deabf64b860353da80fd48f1f9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Wed, 25 Jan 2017 22:21:31 +0100 Subject: [PATCH 099/166] whitespace in front of { --- src/java_bytecode/java_bytecode_parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 8fdcb6007d6..7138ab3951b 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -352,7 +352,7 @@ void java_bytecode_parsert::get_class_refs() } break; - default:{} + default: {} } } From fcbd267522a66c62f35db545e890e2d6f4504446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 30 Jan 2017 03:21:27 +0100 Subject: [PATCH 100/166] get_language options to language API (#480) Adds call to `get_language_options` to the language API. Prevents an uninitialized bool error in the Java front-end. --- src/java_bytecode/java_bytecode_language.h | 2 +- src/langapi/language_ui.cpp | 1 + src/util/language.h | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/java_bytecode/java_bytecode_language.h b/src/java_bytecode/java_bytecode_language.h index be43a606a8f..5937f6f4fd4 100644 --- a/src/java_bytecode/java_bytecode_language.h +++ b/src/java_bytecode/java_bytecode_language.h @@ -19,7 +19,7 @@ Author: Daniel Kroening, kroening@kroening.com class java_bytecode_languaget:public languaget { public: - virtual void get_language_options(const cmdlinet &); + virtual void get_language_options(const cmdlinet &) override; virtual bool preprocess( std::istream &instream, diff --git a/src/langapi/language_ui.cpp b/src/langapi/language_ui.cpp index d409dc1947e..3775c3c6125 100644 --- a/src/langapi/language_ui.cpp +++ b/src/langapi/language_ui.cpp @@ -121,6 +121,7 @@ bool language_uit::parse(const std::string &filename) languaget &language=*lf.language; language.set_message_handler(get_message_handler()); + language.get_language_options(_cmdline); status() << "Parsing " << filename << eom; diff --git a/src/util/language.h b/src/util/language.h index ddb2702954a..edd83471cd5 100644 --- a/src/util/language.h +++ b/src/util/language.h @@ -19,10 +19,14 @@ class symbol_tablet; class exprt; class namespacet; class typet; +class cmdlinet; class languaget:public messaget { public: + // Parse language-specific options + virtual void get_language_options(const cmdlinet &) {} + // parse file virtual bool preprocess( From a2010c88cc508f2ee18b8cbb6b2462fd6a143125 Mon Sep 17 00:00:00 2001 From: Pascal Kesseli Date: Mon, 30 Jan 2017 14:54:25 +0000 Subject: [PATCH 101/166] Added check for div by zero in CEGIS control rational back end. Rational back-end was liable to div by zero in its GOTO programs at various precision. Fixed this using an explicit check. --- .../cegis_control_benchmark_05/SatelliteB2.c | 5311 +++++++++++++++++ .../cegis_control_benchmark_05.zip | Bin 0 -> 109010 bytes .../cegis_control_benchmark_05/controller.h | 1 + .../cegis/cegis_control_benchmark_05/plant.h | 1 + .../simplified_noise.c | 518 ++ .../cegis/cegis_control_benchmark_05/sizes.h | 6 + .../cegis_control_benchmark_05/test.desc | 7 + 7 files changed, 5844 insertions(+) create mode 100644 regression/cegis/cegis_control_benchmark_05/SatelliteB2.c create mode 100644 regression/cegis/cegis_control_benchmark_05/cegis_control_benchmark_05.zip create mode 100644 regression/cegis/cegis_control_benchmark_05/controller.h create mode 100644 regression/cegis/cegis_control_benchmark_05/plant.h create mode 100644 regression/cegis/cegis_control_benchmark_05/simplified_noise.c create mode 100644 regression/cegis/cegis_control_benchmark_05/sizes.h create mode 100644 regression/cegis/cegis_control_benchmark_05/test.desc diff --git a/regression/cegis/cegis_control_benchmark_05/SatelliteB2.c b/regression/cegis/cegis_control_benchmark_05/SatelliteB2.c new file mode 100644 index 00000000000..65f807bfbeb --- /dev/null +++ b/regression/cegis/cegis_control_benchmark_05/SatelliteB2.c @@ -0,0 +1,5311 @@ +// tag-#anon#ST[ARR100{F64}$F64$'a'|S32'a_size'|U32'$pad0'|ARR100{F64}$F64$'b'|S32'b_size'|U32'$pad1'|F64'sample_time'|ARR100{F64}$F64$'a_uncertainty'|ARR100{F64}$F64$'b_uncertainty'] +// file /home/lucascordeiro/dsverifier/bmc/core/definitions.h line 144 +struct anonymous$0; + +// tag-#anon#ST[ARR20{ARR20{F64}$F64$}$ARR20{F64}$F64$$'A'|ARR20{ARR20{F64}$F64$}$ARR20{F64}$F64$$'B'|ARR20{ARR20{F64}$F64$}$ARR20{F64}$F64$$'C'|ARR20{ARR20{F64}$F64$}$ARR20{F64}$F64$$'D'|ARR20{ARR20{F64}$F64$}$ARR20{F64}$F64$$'states'|ARR20{ARR20{F64}$F64$}$ARR20{F64}$F64$$'outputs'|ARR20{ARR20{F64}$F64$}$ARR20{F64}$F64$$'inputs'|ARR20{ARR20{F64}$F64$}$ARR20{F64}$F64$$'K'|U32'nStates'|U32'nInputs'|U32'nOutputs'|U32'$pad0'] +// file /home/lucascordeiro/dsverifier/bmc/core/definitions.h line 156 +struct anonymous$1; + +// tag-#anon#ST[S32'int_bits'|S32'frac_bits'|F64'max'|F64'min'|S32'default_realization'|U32'$pad0'|F64'delta'|S32'scale'|U32'$pad1'|F64'max_error'] +// file /home/lucascordeiro/dsverifier/bmc/core/definitions.h line 171 +struct anonymous$3; + +// tag-#anon#ST[S32'push'|S32'in'|S32'sbiw'|S32'cli'|S32'out'|S32'std'|S32'ldd'|S32'subi'|S32'sbci'|S32'lsl'|S32'rol'|S32'add'|S32'adc'|S32'adiw'|S32'rjmp'|S32'mov'|S32'sbc'|S32'ld'|S32'rcall'|S32'cp'|S32'cpc'|S32'ldi'|S32'brge'|S32'pop'|S32'ret'|S32'st'|S32'brlt'|S32'cpi'] +// file /home/lucascordeiro/dsverifier/bmc/core/definitions.h line 183 +struct anonymous; + +// tag-#anon#ST[S64'clock'|S32'device'|U32'$pad0'|F64'cycle'|SYM#tag-#anon#ST[S32'push'|S32'in'|S32'sbiw'|S32'cli'|S32'out'|S32'std'|S32'ldd'|S32'subi'|S32'sbci'|S32'lsl'|S32'rol'|S32'add'|S32'adc'|S32'adiw'|S32'rjmp'|S32'mov'|S32'sbc'|S32'ld'|S32'rcall'|S32'cp'|S32'cpc'|S32'ldi'|S32'brge'|S32'pop'|S32'ret'|S32'st'|S32'brlt'|S32'cpi']#'assembly'] +// file /home/lucascordeiro/dsverifier/bmc/core/definitions.h line 215 +struct anonymous$2; + +#include + +#ifndef IEEE_FLOAT_EQUAL +#define IEEE_FLOAT_EQUAL(x,y) ((x)==(y)) +#endif +#ifndef IEEE_FLOAT_NOTEQUAL +#define IEEE_FLOAT_NOTEQUAL(x,y) ((x)!=(y)) +#endif + +// __DSVERIFIER_assert +// file /home/lucascordeiro/dsverifier/bmc/core/compatibility.h line 35 +void __DSVERIFIER_assert(_Bool expression); +// __DSVERIFIER_assert_msg +// file /home/lucascordeiro/dsverifier/bmc/core/compatibility.h line 39 +void __DSVERIFIER_assert_msg(_Bool expression, char *msg); +// __DSVERIFIER_assume +// file /home/lucascordeiro/dsverifier/bmc/core/compatibility.h line 21 +void __DSVERIFIER_assume(_Bool expression); +// __assert_fail +// file /usr/include/assert.h line 67 +extern void __assert_fail(const char *, const char *, unsigned int, const char *) _Noreturn; +// call_closedloop_verification_task +// file /home/lucascordeiro/dsverifier/bmc/dsverifier.h line 369 +void call_closedloop_verification_task(void *closedloop_verification_task); +// call_verification_task +// file /home/lucascordeiro/dsverifier/bmc/dsverifier.h line 268 +void call_verification_task(void *verification_task); +// check_stability +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 59 +signed int check_stability(double *a, signed int n); +// check_stability_closedloop +// file /home/lucascordeiro/dsverifier/bmc/core/closed-loop.h line 70 +signed int check_stability_closedloop(double *a, signed int n, double *plant_num, signed int p_num_size, double *plant_den, signed int p_den_size); +// determinant +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 498 +double determinant(double (*a)[20l], signed int n); +// double_add_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 315 +void double_add_matrix(unsigned int lines, unsigned int columns, double (*m1)[20l], double (*m2)[20l], double (*result)[20l]); +// double_check_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 218 +void double_check_limit_cycle(double *y, signed int y_size); +// double_check_oscillations +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 187 +void double_check_oscillations(double *y, signed int y_size); +// double_check_persistent_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 254 +void double_check_persistent_limit_cycle(double *y, signed int y_size); +// double_direct_form_1 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 83 +double double_direct_form_1(double *y, double *x, double *a, double *b, signed int Na, signed int Nb); +// double_direct_form_1_MSP430 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 205 +double double_direct_form_1_MSP430(double *y, double *x, double *a, double *b, signed int Na, signed int Nb); +// double_direct_form_1_impl2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 364 +void double_direct_form_1_impl2(double *x, signed int x_size, double *b, signed int b_size, double *a, signed int a_size, double *y); +// double_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 102 +double double_direct_form_2(double *w, double x, double *a, double *b, signed int Na, signed int Nb); +// double_direct_form_2_MSP430 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 230 +double double_direct_form_2_MSP430(double *w, double x, double *a, double *b, signed int Na, signed int Nb); +// double_exp_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 428 +void double_exp_matrix(unsigned int lines, unsigned int columns, double (*m1)[20l], unsigned int expNumber, double (*result)[20l]); +// double_matrix_multiplication +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 337 +void double_matrix_multiplication(unsigned int i1, unsigned int j1, unsigned int i2, unsigned int j2, double (*m1)[20l], double (*m2)[20l], double (*m3)[20l]); +// double_state_space_representation +// file /home/lucascordeiro/dsverifier/bmc/core/state-space.h line 23 +double double_state_space_representation(void); +// double_sub_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 326 +void double_sub_matrix(unsigned int lines, unsigned int columns, double (*m1)[20l], double (*m2)[20l], double (*result)[20l]); +// double_transposed_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 122 +double double_transposed_direct_form_2(double *w, double x, double *a, double *b, signed int Na, signed int Nb); +// double_transposed_direct_form_2_MSP430 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 257 +double double_transposed_direct_form_2_MSP430(double *w, double x, double *a, double *b, signed int Na, signed int Nb); +// exit +// file /usr/include/stdlib.h line 543 +extern void exit(signed int) _Noreturn; +// fatorial +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 54 +signed int fatorial(signed int n); +// float_direct_form_1 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 144 +float float_direct_form_1(float *y, float *x, float *a, float *b, signed int Na, signed int Nb); +// float_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 163 +float float_direct_form_2(float *w, float x, float *a, float *b, signed int Na, signed int Nb); +// float_transposed_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 183 +float float_transposed_direct_form_2(float *w, float x, float *a, float *b, signed int Na, signed int Nb); +// ft_closedloop_feedback +// file /home/lucascordeiro/dsverifier/bmc/core/closed-loop.h line 57 +void ft_closedloop_feedback(double *c_num, signed int Nc_num, double *c_den, signed int Nc_den, double *model_num, signed int Nmodel_num, double *model_den, signed int Nmodel_den, double *ans_num, signed int Nans_num, double *ans_den, signed int Nans_den); +// ft_closedloop_sensitivity +// file /home/lucascordeiro/dsverifier/bmc/core/closed-loop.h line 42 +void ft_closedloop_sensitivity(double *c_num, signed int Nc_num, double *c_den, signed int Nc_den, double *model_num, signed int Nmodel_num, double *model_den, signed int Nmodel_den, double *ans_num, signed int Nans_num, double *ans_den, signed int Nans_den); +// ft_closedloop_series +// file /home/lucascordeiro/dsverifier/bmc/core/closed-loop.h line 28 +void ft_closedloop_series(double *c_num, signed int Nc_num, double *c_den, signed int Nc_den, double *model_num, signed int Nmodel_num, double *model_den, signed int Nmodel_den, double *ans_num, signed int Nans_num, double *ans_den, signed int Nans_den); +// fxp_abs +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 303 +signed long int fxp_abs(signed long int a); +// fxp_add +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 315 +signed long int fxp_add(signed long int aadd, signed long int badd); +// fxp_add_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 467 +void fxp_add_matrix(unsigned int lines, unsigned int columns, signed long int (*m1)[20l], signed long int (*m2)[20l], signed long int (*result)[20l]); +// fxp_check_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 163 +void fxp_check_limit_cycle(signed long int *y, signed int y_size); +// fxp_check_oscillations +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 253 +void fxp_check_oscillations(signed long int *y, signed int y_size); +// fxp_check_persistent_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 201 +void fxp_check_persistent_limit_cycle(signed long int *y, signed int y_size); +// fxp_determinant +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 529 +double fxp_determinant(signed long int (*a_fxp)[20l], signed int n); +// fxp_direct_form_1 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 22 +signed long int fxp_direct_form_1(signed long int *y, signed long int *x, signed long int *a, signed long int *b, signed int Na, signed int Nb); +// fxp_direct_form_1_impl2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 388 +void fxp_direct_form_1_impl2(signed long int *x, signed int x_size, signed long int *b, signed int b_size, signed long int *a, signed int a_size, signed long int *y); +// fxp_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 41 +signed long int fxp_direct_form_2(signed long int *w, signed long int x, signed long int *a, signed long int *b, signed int Na, signed int Nb); +// fxp_div +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 357 +signed long int fxp_div(signed long int a, signed long int b); +// fxp_double_to_fxp +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 211 +signed long int fxp_double_to_fxp(double value); +// fxp_double_to_fxp_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 247 +void fxp_double_to_fxp_array(double *f, signed long int *r, signed int N); +// fxp_exp_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 390 +void fxp_exp_matrix(unsigned int lines, unsigned int columns, signed long int (*m1)[20l], unsigned int expNumber, signed long int (*result)[20l]); +// fxp_float_to_fxp +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 198 +signed long int fxp_float_to_fxp(float f); +// fxp_float_to_fxp_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 240 +void fxp_float_to_fxp_array(float *f, signed long int *r, signed int N); +// fxp_get_frac_part +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 125 +signed long int fxp_get_frac_part(signed long int in); +// fxp_get_int_part +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 115 +signed long int fxp_get_int_part(signed long int in); +// fxp_int_to_fxp +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 170 +signed long int fxp_int_to_fxp(signed int in); +// fxp_ln +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 288 +signed int fxp_ln(signed int x); +// fxp_log10 +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 345 +double fxp_log10(double x); +// fxp_log10_low +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 333 +double fxp_log10_low(double x); +// fxp_matrix_multiplication +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 368 +void fxp_matrix_multiplication(unsigned int i1, unsigned int j1, unsigned int i2, unsigned int j2, signed long int (*m1)[20l], signed long int (*m2)[20l], signed long int (*m3)[20l]); +// fxp_mult +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 339 +signed long int fxp_mult(signed long int amult, signed long int bmult); +// fxp_neg +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 367 +signed long int fxp_neg(signed long int aneg); +// fxp_print_float +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 407 +void fxp_print_float(signed long int a); +// fxp_print_float_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 411 +void fxp_print_float_array(signed long int *a, signed int N); +// fxp_print_int +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 403 +void fxp_print_int(signed long int a); +// fxp_quantize +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 136 +signed long int fxp_quantize(signed long int aquant); +// fxp_shrl +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 390 +signed long int fxp_shrl(signed long int in, signed int shift); +// fxp_sign +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 380 +signed long int fxp_sign(signed long int a); +// fxp_square +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 399 +signed long int fxp_square(signed long int a); +// fxp_state_space_representation +// file /home/lucascordeiro/dsverifier/bmc/core/state-space.h line 67 +double fxp_state_space_representation(void); +// fxp_sub +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 327 +signed long int fxp_sub(signed long int asub, signed long int bsub); +// fxp_sub_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 474 +void fxp_sub_matrix(unsigned int lines, unsigned int columns, signed long int (*m1)[20l], signed long int (*m2)[20l], signed long int (*result)[20l]); +// fxp_to_double +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 271 +double fxp_to_double(signed long int fxp); +// fxp_to_double_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 291 +void fxp_to_double_array(double *f, signed long int *r, signed int N); +// fxp_to_float +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 264 +float fxp_to_float(signed long int fxp); +// fxp_to_float_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 284 +void fxp_to_float_array(float *f, signed long int *r, signed int N); +// fxp_to_int +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 182 +signed int fxp_to_int(signed long int fxp); +// fxp_transpose +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 582 +void fxp_transpose(signed long int (*a)[20l], signed long int (*b)[20l], signed int n, signed int m); +// fxp_transposed_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 61 +signed long int fxp_transposed_direct_form_2(signed long int *w, signed long int x, signed long int *a, signed long int *b, signed int Na, signed int Nb); +// fxp_verify_overflow +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 153 +void fxp_verify_overflow(signed long int value); +// fxp_verify_overflow_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 158 +void fxp_verify_overflow_array(signed long int *array, signed int n); +// generate_delta_coefficients +// file /home/lucascordeiro/dsverifier/bmc/core/delta-operator.h line 33 +void generate_delta_coefficients(double *vetor, double *out, signed int n, double delta); +// generic_timing_double_direct_form_1 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 286 +double generic_timing_double_direct_form_1(double *y, double *x, double *a, double *b, signed int Na, signed int Nb); +// generic_timing_double_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 311 +double generic_timing_double_direct_form_2(double *w, double x, double *a, double *b, signed int Na, signed int Nb); +// generic_timing_double_transposed_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 338 +double generic_timing_double_transposed_direct_form_2(double *w, double x, double *a, double *b, signed int Na, signed int Nb); +// generic_timing_shift_l_double +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 20 +double generic_timing_shift_l_double(double zIn, double *z, signed int N); +// generic_timing_shift_r_double +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 37 +double generic_timing_shift_r_double(double zIn, double *z, signed int N); +// get_delta_transfer_function +// file /home/lucascordeiro/dsverifier/bmc/core/delta-operator.h line 52 +void get_delta_transfer_function(double *b, double *b_out, signed int b_size, double *a, double *a_out, signed int a_size, double delta); +// get_delta_transfer_function_with_base +// file /home/lucascordeiro/dsverifier/bmc/core/delta-operator.h line 59 +void get_delta_transfer_function_with_base(double *b, double *b_out, signed int b_size, double *a, double *a_out, signed int a_size, double delta); +// iirIIOutTime +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 428 +float iirIIOutTime(float *w, float x, float *a, float *b, signed int Na, signed int Nb); +// iirIItOutTime +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 452 +float iirIItOutTime(float *w, float x, float *a, float *b, signed int Na, signed int Nb); +// iirIItOutTime_double +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 479 +double iirIItOutTime_double(double *w, double x, double *a, double *b, signed int Na, signed int Nb); +// iirOutBoth +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 506 +void iirOutBoth(float *yf, float *xf, float *af, float *bf, float *sumf_ref, signed long int *y, signed long int *x, signed long int *a, signed long int *b, signed long int *sum_ref, signed int Na, signed int Nb); +// iirOutBothL +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 586 +float iirOutBothL(float *yf, float *xf, float *af, float *bf, float xfin, signed long int *y, signed long int *x, signed long int *a, signed long int *b, signed long int xin, signed int Na, signed int Nb); +// iirOutBothL2 +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 626 +float iirOutBothL2(float *yf, float *xf, float *af, float *bf, float xfin, signed long int *y, signed long int *x, signed long int *a, signed long int *b, signed long int xin, signed int Na, signed int Nb); +// iirOutFixedL +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 536 +signed long int iirOutFixedL(signed long int *y, signed long int *x, signed long int xin, signed long int *a, signed long int *b, signed int Na, signed int Nb); +// iirOutFloatL +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 561 +float iirOutFloatL(float *y, float *x, float xin, float *a, float *b, signed int Na, signed int Nb); +// initialization +// file /home/lucascordeiro/dsverifier/bmc/core/initialization.h line 24 +void initialization(); +// initialize_array +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 22 +void initialize_array(double *v, signed int n); +// initials +// file /home/lucascordeiro/dsverifier/bmc/dsverifier.h line 52 +extern void initials(); +// internal_abs +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 49 +double internal_abs(double a); +// internal_pow +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 39 +double internal_pow(double a, double b); +// nchoosek +// file /home/lucascordeiro/dsverifier/bmc/core/delta-operator.h line 23 +signed int nchoosek(signed int n, signed int k); +// nondet_double +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_limit_cycle_closedloop.h line 27 +double nondet_double(); +// nondet_float +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_overflow.h line 18 +float nondet_float(); +// nondet_int +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_overflow.h line 17 +signed int nondet_int(); +// order +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 158 +signed int order(signed int Na, signed int Nb); +// poly_mult +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 165 +void poly_mult(double *a, signed int Na, double *b, signed int Nb, double *ans, signed int Nans); +// poly_sum +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 141 +void poly_sum(double *a, signed int Na, double *b, signed int Nb, double *ans, signed int Nans); +// print_array_elements +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 305 +void print_array_elements(char *name, double *v, signed int n); +// print_fxp_array_elements +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 419 +void print_fxp_array_elements(char *name, signed long int *v, signed int n); +// print_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 481 +void print_matrix(double (*matrix)[20l], unsigned int lines, unsigned int columns); +// printf +// file /usr/include/stdio.h line 362 +extern signed int printf(const char *, ...); +// rand +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 417 +extern signed int rand(void); +// revert_array +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 30 +void revert_array(double *v, double *out, signed int n); +// shiftL +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 53 +signed long int shiftL(signed long int zIn, signed long int *z, signed int N); +// shiftLDouble +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 119 +double shiftLDouble(double zIn, double *z, signed int N); +// shiftLboth +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 130 +void shiftLboth(float zfIn, float *zf, signed long int zIn, signed long int *z, signed int N); +// shiftLfloat +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 75 +float shiftLfloat(float zIn, float *z, signed int N); +// shiftR +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 64 +signed long int shiftR(signed long int zIn, signed long int *z, signed int N); +// shiftRDdouble +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 97 +double shiftRDdouble(double zIn, double *z, signed int N); +// shiftRboth +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 144 +void shiftRboth(float zfIn, float *zf, signed long int zIn, signed long int *z, signed int N); +// shiftRdouble +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 108 +double shiftRdouble(double zIn, double *z, signed int N); +// shiftRfloat +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 86 +float shiftRfloat(float zIn, float *z, signed int N); +// snrPoint +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 402 +float snrPoint(float *s, float *n, signed int blksz); +// snrPower +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 381 +float snrPower(float *s, float *n, signed int blksz); +// snrVariance +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 357 +float snrVariance(float *s, float *n, signed int blksz); +// srand +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 423 +extern void srand(unsigned int seed); +// transpose +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 571 +void transpose(double (*a)[20l], double (*b)[20l], signed int n, signed int m); +// validation +// file /home/lucascordeiro/dsverifier/bmc/dsverifier.h line 125 +void validation(); +// verify_controllability +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_controllability.h line 16 +signed int verify_controllability(void); +// verify_controllability_double +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_controllability.h line 120 +signed int verify_controllability_double(void); +// verify_error +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_error.h line 20 +signed int verify_error(void); +// verify_error_closedloop +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_error_closedloop.h line 27 +signed int verify_error_closedloop(void); +// verify_error_state_space +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_error_state_space.h line 20 +signed int verify_error_state_space(void); +// verify_generic_timing +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_generic_timing.h line 25 +signed int verify_generic_timing(void); +// verify_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_limit_cycle.h line 111 +signed int verify_limit_cycle(void); +// verify_limit_cycle_closed_loop +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_limit_cycle_closedloop.h line 29 +signed int verify_limit_cycle_closed_loop(void); +// verify_limit_cycle_state_space +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_limit_cycle.h line 21 +signed int verify_limit_cycle_state_space(void); +// verify_minimum_phase +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_minimum_phase.h line 24 +signed int verify_minimum_phase(void); +// verify_observability +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_observability.h line 19 +signed int verify_observability(void); +// verify_overflow +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_overflow.h line 23 +signed int verify_overflow(void); +// verify_stability +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_stability.h line 24 +signed int verify_stability(void); +// verify_stability_closedloop_using_dslib +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_stability_closedloop.h line 21 +signed int verify_stability_closedloop_using_dslib(void); +// verify_timing_msp_430 +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_timing_msp430.h line 22 +signed int verify_timing_msp_430(void); +// verify_zero_input_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_zero_input_limit_cycle.h line 16 +signed int verify_zero_input_limit_cycle(void); +// wrap +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 100 +signed long int wrap(signed long int kX, signed long int kLowerBound, signed long int kUpperBound); + +struct anonymous$0 +{ + // a + double a[100l]; + // a_size + signed int a_size; + // b + double b[100l]; + // b_size + signed int b_size; + // sample_time + double sample_time; + // a_uncertainty + double a_uncertainty[100l]; + // b_uncertainty + double b_uncertainty[100l]; +}; + +struct anonymous$1 +{ + // A + double A[20l][20l]; + // B + double B[20l][20l]; + // C + double C[20l][20l]; + // D + double D[20l][20l]; + // states + double states[20l][20l]; + // outputs + double outputs[20l][20l]; + // inputs + double inputs[20l][20l]; + // K + double K[20l][20l]; + // nStates + unsigned int nStates; + // nInputs + unsigned int nInputs; + // nOutputs + unsigned int nOutputs; +}; + +struct anonymous$3 +{ + // int_bits + signed int int_bits; + // frac_bits + signed int frac_bits; + // max + double max; + // min + double min; + // default_realization + signed int default_realization; + // delta + double delta; + // scale + signed int scale; + // max_error + double max_error; +}; + +struct anonymous +{ + // push + signed int push; + // in + signed int in; + // sbiw + signed int sbiw; + // cli + signed int cli; + // out + signed int out; + // std + signed int std; + // ldd + signed int ldd; + // subi + signed int subi; + // sbci + signed int sbci; + // lsl + signed int lsl; + // rol + signed int rol; + // add + signed int add; + // adc + signed int adc; + // adiw + signed int adiw; + // rjmp + signed int rjmp; + // mov + signed int mov; + // sbc + signed int sbc; + // ld + signed int ld; + // rcall + signed int rcall; + // cp + signed int cp; + // cpc + signed int cpc; + // ldi + signed int ldi; + // brge + signed int brge; + // pop + signed int pop; + // ret + signed int ret; + // st + signed int st; + // brlt + signed int brlt; + // cpi + signed int cpi; +}; + +struct anonymous$2 +{ + // clock + signed long int clock; + // device + signed int device; + // cycle + double cycle; + // assembly + struct anonymous assembly; +}; + + +// X_SIZE_VALUE +// file /home/lucascordeiro/dsverifier/bmc/core/definitions.h line 121 +signed int X_SIZE_VALUE=0; +// _controller +// file /home/lucascordeiro/dsverifier/bmc/core/state-space.h line 17 +extern struct anonymous$1 _controller; +// _dbl_max +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 45 +double _dbl_max; +// _dbl_min +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 46 +double _dbl_min; +// _fxp_fmask +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 49 +signed long int _fxp_fmask; +// _fxp_half +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 39 +signed long int _fxp_half; +// _fxp_imask +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 52 +signed long int _fxp_imask; +// _fxp_max +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 42 +signed long int _fxp_max; +// _fxp_min +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 41 +signed long int _fxp_min; +// _fxp_minus_one +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 40 +signed long int _fxp_minus_one; +// _fxp_one +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 38 +signed long int _fxp_one; +// controller +// file input.c line 3 +struct anonymous$0 controller={ .a={ 1.000000, (double)-4.200000e-1f, (double)-3.465000e-1f, (double)-3.915000e-2f, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 }, .a_size=4, + .b={ 2.880000e+0, (double)-4.896000e+0f, 2.074000e+0, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 }, .b_size=3, + .sample_time=1.000000, .a_uncertainty={ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 }, .b_uncertainty={ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 } }; +// ds +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 17 +extern struct anonymous$0 ds; +// error_limit +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_error_state_space.h line 18 +extern double error_limit; +// generic_timer +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_generic_timing.h line 23 +signed int generic_timer=0; +// hw +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 18 +extern struct anonymous$2 hw; +// impl +// file input.c line 11 +struct anonymous$3 impl={ .int_bits=3, .frac_bits=7, .max=1.000000, .min=-1.000000, + .default_realization=0, .delta=0.000000, + .scale=1, .max_error=0.000000 }; +// nInputs +// file /home/lucascordeiro/dsverifier/bmc/core/state-space.h line 20 +extern signed int nInputs; +// nOutputs +// file /home/lucascordeiro/dsverifier/bmc/core/state-space.h line 21 +extern signed int nOutputs; +// nStates +// file /home/lucascordeiro/dsverifier/bmc/core/state-space.h line 19 +extern signed int nStates; +// next +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 416 +unsigned long int next=1ul; +// overflow_mode +// file /home/lucascordeiro/dsverifier/bmc/core/definitions.h line 122 +signed int overflow_mode=1; +// plant +// file input.c line 19 +struct anonymous$0 plant={ .a={ 1.000000, (double)-2.000000f, 1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 }, .a_size=3, + .b={ 1.250000e-1, 1.250000e-1, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 }, .b_size=2, + .sample_time=0.000000, .a_uncertainty={ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 }, .b_uncertainty={ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 } }; +// plant_cbmc +// file /home/lucascordeiro/dsverifier/bmc/dsverifier.h line 46 +struct anonymous$0 plant_cbmc; +// rounding_mode +// file /home/lucascordeiro/dsverifier/bmc/core/definitions.h line 123 +signed int rounding_mode=0; +// scale_factor +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 55 +static const double scale_factor[31l]={ 1.000000, 2.000000, 4.000000, 8.000000, 16.000000, 32.000000, 64.000000, 128.000000, 256.000000, 512.000000, 1024.000000, 2048.000000, 4096.000000, 8192.000000, 16384.000000, 32768.000000, 65536.000000, 1.310720e+5, 2.621440e+5, 5.242880e+5, 1.048576e+6, 2.097152e+6, 4.194304e+6, 8.388608e+6, 1.677722e+7, 3.355443e+7, 6.710886e+7, 1.342177e+8, 2.684355e+8, 5.368709e+8, 1.073742e+9 }; +// scale_factor_inv +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 62 +static const double scale_factor_inv[31l]={ 1.000000, 5.000000e-1, 2.500000e-1, 1.250000e-1, 6.250000e-2, 3.125000e-2, 1.562500e-2, 7.812500e-3, 3.906250e-3, 1.953125e-3, 9.765625e-4, 4.882813e-4, 2.441406e-4, 1.220703e-4, 6.103516e-5, 3.051758e-5, 1.525879e-5, 7.629395e-6, 3.814697e-6, 1.907349e-6, 9.536743e-7, 4.768372e-7, 2.384186e-7, 1.192093e-7, 5.960465e-8, 2.980232e-8, 1.490116e-8, 7.450581e-9, 3.725290e-9, 1.862645e-9, 9.313230e-10 }; + +// __DSVERIFIER_assert +// file /home/lucascordeiro/dsverifier/bmc/core/compatibility.h line 35 +void __DSVERIFIER_assert(_Bool expression) +{ + /* assertion expression */ + assert(expression != (_Bool)0); + if(!(expression == (_Bool)0)) + (void)0; + +} + +// __DSVERIFIER_assert_msg +// file /home/lucascordeiro/dsverifier/bmc/core/compatibility.h line 39 +void __DSVERIFIER_assert_msg(_Bool expression, char *msg) +{ + printf("%c", msg); + /* assertion expression */ + assert(expression != (_Bool)0); + if(!(expression == (_Bool)0)) + (void)0; + +} + +// __DSVERIFIER_assume +// file /home/lucascordeiro/dsverifier/bmc/core/compatibility.h line 21 +void __DSVERIFIER_assume(_Bool expression) +{ + __CPROVER_assume(expression != (_Bool)0); +} + +// call_closedloop_verification_task +// file /home/lucascordeiro/dsverifier/bmc/dsverifier.h line 369 +void call_closedloop_verification_task(void *closedloop_verification_task) +{ + _Bool base_case_executed=(_Bool)0; + signed int i=0; + i = 0; + for( ; !(i >= plant.b_size); i = i + 1) + { + if(plant.b_uncertainty[(signed long int)i] > 0.000000) + { + double call_closedloop_verification_task$$1$$1$$1$$1$$factor=(plant.b[(signed long int)i] * plant.b_uncertainty[(signed long int)i]) / 100.000000; + call_closedloop_verification_task$$1$$1$$1$$1$$factor = call_closedloop_verification_task$$1$$1$$1$$1$$factor < 0.000000 ? call_closedloop_verification_task$$1$$1$$1$$1$$factor * (double)-1 : call_closedloop_verification_task$$1$$1$$1$$1$$factor; + double call_closedloop_verification_task$$1$$1$$1$$1$$min=plant.b[(signed long int)i] - call_closedloop_verification_task$$1$$1$$1$$1$$factor; + double call_closedloop_verification_task$$1$$1$$1$$1$$max=plant.b[(signed long int)i] + call_closedloop_verification_task$$1$$1$$1$$1$$factor; + if((signed int)base_case_executed == 1 && IEEE_FLOAT_EQUAL(call_closedloop_verification_task$$1$$1$$1$$1$$factor, 0.000000)) + goto __CPROVER_DUMP_L9; + + else + if((signed int)base_case_executed == 0 && IEEE_FLOAT_EQUAL(call_closedloop_verification_task$$1$$1$$1$$1$$factor, 0.000000)) + base_case_executed = (_Bool)0; + + plant_cbmc.b[(signed long int)i] = nondet_double(); + _Bool tmp_if_expr$1; + if(plant_cbmc.b[(signed long int)i] >= call_closedloop_verification_task$$1$$1$$1$$1$$min) + tmp_if_expr$1 = plant_cbmc.b[(signed long int)i] <= call_closedloop_verification_task$$1$$1$$1$$1$$max ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$1 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$1); + } + + else + plant_cbmc.b[(signed long int)i] = plant.b[(signed long int)i]; + + __CPROVER_DUMP_L9: + ; + } + i = 0; + for( ; !(i >= plant.a_size); i = i + 1) + { + if(plant.a_uncertainty[(signed long int)i] > 0.000000) + { + double factor=(plant.a[(signed long int)i] * plant.a_uncertainty[(signed long int)i]) / 100.000000; + factor = factor < 0.000000 ? factor * (double)-1 : factor; + double min=plant.a[(signed long int)i] - factor; + double max=plant.a[(signed long int)i] + factor; + if((signed int)base_case_executed == 1 && IEEE_FLOAT_EQUAL(factor, 0.000000)) + goto __CPROVER_DUMP_L19; + + else + if((signed int)base_case_executed == 0 && IEEE_FLOAT_EQUAL(factor, 0.000000)) + base_case_executed = (_Bool)0; + + plant_cbmc.a[(signed long int)i] = nondet_double(); + _Bool tmp_if_expr$2; + if(plant_cbmc.a[(signed long int)i] >= min) + tmp_if_expr$2 = plant_cbmc.a[(signed long int)i] <= max ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$2 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$2); + } + + else + plant_cbmc.a[(signed long int)i] = plant.a[(signed long int)i]; + + __CPROVER_DUMP_L19: + ; + } + ((void (*)())closedloop_verification_task)(); +} + +// call_verification_task +// file /home/lucascordeiro/dsverifier/bmc/dsverifier.h line 268 +void call_verification_task(void *verification_task) +{ + signed int i=0; + _Bool base_case_executed=(_Bool)0; + if((_Bool)0) + { + i = 0; + for( ; !(i >= ds.b_size); i = i + 1) + { + if(ds.b_uncertainty[(signed long int)i] > 0.000000) + { + double call_verification_task$$1$$1$$1$$1$$1$$factor=ds.b_uncertainty[(signed long int)i]; + call_verification_task$$1$$1$$1$$1$$1$$factor = call_verification_task$$1$$1$$1$$1$$1$$factor < 0.000000 ? call_verification_task$$1$$1$$1$$1$$1$$factor * (double)-1 : call_verification_task$$1$$1$$1$$1$$1$$factor; + double min=ds.b[(signed long int)i] - call_verification_task$$1$$1$$1$$1$$1$$factor; + double max=ds.b[(signed long int)i] + call_verification_task$$1$$1$$1$$1$$1$$factor; + if((signed int)base_case_executed == 1 && IEEE_FLOAT_EQUAL(call_verification_task$$1$$1$$1$$1$$1$$factor, 0.000000)) + goto __CPROVER_DUMP_L8; + + else + if((signed int)base_case_executed == 0 && IEEE_FLOAT_EQUAL(call_verification_task$$1$$1$$1$$1$$1$$factor, 0.000000)) + base_case_executed = (_Bool)0; + + ds.b[(signed long int)i] = nondet_double(); + _Bool tmp_if_expr$1; + if(ds.b[(signed long int)i] >= min) + tmp_if_expr$1 = ds.b[(signed long int)i] <= max ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$1 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$1); + } + + + __CPROVER_DUMP_L8: + ; + } + i = 0; + for( ; !(i >= ds.a_size); i = i + 1) + { + if(ds.a_uncertainty[(signed long int)i] > 0.000000) + { + double factor=ds.a_uncertainty[(signed long int)i]; + factor = factor < 0.000000 ? factor * (double)-1 : factor; + double call_verification_task$$1$$1$$2$$1$$1$$min=ds.a[(signed long int)i] - factor; + double call_verification_task$$1$$1$$2$$1$$1$$max=ds.a[(signed long int)i] + factor; + if((signed int)base_case_executed == 1 && IEEE_FLOAT_EQUAL(factor, 0.000000)) + goto __CPROVER_DUMP_L17; + + else + if((signed int)base_case_executed == 0 && IEEE_FLOAT_EQUAL(factor, 0.000000)) + base_case_executed = (_Bool)0; + + ds.a[(signed long int)i] = nondet_double(); + _Bool tmp_if_expr$2; + if(ds.a[(signed long int)i] >= call_verification_task$$1$$1$$2$$1$$1$$min) + tmp_if_expr$2 = ds.a[(signed long int)i] <= call_verification_task$$1$$1$$2$$1$$1$$max ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$2 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$2); + } + + + __CPROVER_DUMP_L17: + ; + } + } + + else + { + signed int call_verification_task$$1$$2$$i=0; + call_verification_task$$1$$2$$i = 0; + for( ; !(call_verification_task$$1$$2$$i >= ds.b_size); call_verification_task$$1$$2$$i = call_verification_task$$1$$2$$i + 1) + { + if(ds.b_uncertainty[(signed long int)call_verification_task$$1$$2$$i] > 0.000000) + { + double call_verification_task$$1$$2$$1$$1$$1$$factor=(ds.b[(signed long int)call_verification_task$$1$$2$$i] * ds.b_uncertainty[(signed long int)call_verification_task$$1$$2$$i]) / 100.000000; + call_verification_task$$1$$2$$1$$1$$1$$factor = call_verification_task$$1$$2$$1$$1$$1$$factor < 0.000000 ? call_verification_task$$1$$2$$1$$1$$1$$factor * (double)-1 : call_verification_task$$1$$2$$1$$1$$1$$factor; + double call_verification_task$$1$$2$$1$$1$$1$$min=ds.b[(signed long int)call_verification_task$$1$$2$$i] - call_verification_task$$1$$2$$1$$1$$1$$factor; + double call_verification_task$$1$$2$$1$$1$$1$$max=ds.b[(signed long int)call_verification_task$$1$$2$$i] + call_verification_task$$1$$2$$1$$1$$1$$factor; + if((signed int)base_case_executed == 1 && IEEE_FLOAT_EQUAL(call_verification_task$$1$$2$$1$$1$$1$$factor, 0.000000)) + goto __CPROVER_DUMP_L27; + + else + if((signed int)base_case_executed == 0 && IEEE_FLOAT_EQUAL(call_verification_task$$1$$2$$1$$1$$1$$factor, 0.000000)) + base_case_executed = (_Bool)0; + + ds.b[(signed long int)call_verification_task$$1$$2$$i] = nondet_double(); + _Bool tmp_if_expr$3; + if(ds.b[(signed long int)call_verification_task$$1$$2$$i] >= call_verification_task$$1$$2$$1$$1$$1$$min) + tmp_if_expr$3 = ds.b[(signed long int)call_verification_task$$1$$2$$i] <= call_verification_task$$1$$2$$1$$1$$1$$max ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$3 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$3); + } + + + __CPROVER_DUMP_L27: + ; + } + call_verification_task$$1$$2$$i = 0; + for( ; !(call_verification_task$$1$$2$$i >= ds.a_size); call_verification_task$$1$$2$$i = call_verification_task$$1$$2$$i + 1) + { + if(ds.a_uncertainty[(signed long int)call_verification_task$$1$$2$$i] > 0.000000) + { + double call_verification_task$$1$$2$$2$$1$$1$$factor=(ds.a[(signed long int)call_verification_task$$1$$2$$i] * ds.a_uncertainty[(signed long int)call_verification_task$$1$$2$$i]) / 100.000000; + call_verification_task$$1$$2$$2$$1$$1$$factor = call_verification_task$$1$$2$$2$$1$$1$$factor < 0.000000 ? call_verification_task$$1$$2$$2$$1$$1$$factor * (double)-1 : call_verification_task$$1$$2$$2$$1$$1$$factor; + double call_verification_task$$1$$2$$2$$1$$1$$min=ds.a[(signed long int)call_verification_task$$1$$2$$i] - call_verification_task$$1$$2$$2$$1$$1$$factor; + double call_verification_task$$1$$2$$2$$1$$1$$max=ds.a[(signed long int)call_verification_task$$1$$2$$i] + call_verification_task$$1$$2$$2$$1$$1$$factor; + if((signed int)base_case_executed == 1 && IEEE_FLOAT_EQUAL(call_verification_task$$1$$2$$2$$1$$1$$factor, 0.000000)) + goto __CPROVER_DUMP_L36; + + else + if((signed int)base_case_executed == 0 && IEEE_FLOAT_EQUAL(call_verification_task$$1$$2$$2$$1$$1$$factor, 0.000000)) + base_case_executed = (_Bool)0; + + ds.a[(signed long int)call_verification_task$$1$$2$$i] = nondet_double(); + _Bool tmp_if_expr$4; + if(ds.a[(signed long int)call_verification_task$$1$$2$$i] >= call_verification_task$$1$$2$$2$$1$$1$$min) + tmp_if_expr$4 = ds.a[(signed long int)call_verification_task$$1$$2$$i] <= call_verification_task$$1$$2$$2$$1$$1$$max ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$4 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$4); + } + + + __CPROVER_DUMP_L36: + ; + } + } + ((void (*)())verification_task)(); +} + +// check_stability +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 59 +signed int check_stability(double *a, signed int n) +{ + signed int lines=2 * n - 1; + signed int columns=n; + const signed long int columns$array_size0=(signed long int)n; + const signed long int columns$array_size1=(signed long int)lines; + double m[columns$array_size1][columns$array_size0]; + signed int i; + signed int j; + const signed long int j$array_size0=(signed long int)n; + double current_stability[j$array_size0]; + i = 0; + for( ; !(i >= n); i = i + 1) + current_stability[(signed long int)i] = a[(signed long int)i]; + double sum=0.000000; + i = 0; + for( ; !(i >= n); i = i + 1) + sum = sum + a[(signed long int)i]; + if(sum <= 0.000000) + { + printf("[DEBUG] the first constraint of Jury criteria failed: (F(1) > 0)"); + return 0; + } + + else + { + sum = 0.000000; + i = 0; + for( ; !(i >= n); i = i + 1) + { + double return_value_internal_pow$1=internal_pow((double)-1, (double)((n - 1) - i)); + sum = sum + a[(signed long int)i] * return_value_internal_pow$1; + } + double return_value_internal_pow$2=internal_pow((double)-1, (double)(n - 1)); + sum = sum * return_value_internal_pow$2; + if(sum <= 0.000000) + { + printf("[DEBUG] the second constraint of Jury criteria failed: (F(-1)*(-1)^n > 0)"); + return 0; + } + + else + { + double return_value_internal_abs$3=internal_abs(a[(signed long int)(n - 1)]); + if(return_value_internal_abs$3 > *a) + { + printf("[DEBUG] the third constraint of Jury criteria failed: (abs(a0) < a_{n}*z^{n})"); + return 0; + } + + else + { + i = 0; + for( ; !(i >= lines); i = i + 1) + { + j = 0; + for( ; !(j >= columns); j = j + 1) + m[(signed long int)i][(signed long int)j] = 0.000000; + } + i = 0; + for( ; !(i >= lines); i = i + 1) + { + j = 0; + for( ; !(j >= columns); j = j + 1) + if(i == 0) + m[(signed long int)i][(signed long int)j] = a[(signed long int)j]; + + else + if(!(i % 2 == 0)) + { + signed int x=0; + for( ; !(x >= columns); x = x + 1) + m[(signed long int)i][(signed long int)x] = m[(signed long int)(i - 1)][(signed long int)((columns - x) - 1)]; + columns = columns - 1; + j = columns; + } + + else + m[(signed long int)i][(signed long int)j] = m[(signed long int)(i - 2)][(signed long int)j] - (m[(signed long int)(i - 2)][(signed long int)columns] / m[(signed long int)(i - 2)][0l]) * m[(signed long int)(i - 1)][(signed long int)j]; + } + signed int first_is_positive=m[0l][0l] >= 0.000000 ? 1 : 0; + i = 0; + for( ; !(i >= lines); i = i + 1) + if(i % 2 == 0) + { + signed int line_is_positive=m[(signed long int)i][0l] >= 0.000000 ? 1 : 0; + if(!(first_is_positive == line_is_positive)) + return 0; + + } + + return 1; + } + } + } +} + +// check_stability_closedloop +// file /home/lucascordeiro/dsverifier/bmc/core/closed-loop.h line 70 +signed int check_stability_closedloop(double *a, signed int n, double *plant_num, signed int p_num_size, double *plant_den, signed int p_den_size) +{ + signed int columns=n; + const signed long int columns$array_size0=(signed long int)n; + const signed long int columns$array_size1=(signed long int)(2 * n - 1); + double m[columns$array_size1][columns$array_size0]; + signed int i; + signed int j; + signed int first_is_positive=0; + double *p_num=plant_num; + double *p_den=plant_den; + double sum=0.000000; + i = 0; + for( ; !(i >= n); i = i + 1) + sum = sum + a[(signed long int)i]; + __DSVERIFIER_assert(sum > 0.000000); + sum = 0.000000; + i = 0; + for( ; !(i >= n); i = i + 1) + { + double return_value_internal_pow$1=internal_pow((double)-1, (double)((n - 1) - i)); + sum = sum + a[(signed long int)i] * return_value_internal_pow$1; + } + double return_value_internal_pow$2=internal_pow((double)-1, (double)(n - 1)); + sum = sum * return_value_internal_pow$2; + __DSVERIFIER_assert(sum > 0.000000); + double return_value_internal_abs$3=internal_abs(a[(signed long int)(n - 1)]); + __DSVERIFIER_assert(return_value_internal_abs$3 < a[0l]); + i = 0; + for( ; !(i >= 2 * n + -1); i = i + 1) + { + j = 0; + for( ; !(j >= columns); j = j + 1) + { + m[(signed long int)i][(signed long int)j] = 0.000000; + if(i == 0) + m[(signed long int)i][(signed long int)j] = a[(signed long int)j]; + + else + if(!(i % 2 == 0)) + { + signed int x=0; + for( ; !(x >= columns); x = x + 1) + m[(signed long int)i][(signed long int)x] = m[(signed long int)(i - 1)][(signed long int)((columns - x) - 1)]; + columns = columns - 1; + j = columns; + } + + else + { + m[(signed long int)i][(signed long int)j] = m[(signed long int)(i - 2)][(signed long int)j] - (m[(signed long int)(i - 2)][(signed long int)columns] / m[(signed long int)(i - 2)][0l]) * m[(signed long int)(i - 1)][(signed long int)j]; + _Bool tmp_if_expr$4; + if(m[0l][0l] >= 0.000000) + tmp_if_expr$4 = m[(signed long int)i][0l] >= 0.000000 ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$4 = (_Bool)0; + __DSVERIFIER_assert(tmp_if_expr$4); + } + } + } + return 1; +} + +// determinant +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 498 +double determinant(double (*a)[20l], signed int n) +{ + signed int i; + signed int j; + signed int j1; + signed int j2; + double det=0.000000; + double m[20l][20l]; + if(n >= 1) + { + if(n == 1) + det = a[0l][0l]; + + else + if(n == 2) + det = a[0l][0l] * a[1l][1l] - a[1l][0l] * a[0l][1l]; + + else + { + det = 0.000000; + j1 = 0; + for( ; !(j1 >= n); j1 = j1 + 1) + { + i = 0; + for( ; !(i >= -1 + n); i = i + 1) + { + i = 1; + for( ; !(i >= n); i = i + 1) + { + j2 = 0; + j = 0; + for( ; !(j >= n); j = j + 1) + if(!(j == j1)) + { + m[(signed long int)(i - 1)][(signed long int)j2] = a[(signed long int)i][(signed long int)j]; + j2 = j2 + 1; + } + + } + } + double return_value_internal_pow$1=internal_pow(-1.000000, 1.000000 + (double)j1 + 1.000000); + double return_value_determinant$2=determinant(m, n - 1); + det = det + return_value_internal_pow$1 * a[0l][(signed long int)j1] * return_value_determinant$2; + } + } + } + + return det; +} + +// double_add_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 315 +void double_add_matrix(unsigned int lines, unsigned int columns, double (*m1)[20l], double (*m2)[20l], double (*result)[20l]) +{ + unsigned int i; + unsigned int j; + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + result[(signed long int)i][(signed long int)j] = m1[(signed long int)i][(signed long int)j] + m2[(signed long int)i][(signed long int)j]; + } +} + +// double_check_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 218 +void double_check_limit_cycle(double *y, signed int y_size) +{ + double reference=y[(signed long int)(y_size - 1)]; + signed int idx=0; + signed int window_size=1; + idx = y_size - 2; + for( ; idx >= 0; idx = idx - 1) + if(IEEE_FLOAT_NOTEQUAL(y[(signed long int)idx], reference)) + window_size = window_size + 1; + + else + break; + __DSVERIFIER_assume(window_size != y_size && window_size != 1); + printf("window_size %d\n", window_size); + signed int desired_elements=2 * window_size; + signed int found_elements=0; + idx = y_size - 1; + for( ; idx >= 0; idx = idx - 1) + if(!(-1 + y_size + -window_size >= idx)) + { + printf("%.0f == %.0f\n", y[(signed long int)idx], y[(signed long int)(idx - window_size)]); + signed int cmp_idx=idx - window_size; + _Bool tmp_if_expr$1; + if(cmp_idx >= 1) + tmp_if_expr$1 = IEEE_FLOAT_EQUAL(y[(signed long int)idx], y[(signed long int)(idx - window_size)]) ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$1 = (_Bool)0; + if(tmp_if_expr$1) + found_elements = found_elements + 2; + + else + break; + } + + printf("desired_elements %d\n", desired_elements); + printf("found_elements %d\n", found_elements); + __DSVERIFIER_assert(desired_elements != found_elements); +} + +// double_check_oscillations +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 187 +void double_check_oscillations(double *y, signed int y_size) +{ + __DSVERIFIER_assume(IEEE_FLOAT_NOTEQUAL(y[0l], y[(signed long int)(y_size - 1)])); + signed int window_timer=0; + signed int window_count=0; + signed int i; + signed int j; + i = 2; + for( ; !(i >= y_size); i = i + 1) + { + signed int window_size=i; + j = 0; + for( ; !(j >= y_size); j = j + 1) + { + if(!(window_size >= window_timer)) + { + window_timer = 0; + window_count = 0; + } + + signed int window_index=j + window_size; + if(!(window_index >= y_size)) + { + if(IEEE_FLOAT_EQUAL(y[(signed long int)j], y[(signed long int)window_index])) + { + window_count = window_count + 1; + /* assertion !(window_count == window_size) */ + assert(!(window_count == window_size)); + if(!(window_count == window_size)) + (void)0; + + } + + } + + else + break; + window_timer = window_timer + 1; + } + } +} + +// double_check_persistent_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 254 +void double_check_persistent_limit_cycle(double *y, signed int y_size) +{ + signed int idy=0; + signed int count_same=0; + signed int window_size=0; + double reference=y[0l]; + idy = 0; + for( ; !(idy >= y_size); idy = idy + 1) + if(IEEE_FLOAT_NOTEQUAL(y[(signed long int)idy], reference)) + window_size = window_size + 1; + + else + if(!(window_size == 0)) + break; + + else + count_same = count_same + 1; + window_size = window_size + count_same; + __DSVERIFIER_assume(window_size > 1 && window_size <= y_size / 2); + const signed long int reference$array_size0=(signed long int)window_size; + double lco_elements[reference$array_size0]; + idy = 0; + for( ; !(idy >= y_size); idy = idy + 1) + if(!(idy >= window_size)) + lco_elements[(signed long int)idy] = y[(signed long int)idy]; + + idy = 0; + signed int lco_idy=0; + _Bool is_persistent=(_Bool)0; + while(!(idy >= y_size)) + { + signed int tmp_post$1=idy; + idy = idy + 1; + signed int tmp_post$2=lco_idy; + lco_idy = lco_idy + 1; + if(IEEE_FLOAT_EQUAL(y[(signed long int)tmp_post$1], lco_elements[(signed long int)tmp_post$2])) + is_persistent = (_Bool)0; + + else + { + is_persistent = (_Bool)0; + break; + } + if(lco_idy == window_size) + lco_idy = 0; + + } + __DSVERIFIER_assert((signed int)is_persistent == 0); +} + +// double_direct_form_1 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 83 +double double_direct_form_1(double *y, double *x, double *a, double *b, signed int Na, signed int Nb) +{ + double *a_ptr; + double *y_ptr; + double *b_ptr; + double *x_ptr; + double sum=0.000000; + a_ptr = &a[1l]; + y_ptr = &y[(signed long int)(Na - 1)]; + b_ptr = &b[0l]; + x_ptr = &x[(signed long int)(Nb - 1)]; + signed int i; + signed int j; + i = 0; + for( ; !(i >= Nb); i = i + 1) + { + double *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + double *tmp_post$2=x_ptr; + x_ptr = x_ptr - 1l; + sum = sum + *tmp_post$1 * *tmp_post$2; + } + j = 1; + for( ; !(j >= Na); j = j + 1) + { + double *tmp_post$3=a_ptr; + a_ptr = a_ptr + 1l; + double *tmp_post$4=y_ptr; + y_ptr = y_ptr - 1l; + sum = sum - *tmp_post$3 * *tmp_post$4; + } + sum = sum / a[0l]; + return sum; +} + +// double_direct_form_1_MSP430 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 205 +double double_direct_form_1_MSP430(double *y, double *x, double *a, double *b, signed int Na, signed int Nb) +{ + signed int timer1=0; + double *a_ptr; + double *y_ptr; + double *b_ptr; + double *x_ptr; + double sum=0.000000; + a_ptr = &a[1l]; + y_ptr = &y[(signed long int)(Na - 1)]; + b_ptr = &b[0l]; + x_ptr = &x[(signed long int)(Nb - 1)]; + signed int i; + signed int j; + timer1 = timer1 + 91; + i = 0; + for( ; !(i >= Nb); i = i + 1) + { + double *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + double *tmp_post$2=x_ptr; + x_ptr = x_ptr - 1l; + sum = sum + *tmp_post$1 * *tmp_post$2; + timer1 = timer1 + 47; + } + j = 1; + for( ; !(j >= Na); j = j + 1) + { + double *tmp_post$3=a_ptr; + a_ptr = a_ptr + 1l; + double *tmp_post$4=y_ptr; + y_ptr = y_ptr - 1l; + sum = sum - *tmp_post$3 * *tmp_post$4; + timer1 = timer1 + 57; + } + timer1 = timer1 + 3; + /* assertion (double) timer1 * hw.cycle <= ds.sample_time */ + assert((double)timer1 * hw.cycle <= ds.sample_time); + if((double)timer1 * hw.cycle <= ds.sample_time) + (void)0; + + return sum; +} + +// double_direct_form_1_impl2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 364 +void double_direct_form_1_impl2(double *x, signed int x_size, double *b, signed int b_size, double *a, signed int a_size, double *y) +{ + signed int i=0; + signed int j=0; + const signed long int j$array_size0=(signed long int)x_size; + double v[j$array_size0]; + i = 0; + for( ; !(i >= x_size); i = i + 1) + { + v[(signed long int)i] = 0.000000; + j = 0; + for( ; !(j >= b_size); j = j + 1) + { + if(!(i >= j)) + break; + + v[(signed long int)i] = v[(signed long int)i] + x[(signed long int)(i - j)] * b[(signed long int)j]; + } + } + y[0l] = v[0l]; + i = 1; + for( ; !(i >= x_size); i = i + 1) + { + y[(signed long int)i] = 0.000000; + y[(signed long int)i] = y[(signed long int)i] + v[(signed long int)i]; + j = 1; + for( ; !(j >= a_size); j = j + 1) + { + if(!(i >= j)) + break; + + y[(signed long int)i] = y[(signed long int)i] + y[(signed long int)(i - j)] * (double)-1 * a[(signed long int)j]; + } + } +} + +// double_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 102 +double double_direct_form_2(double *w, double x, double *a, double *b, signed int Na, signed int Nb) +{ + double *a_ptr; + double *b_ptr; + double *w_ptr; + double sum=0.000000; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + w_ptr = &w[1l]; + signed int k; + signed int j=1; + for( ; !(j >= Na); j = j + 1) + { + double *tmp_post$1=a_ptr; + a_ptr = a_ptr + 1l; + double *tmp_post$2=w_ptr; + w_ptr = w_ptr + 1l; + w[0l] = w[0l] - *tmp_post$1 * *tmp_post$2; + } + w[0l] = w[0l] + x; + w[0l] = w[0l] / a[0l]; + w_ptr = &w[0l]; + k = 0; + for( ; !(k >= Nb); k = k + 1) + { + double *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + double *tmp_post$4=w_ptr; + w_ptr = w_ptr + 1l; + sum = sum + *tmp_post$3 * *tmp_post$4; + } + return sum; +} + +// double_direct_form_2_MSP430 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 230 +double double_direct_form_2_MSP430(double *w, double x, double *a, double *b, signed int Na, signed int Nb) +{ + signed int timer1=0; + double *a_ptr; + double *b_ptr; + double *w_ptr; + double sum=0.000000; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + w_ptr = &w[1l]; + signed int k; + signed int j; + timer1 = timer1 + 71; + j = 1; + for( ; !(j >= Na); j = j + 1) + { + double *tmp_post$1=a_ptr; + a_ptr = a_ptr + 1l; + double *tmp_post$2=w_ptr; + w_ptr = w_ptr + 1l; + w[0l] = w[0l] - *tmp_post$1 * *tmp_post$2; + timer1 = timer1 + 54; + } + w[0l] = w[0l] + x; + w[0l] = w[0l] / a[0l]; + w_ptr = &w[0l]; + k = 0; + for( ; !(k >= Nb); k = k + 1) + { + double *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + double *tmp_post$4=w_ptr; + w_ptr = w_ptr + 1l; + sum = sum + *tmp_post$3 * *tmp_post$4; + timer1 = timer1 + 46; + } + timer1 = timer1 + 38; + /* assertion (double) timer1 * hw.cycle <= ds.sample_time */ + assert((double)timer1 * hw.cycle <= ds.sample_time); + if((double)timer1 * hw.cycle <= ds.sample_time) + (void)0; + + return sum; +} + +// double_exp_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 428 +void double_exp_matrix(unsigned int lines, unsigned int columns, double (*m1)[20l], unsigned int expNumber, double (*result)[20l]) +{ + unsigned int i; + unsigned int j; + unsigned int k; + unsigned int l; + double m2[20l][20l]; + if(expNumber == 0u) + { + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + if(i == j) + result[(signed long int)i][(signed long int)j] = 1.000000; + + else + result[(signed long int)i][(signed long int)j] = 0.000000; + } + } + + else + { + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + result[(signed long int)i][(signed long int)j] = m1[(signed long int)i][(signed long int)j]; + } + if(!(expNumber == 1u)) + { + l = 1u; + for( ; !(l >= expNumber); l = l + 1u) + { + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + m2[(signed long int)i][(signed long int)j] = result[(signed long int)i][(signed long int)j]; + } + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + result[(signed long int)i][(signed long int)j] = 0.000000; + } + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + { + k = 0u; + for( ; !(k >= columns); k = k + 1u) + result[(signed long int)i][(signed long int)j] = result[(signed long int)i][(signed long int)j] + m2[(signed long int)i][(signed long int)k] * m1[(signed long int)k][(signed long int)j]; + } + } + } + } + + } +} + +// double_matrix_multiplication +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 337 +void double_matrix_multiplication(unsigned int i1, unsigned int j1, unsigned int i2, unsigned int j2, double (*m1)[20l], double (*m2)[20l], double (*m3)[20l]) +{ + unsigned int i; + unsigned int j; + unsigned int k; + if(j1 == i2) + { + i = 0u; + for( ; !(i >= i1); i = i + 1u) + { + j = 0u; + for( ; !(j >= j2); j = j + 1u) + m3[(signed long int)i][(signed long int)j] = 0.000000; + } + i = 0u; + for( ; !(i >= i1); i = i + 1u) + { + j = 0u; + for( ; !(j >= j2); j = j + 1u) + { + k = 0u; + for( ; !(k >= j1); k = k + 1u) + { + double mult=m1[(signed long int)i][(signed long int)k] * m2[(signed long int)k][(signed long int)j]; + m3[(signed long int)i][(signed long int)j] = m3[(signed long int)i][(signed long int)j] + m1[(signed long int)i][(signed long int)k] * m2[(signed long int)k][(signed long int)j]; + } + } + } + } + + else + printf("\nError! Operation invalid, please enter with valid matrices.\n"); +} + +// double_state_space_representation +// file /home/lucascordeiro/dsverifier/bmc/core/state-space.h line 23 +double double_state_space_representation(void) +{ + double result1[20l][20l]; + double result2[20l][20l]; + signed int i; + signed int j; + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + { + result1[(signed long int)i][(signed long int)j] = 0.000000; + result2[(signed long int)i][(signed long int)j] = 0.000000; + } + } + double_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nStates, (unsigned int)nStates, 1u, _controller.C, _controller.states, result1); + double_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nInputs, (unsigned int)nInputs, 1u, _controller.D, _controller.inputs, result2); + double_add_matrix((unsigned int)nOutputs, 1u, result1, result2, _controller.outputs); + i = 1; + for( ; !(i >= 0); i = i + 1) + { + double_matrix_multiplication((unsigned int)nStates, (unsigned int)nStates, (unsigned int)nStates, 1u, _controller.A, _controller.states, result1); + double_matrix_multiplication((unsigned int)nStates, (unsigned int)nInputs, (unsigned int)nInputs, 1u, _controller.B, _controller.inputs, result2); + double_add_matrix((unsigned int)nStates, 1u, result1, result2, _controller.states); + double_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nStates, (unsigned int)nStates, 1u, _controller.C, _controller.states, result1); + double_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nInputs, (unsigned int)nInputs, 1u, _controller.D, _controller.inputs, result2); + double_add_matrix((unsigned int)nOutputs, 1u, result1, result2, _controller.outputs); + } + return _controller.outputs[0l][0l]; +} + +// double_sub_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 326 +void double_sub_matrix(unsigned int lines, unsigned int columns, double (*m1)[20l], double (*m2)[20l], double (*result)[20l]) +{ + unsigned int i; + unsigned int j; + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + result[(signed long int)i][(signed long int)j] = m1[(signed long int)i][(signed long int)j] - m2[(signed long int)i][(signed long int)j]; + } +} + +// double_transposed_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 122 +double double_transposed_direct_form_2(double *w, double x, double *a, double *b, signed int Na, signed int Nb) +{ + double *a_ptr; + double *b_ptr; + double yout=0.000000; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + signed int Nw=Na > Nb ? Na : Nb; + double *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + yout = *tmp_post$1 * x + w[0l]; + yout = yout / a[0l]; + signed int j=0; + for( ; !(j >= -1 + Nw); j = j + 1) + { + w[(signed long int)j] = w[(signed long int)(j + 1)]; + if(!(j >= -1 + Na)) + { + double *tmp_post$2=a_ptr; + a_ptr = a_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] - *tmp_post$2 * yout; + } + + if(!(j >= -1 + Nb)) + { + double *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] + *tmp_post$3 * x; + } + + } + return yout; +} + +// double_transposed_direct_form_2_MSP430 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 257 +double double_transposed_direct_form_2_MSP430(double *w, double x, double *a, double *b, signed int Na, signed int Nb) +{ + signed int timer1=0; + double *a_ptr; + double *b_ptr; + double yout=0.000000; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + signed int Nw=Na > Nb ? Na : Nb; + double *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + yout = *tmp_post$1 * x + w[0l]; + signed int j; + timer1 = timer1 + 105; + j = 0; + for( ; !(j >= -1 + Nw); j = j + 1) + { + w[(signed long int)j] = w[(signed long int)(j + 1)]; + if(!(j >= -1 + Na)) + { + double *tmp_post$2=a_ptr; + a_ptr = a_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] - *tmp_post$2 * yout; + timer1 = timer1 + 41; + } + + if(!(j >= -1 + Nb)) + { + double *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] + *tmp_post$3 * x; + timer1 = timer1 + 38; + } + + timer1 = timer1 + 54; + } + timer1 = timer1 + 7; + /* assertion (double) timer1 * hw.cycle <= ds.sample_time */ + assert((double)timer1 * hw.cycle <= ds.sample_time); + if((double)timer1 * hw.cycle <= ds.sample_time) + (void)0; + + return yout; +} + +// fatorial +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 54 +signed int fatorial(signed int n) +{ + signed int tmp_if_expr$2; + signed int return_value_fatorial$1; + if(n == 0) + tmp_if_expr$2 = 1; + + else + { + return_value_fatorial$1=fatorial(n - 1); + tmp_if_expr$2 = n * return_value_fatorial$1; + } + return tmp_if_expr$2; +} + +// float_direct_form_1 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 144 +float float_direct_form_1(float *y, float *x, float *a, float *b, signed int Na, signed int Nb) +{ + float *a_ptr; + float *y_ptr; + float *b_ptr; + float *x_ptr; + float sum=0.000000f; + a_ptr = &a[1l]; + y_ptr = &y[(signed long int)(Na - 1)]; + b_ptr = &b[0l]; + x_ptr = &x[(signed long int)(Nb - 1)]; + signed int i; + signed int j; + i = 0; + for( ; !(i >= Nb); i = i + 1) + { + float *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + float *tmp_post$2=x_ptr; + x_ptr = x_ptr - 1l; + sum = sum + *tmp_post$1 * *tmp_post$2; + } + j = 1; + for( ; !(j >= Na); j = j + 1) + { + float *tmp_post$3=a_ptr; + a_ptr = a_ptr + 1l; + float *tmp_post$4=y_ptr; + y_ptr = y_ptr - 1l; + sum = sum - *tmp_post$3 * *tmp_post$4; + } + sum = sum / a[0l]; + return sum; +} + +// float_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 163 +float float_direct_form_2(float *w, float x, float *a, float *b, signed int Na, signed int Nb) +{ + float *a_ptr; + float *b_ptr; + float *w_ptr; + float sum=0.000000f; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + w_ptr = &w[1l]; + signed int k; + signed int j=1; + for( ; !(j >= Na); j = j + 1) + { + float *tmp_post$1=a_ptr; + a_ptr = a_ptr + 1l; + float *tmp_post$2=w_ptr; + w_ptr = w_ptr + 1l; + w[0l] = w[0l] - *tmp_post$1 * *tmp_post$2; + } + w[0l] = w[0l] + x; + w[0l] = w[0l] / a[0l]; + w_ptr = &w[0l]; + k = 0; + for( ; !(k >= Nb); k = k + 1) + { + float *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + float *tmp_post$4=w_ptr; + w_ptr = w_ptr + 1l; + sum = sum + *tmp_post$3 * *tmp_post$4; + } + return sum; +} + +// float_transposed_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 183 +float float_transposed_direct_form_2(float *w, float x, float *a, float *b, signed int Na, signed int Nb) +{ + float *a_ptr; + float *b_ptr; + float yout=0.000000f; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + signed int Nw=Na > Nb ? Na : Nb; + float *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + yout = *tmp_post$1 * x + w[0l]; + yout = yout / a[0l]; + signed int j=0; + for( ; !(j >= -1 + Nw); j = j + 1) + { + w[(signed long int)j] = w[(signed long int)(j + 1)]; + if(!(j >= -1 + Na)) + { + float *tmp_post$2=a_ptr; + a_ptr = a_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] - *tmp_post$2 * yout; + } + + if(!(j >= -1 + Nb)) + { + float *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] + *tmp_post$3 * x; + } + + } + return yout; +} + +// ft_closedloop_feedback +// file /home/lucascordeiro/dsverifier/bmc/core/closed-loop.h line 57 +void ft_closedloop_feedback(double *c_num, signed int Nc_num, double *c_den, signed int Nc_den, double *model_num, signed int Nmodel_num, double *model_den, signed int Nmodel_den, double *ans_num, signed int Nans_num, double *ans_den, signed int Nans_den) +{ + Nans_num = (Nc_den + Nmodel_num) - 1; + Nans_den = (Nc_den + Nmodel_den) - 1; + signed int Nnum_mult=(Nc_num + Nmodel_num) - 1; + const signed long int Nnum_mult$array_size0=(signed long int)Nans_den; + double den_mult[Nnum_mult$array_size0]; + const signed long int den_mult$array_size0=(signed long int)Nnum_mult; + double num_mult[den_mult$array_size0]; + poly_mult(c_num, Nc_num, model_num, Nmodel_num, num_mult, Nnum_mult); + poly_mult(c_den, Nc_den, model_den, Nmodel_den, den_mult, Nans_den); + poly_sum(num_mult, Nnum_mult, den_mult, Nans_den, ans_den, Nans_den); + poly_mult(c_den, Nc_den, model_num, Nmodel_num, ans_num, Nans_num); +} + +// ft_closedloop_sensitivity +// file /home/lucascordeiro/dsverifier/bmc/core/closed-loop.h line 42 +void ft_closedloop_sensitivity(double *c_num, signed int Nc_num, double *c_den, signed int Nc_den, double *model_num, signed int Nmodel_num, double *model_den, signed int Nmodel_den, double *ans_num, signed int Nans_num, double *ans_den, signed int Nans_den) +{ + signed int Nans_num_p=(Nc_num + Nmodel_num) - 1; + Nans_den = (Nc_den + Nmodel_den) - 1; + Nans_num = (Nc_den + Nmodel_den) - 1; + const signed long int Nans_num_p$array_size0=(signed long int)Nans_num_p; + double num_mult[Nans_num_p$array_size0]; + poly_mult(c_den, Nc_den, model_den, Nmodel_den, ans_num, Nans_num); + poly_mult(c_num, Nc_num, model_num, Nmodel_num, num_mult, Nans_num_p); + poly_sum(ans_num, Nans_num, num_mult, Nans_num_p, ans_den, Nans_den); +} + +// ft_closedloop_series +// file /home/lucascordeiro/dsverifier/bmc/core/closed-loop.h line 28 +void ft_closedloop_series(double *c_num, signed int Nc_num, double *c_den, signed int Nc_den, double *model_num, signed int Nmodel_num, double *model_den, signed int Nmodel_den, double *ans_num, signed int Nans_num, double *ans_den, signed int Nans_den) +{ + Nans_num = (Nc_num + Nmodel_num) - 1; + Nans_den = (Nc_den + Nmodel_den) - 1; + const signed long int ft_closedloop_series$array_size0=(signed long int)Nans_den; + double den_mult[ft_closedloop_series$array_size0]; + poly_mult(c_num, Nc_num, model_num, Nmodel_num, ans_num, Nans_num); + poly_mult(c_den, Nc_den, model_den, Nmodel_den, den_mult, Nans_den); + poly_sum(ans_num, Nans_num, den_mult, Nans_den, ans_den, Nans_den); +} + +// fxp_abs +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 303 +signed long int fxp_abs(signed long int a) +{ + signed long int tmp=a < 0l ? -((signed long int)a) : a; + return tmp; +} + +// fxp_add +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 315 +signed long int fxp_add(signed long int aadd, signed long int badd) +{ + signed long int tmpadd=(signed long int)aadd + (signed long int)badd; + return tmpadd; +} + +// fxp_add_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 467 +void fxp_add_matrix(unsigned int lines, unsigned int columns, signed long int (*m1)[20l], signed long int (*m2)[20l], signed long int (*result)[20l]) +{ + unsigned int i; + unsigned int j; + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + result[(signed long int)i][(signed long int)j]=fxp_add(m1[(signed long int)i][(signed long int)j], m2[(signed long int)i][(signed long int)j]); + } +} + +// fxp_check_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 163 +void fxp_check_limit_cycle(signed long int *y, signed int y_size) +{ + signed long int reference=y[(signed long int)(y_size - 1)]; + signed int idx=0; + signed int window_size=1; + idx = y_size - 2; + for( ; idx >= 0; idx = idx - 1) + if(!(y[(signed long int)idx] == reference)) + window_size = window_size + 1; + + else + break; + __DSVERIFIER_assume(window_size != y_size && window_size != 1); + printf("window_size %d\n", window_size); + signed int desired_elements=2 * window_size; + signed int found_elements=0; + idx = y_size - 1; + for( ; idx >= 0; idx = idx - 1) + if(!(-1 + y_size + -window_size >= idx)) + { + printf("%.0f == %.0f\n", y[(signed long int)idx], y[(signed long int)(idx - window_size)]); + signed int cmp_idx=idx - window_size; + _Bool tmp_if_expr$1; + if(cmp_idx >= 1) + tmp_if_expr$1 = y[(signed long int)idx] == y[(signed long int)(idx - window_size)] ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$1 = (_Bool)0; + if(tmp_if_expr$1) + found_elements = found_elements + 2; + + else + break; + } + + __DSVERIFIER_assume(found_elements > 0); + printf("desired_elements %d\n", desired_elements); + printf("found_elements %d\n", found_elements); + __DSVERIFIER_assume(found_elements == desired_elements); + __DSVERIFIER_assert((_Bool)0); +} + +// fxp_check_oscillations +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 253 +void fxp_check_oscillations(signed long int *y, signed int y_size) +{ + _Bool tmp_if_expr$1; + if(!(*y == y[(signed long int)(-1 + y_size)])) + tmp_if_expr$1 = y[(signed long int)(y_size - 1)] != y[(signed long int)(y_size - 2)] ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$1 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$1); + signed int window_timer=0; + signed int window_count=0; + signed int i; + signed int j; + i = 2; + for( ; !(i >= y_size); i = i + 1) + { + signed int window_size=i; + j = 0; + for( ; !(j >= y_size); j = j + 1) + { + if(!(window_size >= window_timer)) + { + window_timer = 0; + window_count = 0; + } + + signed int window_index=j + window_size; + if(!(window_index >= y_size)) + { + if(y[(signed long int)j] == y[(signed long int)window_index]) + { + window_count = window_count + 1; + __DSVERIFIER_assert(!(window_count == window_size)); + } + + } + + else + break; + window_timer = window_timer + 1; + } + } +} + +// fxp_check_persistent_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 201 +void fxp_check_persistent_limit_cycle(signed long int *y, signed int y_size) +{ + signed int idy=0; + signed int count_same=0; + signed int window_size=0; + signed long int reference=y[0l]; + idy = 0; + for( ; !(idy >= y_size); idy = idy + 1) + if(!(y[(signed long int)idy] == reference)) + window_size = window_size + 1; + + else + if(!(window_size == 0)) + break; + + else + count_same = count_same + 1; + window_size = window_size + count_same; + __DSVERIFIER_assume(window_size > 1 && window_size <= y_size / 2); + const signed long int reference$array_size0=(signed long int)window_size; + signed long int lco_elements[reference$array_size0]; + idy = 0; + for( ; !(idy >= y_size); idy = idy + 1) + if(!(idy >= window_size)) + lco_elements[(signed long int)idy] = y[(signed long int)idy]; + + idy = 0; + signed int lco_idy=0; + _Bool is_persistent=(_Bool)0; + while(!(idy >= y_size)) + { + signed int tmp_post$1=idy; + idy = idy + 1; + signed int tmp_post$2=lco_idy; + lco_idy = lco_idy + 1; + if(y[(signed long int)tmp_post$1] == lco_elements[(signed long int)tmp_post$2]) + is_persistent = (_Bool)0; + + else + { + is_persistent = (_Bool)0; + break; + } + if(lco_idy == window_size) + lco_idy = 0; + + } + __DSVERIFIER_assert((signed int)is_persistent == 0); +} + +// fxp_determinant +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 529 +double fxp_determinant(signed long int (*a_fxp)[20l], signed int n) +{ + signed int i; + signed int j; + signed int j1; + signed int j2; + double a[20l][20l]; + i = 0; + for( ; !(i >= n); i = i + 1) + { + j = 0; + for( ; !(j >= n); j = j + 1) + a[(signed long int)i][(signed long int)j]=fxp_to_double(a_fxp[(signed long int)i][(signed long int)j]); + } + double det=0.000000; + double m[20l][20l]; + if(n >= 1) + { + if(n == 1) + det = a[0l][0l]; + + else + if(n == 2) + det = a[0l][0l] * a[1l][1l] - a[1l][0l] * a[0l][1l]; + + else + { + det = 0.000000; + j1 = 0; + for( ; !(j1 >= n); j1 = j1 + 1) + { + i = 0; + for( ; !(i >= -1 + n); i = i + 1) + { + i = 1; + for( ; !(i >= n); i = i + 1) + { + j2 = 0; + j = 0; + for( ; !(j >= n); j = j + 1) + if(!(j == j1)) + { + m[(signed long int)(i - 1)][(signed long int)j2] = a[(signed long int)i][(signed long int)j]; + j2 = j2 + 1; + } + + } + } + double return_value_internal_pow$1=internal_pow(-1.000000, 1.000000 + (double)j1 + 1.000000); + double return_value_determinant$2=determinant(m, n - 1); + det = det + return_value_internal_pow$1 * a[0l][(signed long int)j1] * return_value_determinant$2; + } + } + } + + return det; +} + +// fxp_direct_form_1 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 22 +signed long int fxp_direct_form_1(signed long int *y, signed long int *x, signed long int *a, signed long int *b, signed int Na, signed int Nb) +{ + signed long int *a_ptr; + signed long int *y_ptr; + signed long int *b_ptr; + signed long int *x_ptr; + signed long int sum=0l; + a_ptr = &a[1l]; + y_ptr = &y[(signed long int)(Na - 1)]; + b_ptr = &b[0l]; + x_ptr = &x[(signed long int)(Nb - 1)]; + signed int i; + signed int j; + i = 0; + for( ; !(i >= Nb); i = i + 1) + { + signed long int *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + signed long int *tmp_post$2=x_ptr; + x_ptr = x_ptr - 1l; + signed long int return_value_fxp_mult$3=fxp_mult(*tmp_post$1, *tmp_post$2); + sum=fxp_add(sum, return_value_fxp_mult$3); + } + j = 1; + for( ; !(j >= Na); j = j + 1) + { + signed long int *tmp_post$4=a_ptr; + a_ptr = a_ptr + 1l; + signed long int *tmp_post$5=y_ptr; + y_ptr = y_ptr - 1l; + signed long int return_value_fxp_mult$6=fxp_mult(*tmp_post$4, *tmp_post$5); + sum=fxp_sub(sum, return_value_fxp_mult$6); + } + sum=fxp_div(sum, a[0l]); + signed long int return_value_fxp_quantize$7=fxp_quantize(sum); + return return_value_fxp_quantize$7; +} + +// fxp_direct_form_1_impl2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 388 +void fxp_direct_form_1_impl2(signed long int *x, signed int x_size, signed long int *b, signed int b_size, signed long int *a, signed int a_size, signed long int *y) +{ + signed int i=0; + signed int j=0; + const signed long int j$array_size0=(signed long int)x_size; + signed long int v[j$array_size0]; + i = 0; + for( ; !(i >= x_size); i = i + 1) + { + v[(signed long int)i] = 0l; + j = 0; + for( ; !(j >= b_size); j = j + 1) + { + if(!(i >= j)) + break; + + signed long int return_value_fxp_mult$1=fxp_mult(x[(signed long int)(i - j)], b[(signed long int)j]); + v[(signed long int)i]=fxp_add(v[(signed long int)i], return_value_fxp_mult$1); + } + } + y[0l] = v[0l]; + i = 1; + for( ; !(i >= x_size); i = i + 1) + { + y[(signed long int)i] = 0l; + y[(signed long int)i]=fxp_add(y[(signed long int)i], v[(signed long int)i]); + j = 1; + for( ; !(j >= a_size); j = j + 1) + { + if(!(i >= j)) + break; + + signed long int return_value_fxp_mult$2=fxp_mult(y[(signed long int)(i - j)], -a[(signed long int)j]); + y[(signed long int)i]=fxp_add(y[(signed long int)i], return_value_fxp_mult$2); + } + } +} + +// fxp_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 41 +signed long int fxp_direct_form_2(signed long int *w, signed long int x, signed long int *a, signed long int *b, signed int Na, signed int Nb) +{ + signed long int *a_ptr; + signed long int *b_ptr; + signed long int *w_ptr; + signed long int sum=0l; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + w_ptr = &w[1l]; + signed int k; + signed int j=1; + for( ; !(j >= Na); j = j + 1) + { + signed long int *tmp_post$1=a_ptr; + a_ptr = a_ptr + 1l; + signed long int *tmp_post$2=w_ptr; + w_ptr = w_ptr + 1l; + signed long int return_value_fxp_mult$3=fxp_mult(*tmp_post$1, *tmp_post$2); + w[0l]=fxp_sub(w[0l], return_value_fxp_mult$3); + } + w[0l]=fxp_add(w[0l], x); + w[0l]=fxp_div(w[0l], a[0l]); + w_ptr = &w[0l]; + k = 0; + for( ; !(k >= Nb); k = k + 1) + { + signed long int *tmp_post$4=b_ptr; + b_ptr = b_ptr + 1l; + signed long int *tmp_post$5=w_ptr; + w_ptr = w_ptr + 1l; + signed long int return_value_fxp_mult$6=fxp_mult(*tmp_post$4, *tmp_post$5); + sum=fxp_add(sum, return_value_fxp_mult$6); + } + signed long int return_value_fxp_quantize$7=fxp_quantize(sum); + return return_value_fxp_quantize$7; +} + +// fxp_div +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 357 +signed long int fxp_div(signed long int a, signed long int b) +{ + signed long int tmpdiv=(a << impl.frac_bits) / b; + return tmpdiv; +} + +// fxp_double_to_fxp +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 211 +signed long int fxp_double_to_fxp(double value) +{ + signed long int tmp; + double ftemp=value * scale_factor[(signed long int)impl.frac_bits]; + if(rounding_mode == 0) + { + if(value >= 0.000000) + tmp = (signed long int)(ftemp + 5.000000e-1); + + else + tmp = (signed long int)(ftemp - 5.000000e-1); + } + + else + if(rounding_mode == 1) + { + tmp = (signed long int)ftemp; + double residue=ftemp - (double)tmp; + if(value < 0.000000 && IEEE_FLOAT_NOTEQUAL(residue, 0.000000)) + { + ftemp = ftemp - 1.000000; + tmp = (signed long int)ftemp; + } + + } + + else + if(rounding_mode == 0) + tmp = (signed long int)ftemp; + + return tmp; +} + +// fxp_double_to_fxp_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 247 +void fxp_double_to_fxp_array(double *f, signed long int *r, signed int N) +{ + signed int i=0; + for( ; !(i >= N); i = i + 1) + r[(signed long int)i]=fxp_double_to_fxp(f[(signed long int)i]); +} + +// fxp_exp_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 390 +void fxp_exp_matrix(unsigned int lines, unsigned int columns, signed long int (*m1)[20l], unsigned int expNumber, signed long int (*result)[20l]) +{ + unsigned int i; + unsigned int j; + unsigned int l; + unsigned int k; + signed long int m2[20l][20l]; + if(expNumber == 0u) + { + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + if(i == j) + result[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(1.000000); + + else + result[(signed long int)i][(signed long int)j] = 0l; + } + } + + else + { + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + result[(signed long int)i][(signed long int)j] = m1[(signed long int)i][(signed long int)j]; + } + if(!(expNumber == 1u)) + { + l = 1u; + for( ; !(l >= expNumber); l = l + 1u) + { + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + m2[(signed long int)i][(signed long int)j] = result[(signed long int)i][(signed long int)j]; + } + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + result[(signed long int)i][(signed long int)j] = 0l; + } + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + { + k = 0u; + for( ; !(k >= columns); k = k + 1u) + { + signed long int return_value_fxp_mult$1=fxp_mult(m2[(signed long int)i][(signed long int)k], m1[(signed long int)k][(signed long int)j]); + result[(signed long int)i][(signed long int)j]=fxp_add(result[(signed long int)i][(signed long int)j], return_value_fxp_mult$1); + } + } + } + } + } + + } +} + +// fxp_float_to_fxp +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 198 +signed long int fxp_float_to_fxp(float f) +{ + signed long int tmp; + double ftemp=(double)f * scale_factor[(signed long int)impl.frac_bits]; + if(f >= 0.000000f) + tmp = (signed long int)(ftemp + 5.000000e-1); + + else + tmp = (signed long int)(ftemp - 5.000000e-1); + return tmp; +} + +// fxp_float_to_fxp_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 240 +void fxp_float_to_fxp_array(float *f, signed long int *r, signed int N) +{ + signed int i=0; + for( ; !(i >= N); i = i + 1) + r[(signed long int)i]=fxp_float_to_fxp(f[(signed long int)i]); +} + +// fxp_get_frac_part +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 125 +signed long int fxp_get_frac_part(signed long int in) +{ + return in < 0l ? -(-in & _fxp_fmask) : in & _fxp_fmask; +} + +// fxp_get_int_part +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 115 +signed long int fxp_get_int_part(signed long int in) +{ + return in < 0l ? -(-in & _fxp_imask) : in & _fxp_imask; +} + +// fxp_int_to_fxp +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 170 +signed long int fxp_int_to_fxp(signed int in) +{ + signed long int lin=(signed long int)in * _fxp_one; + return lin; +} + +// fxp_ln +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 288 +signed int fxp_ln(signed int x) +{ + signed int t; + signed int y=0xA65AF; + if(!(x >= 0x8000)) + { + x = x << 16; + y = y - 0xB1721; + } + + if(!(x >= 0x800000)) + { + x = x << 8; + y = y - 0x58B91; + } + + if(!(x >= 0x8000000)) + { + x = x << 4; + y = y - 0x2C5C8; + } + + if(!(x >= 0x20000000)) + { + x = x << 2; + y = y - 0x162E4; + } + + if(!(x >= 0x40000000)) + { + x = x << 1; + y = y - 0xB172; + } + + t = x + (x >> 1); + if((0x80000000u & (unsigned int)t) == 0u) + { + x = t; + y = y - 0x67CD; + } + + t = x + (x >> 2); + if((0x80000000u & (unsigned int)t) == 0u) + { + x = t; + y = y - 0x3920; + } + + t = x + (x >> 3); + if((0x80000000u & (unsigned int)t) == 0u) + { + x = t; + y = y - 0x1E27; + } + + t = x + (x >> 4); + if((0x80000000u & (unsigned int)t) == 0u) + { + x = t; + y = y - 0xF85; + } + + t = x + (x >> 5); + if((0x80000000u & (unsigned int)t) == 0u) + { + x = t; + y = y - 0x7E1; + } + + t = x + (x >> 6); + if((0x80000000u & (unsigned int)t) == 0u) + { + x = t; + y = y - 0x3F8; + } + + t = x + (x >> 7); + if((0x80000000u & (unsigned int)t) == 0u) + { + x = t; + y = y - 0x1FE; + } + + x = (signed int)(0x80000000u - (unsigned int)x); + y = y - (x >> 15); + return y; +} + +// fxp_log10 +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 345 +double fxp_log10(double x) +{ + if(x > 32767.000000) + { + if(x > 1.073676e+9) + { + x = x / 1.073676e+9; + double return_value_fxp_log10_low$1=fxp_log10_low(x); + return return_value_fxp_log10_low$1 + 9.030873e+0; + } + + x = x / 32767.000000; + double return_value_fxp_log10_low$2=fxp_log10_low(x); + return return_value_fxp_log10_low$2 + 4.515437e+0; + } + + else + { + double return_value_fxp_log10_low$3=fxp_log10_low(x); + return return_value_fxp_log10_low$3; + } +} + +// fxp_log10_low +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 333 +double fxp_log10_low(double x) +{ + signed int xint=(signed int)(x * 65536.000000 + 5.000000e-1); + signed int lnum=fxp_ln(xint); + signed int lden=fxp_ln(655360); + return (double)lnum / (double)lden; +} + +// fxp_matrix_multiplication +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 368 +void fxp_matrix_multiplication(unsigned int i1, unsigned int j1, unsigned int i2, unsigned int j2, signed long int (*m1)[20l], signed long int (*m2)[20l], signed long int (*m3)[20l]) +{ + unsigned int i; + unsigned int j; + unsigned int k; + if(j1 == i2) + { + i = 0u; + for( ; !(i >= i1); i = i + 1u) + { + j = 0u; + for( ; !(j >= j2); j = j + 1u) + m3[(signed long int)i][(signed long int)j] = 0l; + } + i = 0u; + for( ; !(i >= i1); i = i + 1u) + { + j = 0u; + for( ; !(j >= j2); j = j + 1u) + { + k = 0u; + for( ; !(k >= j1); k = k + 1u) + { + signed long int return_value_fxp_mult$1=fxp_mult(m1[(signed long int)i][(signed long int)k], m2[(signed long int)k][(signed long int)j]); + m3[(signed long int)i][(signed long int)j]=fxp_add(m3[(signed long int)i][(signed long int)j], return_value_fxp_mult$1); + } + } + } + } + + else + printf("\nError! Operation invalid, please enter with valid matrices.\n"); +} + +// fxp_mult +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 339 +signed long int fxp_mult(signed long int amult, signed long int bmult) +{ + signed long int tmpmult; + signed long int tmpmultprec; + tmpmult = (signed long int)((signed long int)amult * (signed long int)bmult); + if(tmpmult >= 0l) + tmpmultprec = tmpmult + ((tmpmult & (signed long int)(1 << impl.frac_bits - 1)) << 1) >> impl.frac_bits; + + else + tmpmultprec = -(-tmpmult + ((-tmpmult & (signed long int)(1 << impl.frac_bits - 1)) << 1) >> impl.frac_bits); + return tmpmultprec; +} + +// fxp_neg +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 367 +signed long int fxp_neg(signed long int aneg) +{ + signed long int tmpneg=-((signed long int)aneg); + return tmpneg; +} + +// fxp_print_float +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 407 +void fxp_print_float(signed long int a) +{ + float return_value_fxp_to_float$1=fxp_to_float(a); + printf("\n%f", return_value_fxp_to_float$1); +} + +// fxp_print_float_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 411 +void fxp_print_float_array(signed long int *a, signed int N) +{ + signed int i=0; + for( ; !(i >= N); i = i + 1) + { + float return_value_fxp_to_float$1=fxp_to_float(a[(signed long int)i]); + printf("\n%f", return_value_fxp_to_float$1); + } +} + +// fxp_print_int +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 403 +void fxp_print_int(signed long int a) +{ + printf("\n%i", (signed int)a); +} + +// fxp_quantize +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 136 +signed long int fxp_quantize(signed long int aquant) +{ + if(overflow_mode == 2) + { + if(!(aquant >= _fxp_min)) + return _fxp_min; + + else + if(!(_fxp_max >= aquant)) + return _fxp_max; + + } + + else + if(overflow_mode == 3) + { + if(!(_fxp_max >= aquant) || !(aquant >= _fxp_min)) + { + signed long int return_value_wrap$1=wrap(aquant, _fxp_min, _fxp_max); + return return_value_wrap$1; + } + + } + + return (signed long int)aquant; +} + +// fxp_shrl +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 390 +signed long int fxp_shrl(signed long int in, signed int shift) +{ + return (signed long int)((unsigned int)in >> shift); +} + +// fxp_sign +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 380 +signed long int fxp_sign(signed long int a) +{ + return a == 0l ? 0l : (a < 0l ? _fxp_minus_one : _fxp_one); +} + +// fxp_square +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 399 +signed long int fxp_square(signed long int a) +{ + signed long int return_value_fxp_mult$1=fxp_mult(a, a); + return return_value_fxp_mult$1; +} + +// fxp_state_space_representation +// file /home/lucascordeiro/dsverifier/bmc/core/state-space.h line 67 +double fxp_state_space_representation(void) +{ + signed long int result1[20l][20l]; + signed long int result2[20l][20l]; + signed int i; + signed int j; + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + { + result1[(signed long int)i][(signed long int)j] = 0l; + result2[(signed long int)i][(signed long int)j] = 0l; + } + } + signed long int A_fpx[20l][20l]; + signed long int B_fpx[20l][20l]; + signed long int C_fpx[20l][20l]; + signed long int D_fpx[20l][20l]; + signed long int states_fpx[20l][20l]; + signed long int inputs_fpx[20l][20l]; + signed long int outputs_fpx[20l][20l]; + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + A_fpx[(signed long int)i][(signed long int)j] = 0l; + } + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + B_fpx[(signed long int)i][(signed long int)j] = 0l; + } + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + C_fpx[(signed long int)i][(signed long int)j] = 0l; + } + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + D_fpx[(signed long int)i][(signed long int)j] = 0l; + } + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + states_fpx[(signed long int)i][(signed long int)j] = 0l; + } + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + inputs_fpx[(signed long int)i][(signed long int)j] = 0l; + } + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + outputs_fpx[(signed long int)i][(signed long int)j] = 0l; + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + A_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.A[(signed long int)i][(signed long int)j]); + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs); j = j + 1) + B_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.B[(signed long int)i][(signed long int)j]); + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + C_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.C[(signed long int)i][(signed long int)j]); + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs); j = j + 1) + D_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.D[(signed long int)i][(signed long int)j]); + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + states_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.states[(signed long int)i][(signed long int)j]); + } + i = 0; + for( ; !(i >= nInputs); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + inputs_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.inputs[(signed long int)i][(signed long int)j]); + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + outputs_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.outputs[(signed long int)i][(signed long int)j]); + } + fxp_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nStates, (unsigned int)nStates, 1u, C_fpx, states_fpx, result1); + fxp_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nInputs, (unsigned int)nInputs, 1u, D_fpx, inputs_fpx, result2); + fxp_add_matrix((unsigned int)nOutputs, 1u, result1, result2, outputs_fpx); + i = 1; + for( ; !(i >= 0); i = i + 1) + { + fxp_matrix_multiplication((unsigned int)nStates, (unsigned int)nStates, (unsigned int)nStates, 1u, A_fpx, states_fpx, result1); + fxp_matrix_multiplication((unsigned int)nStates, (unsigned int)nInputs, (unsigned int)nInputs, 1u, B_fpx, inputs_fpx, result2); + fxp_add_matrix((unsigned int)nStates, 1u, result1, result2, states_fpx); + fxp_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nStates, (unsigned int)nStates, 1u, C_fpx, states_fpx, result1); + fxp_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nInputs, (unsigned int)nInputs, 1u, D_fpx, inputs_fpx, result2); + fxp_add_matrix((unsigned int)nOutputs, 1u, result1, result2, outputs_fpx); + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + _controller.states[(signed long int)i][(signed long int)j]=fxp_to_double(states_fpx[(signed long int)i][(signed long int)j]); + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + _controller.outputs[(signed long int)i][(signed long int)j]=fxp_to_double(outputs_fpx[(signed long int)i][(signed long int)j]); + } + return _controller.outputs[0l][0l]; +} + +// fxp_sub +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 327 +signed long int fxp_sub(signed long int asub, signed long int bsub) +{ + signed long int tmpsub=(signed long int)((signed long int)asub - (signed long int)bsub); + return tmpsub; +} + +// fxp_sub_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 474 +void fxp_sub_matrix(unsigned int lines, unsigned int columns, signed long int (*m1)[20l], signed long int (*m2)[20l], signed long int (*result)[20l]) +{ + unsigned int i; + unsigned int j; + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + result[(signed long int)i][(signed long int)j]=fxp_sub(m1[(signed long int)i][(signed long int)j], m2[(signed long int)i][(signed long int)j]); + } +} + +// fxp_to_double +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 271 +double fxp_to_double(signed long int fxp) +{ + double f; + signed int f_int=(signed int)fxp; + f = (double)f_int * scale_factor_inv[(signed long int)impl.frac_bits]; + return f; +} + +// fxp_to_double_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 291 +void fxp_to_double_array(double *f, signed long int *r, signed int N) +{ + signed int i=0; + for( ; !(i >= N); i = i + 1) + f[(signed long int)i]=fxp_to_double(r[(signed long int)i]); +} + +// fxp_to_float +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 264 +float fxp_to_float(signed long int fxp) +{ + float f; + signed int f_int=(signed int)fxp; + f = (float)((double)f_int * scale_factor_inv[(signed long int)impl.frac_bits]); + return f; +} + +// fxp_to_float_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 284 +void fxp_to_float_array(float *f, signed long int *r, signed int N) +{ + signed int i=0; + for( ; !(i >= N); i = i + 1) + f[(signed long int)i]=fxp_to_float(r[(signed long int)i]); +} + +// fxp_to_int +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 182 +signed int fxp_to_int(signed long int fxp) +{ + if(fxp >= 0l) + fxp = fxp + _fxp_half; + + else + fxp = fxp - _fxp_half; + fxp = fxp >> impl.frac_bits; + return (signed int)fxp; +} + +// fxp_transpose +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 582 +void fxp_transpose(signed long int (*a)[20l], signed long int (*b)[20l], signed int n, signed int m) +{ + signed int i; + signed int j; + i = 0; + for( ; !(i >= n); i = i + 1) + { + j = 0; + for( ; !(j >= m); j = j + 1) + b[(signed long int)j][(signed long int)i] = a[(signed long int)i][(signed long int)j]; + } +} + +// fxp_transposed_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 61 +signed long int fxp_transposed_direct_form_2(signed long int *w, signed long int x, signed long int *a, signed long int *b, signed int Na, signed int Nb) +{ + signed long int *a_ptr; + signed long int *b_ptr; + signed long int yout=0l; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + signed int Nw=Na > Nb ? Na : Nb; + signed long int *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + signed long int return_value_fxp_mult$2=fxp_mult(*tmp_post$1, x); + yout=fxp_add(return_value_fxp_mult$2, w[0l]); + yout=fxp_div(yout, a[0l]); + signed int j=0; + for( ; !(j >= -1 + Nw); j = j + 1) + { + w[(signed long int)j] = w[(signed long int)(j + 1)]; + if(!(j >= -1 + Na)) + { + signed long int *tmp_post$3=a_ptr; + a_ptr = a_ptr + 1l; + signed long int return_value_fxp_mult$4=fxp_mult(*tmp_post$3, yout); + w[(signed long int)j]=fxp_sub(w[(signed long int)j], return_value_fxp_mult$4); + } + + if(!(j >= -1 + Nb)) + { + signed long int *tmp_post$5=b_ptr; + b_ptr = b_ptr + 1l; + signed long int return_value_fxp_mult$6=fxp_mult(*tmp_post$5, x); + w[(signed long int)j]=fxp_add(w[(signed long int)j], return_value_fxp_mult$6); + } + + } + signed long int return_value_fxp_quantize$7=fxp_quantize(yout); + return return_value_fxp_quantize$7; +} + +// fxp_verify_overflow +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 153 +void fxp_verify_overflow(signed long int value) +{ + fxp_quantize(value); + __DSVERIFIER_assert(value <= _fxp_max && value >= _fxp_min); +} + +// fxp_verify_overflow_array +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 158 +void fxp_verify_overflow_array(signed long int *array, signed int n) +{ + signed int i=0; + i = 0; + for( ; !(i >= n); i = i + 1) + fxp_verify_overflow(array[(signed long int)i]); +} + +// generate_delta_coefficients +// file /home/lucascordeiro/dsverifier/bmc/core/delta-operator.h line 33 +void generate_delta_coefficients(double *vetor, double *out, signed int n, double delta) +{ + signed int i; + signed int j; + signed int N=n - 1; + double sum_delta_operator; + i = 0; + for( ; N >= i; i = i + 1) + { + sum_delta_operator = 0.000000; + j = 0; + for( ; i >= j; j = j + 1) + { + signed int return_value_nchoosek$1=nchoosek(N - j, i - j); + sum_delta_operator = sum_delta_operator + vetor[(signed long int)j] * (double)return_value_nchoosek$1; + } + double return_value_internal_pow$2=internal_pow(delta, (double)(N - i)); + out[(signed long int)i] = return_value_internal_pow$2 * sum_delta_operator; + } +} + +// generic_timing_double_direct_form_1 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 286 +double generic_timing_double_direct_form_1(double *y, double *x, double *a, double *b, signed int Na, signed int Nb) +{ + generic_timer = generic_timer + 6 * hw.assembly.push + 3 * hw.assembly.in + 1 * hw.assembly.sbiw + 1 * hw.assembly.cli + 3 * hw.assembly.out + 12 * hw.assembly.std; + double *a_ptr; + double *y_ptr; + double *b_ptr; + double *x_ptr; + double sum=0.000000; + a_ptr = &a[1l]; + y_ptr = &y[(signed long int)(Na - 1)]; + b_ptr = &b[0l]; + x_ptr = &x[(signed long int)(Nb - 1)]; + generic_timer = generic_timer + 12 * hw.assembly.std + 12 * hw.assembly.ldd + 2 * hw.assembly.subi + 2 * hw.assembly.sbci + 4 * hw.assembly.lsl + 4 * hw.assembly.rol + 2 * hw.assembly.add + 2 * hw.assembly.adc + 1 * hw.assembly.adiw; + signed int i; + signed int j; + generic_timer = generic_timer + 2 * hw.assembly.std + 1 * hw.assembly.rjmp; + i = 0; + for( ; !(i >= Nb); i = i + 1) + { + generic_timer = generic_timer + 20 * hw.assembly.ldd + 24 * hw.assembly.mov + 2 * hw.assembly.subi + 1 * hw.assembly.sbci + 1 * hw.assembly.sbc + 10 * hw.assembly.std + 2 * hw.assembly.ld + 2 * hw.assembly.rcall + 1 * hw.assembly.adiw + 1 * hw.assembly.cp + 1 * hw.assembly.cpc + 1 * hw.assembly.adiw + 1 * hw.assembly.brge + 1 * hw.assembly.rjmp; + double *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + double *tmp_post$2=x_ptr; + x_ptr = x_ptr - 1l; + sum = sum + *tmp_post$1 * *tmp_post$2; + } + generic_timer = generic_timer + 2 * hw.assembly.ldi + 2 * hw.assembly.std + 1 * hw.assembly.rjmp; + j = 1; + for( ; !(j >= Na); j = j + 1) + { + generic_timer = generic_timer + 22 * hw.assembly.ldd + 24 * hw.assembly.mov + 2 * hw.assembly.subi + 8 * hw.assembly.std + 1 * hw.assembly.sbci + 2 * hw.assembly.ld + 2 * hw.assembly.rcall + 1 * hw.assembly.sbc + 1 * hw.assembly.adiw + 1 * hw.assembly.cp + 1 * hw.assembly.cpc + 1 * hw.assembly.adiw + 1 * hw.assembly.brge + 1 * hw.assembly.rjmp; + double *tmp_post$3=a_ptr; + a_ptr = a_ptr + 1l; + double *tmp_post$4=y_ptr; + y_ptr = y_ptr - 1l; + sum = sum - *tmp_post$3 * *tmp_post$4; + } + generic_timer = generic_timer + 4 * hw.assembly.ldd + 4 * hw.assembly.mov + 1 * hw.assembly.adiw + 1 * hw.assembly.in + 1 * hw.assembly.cli + 3 * hw.assembly.out + 6 * hw.assembly.pop + 1 * hw.assembly.ret; + return sum; +} + +// generic_timing_double_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 311 +double generic_timing_double_direct_form_2(double *w, double x, double *a, double *b, signed int Na, signed int Nb) +{ + generic_timer = generic_timer + 8 * hw.assembly.push + 14 * hw.assembly.std + 3 * hw.assembly.out + 3 * hw.assembly.in + 1 * hw.assembly.sbiw + 1 * hw.assembly.cli; + double *a_ptr; + double *b_ptr; + double *w_ptr; + double sum=0.000000; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + w_ptr = &w[1l]; + signed int k; + signed int j; + generic_timer = generic_timer + 10 * hw.assembly.std + 6 * hw.assembly.ldd + 2 * hw.assembly.adiw; + generic_timer = generic_timer + 2 * hw.assembly.ldi + 2 * hw.assembly.std + 1 * hw.assembly.rjmp; + j = 1; + for( ; !(j >= Na); j = j + 1) + { + double *tmp_post$1=a_ptr; + a_ptr = a_ptr + 1l; + double *tmp_post$2=w_ptr; + w_ptr = w_ptr + 1l; + w[0l] = w[0l] - *tmp_post$1 * *tmp_post$2; + generic_timer = generic_timer + 23 * hw.assembly.ldd + 32 * hw.assembly.mov + 9 * hw.assembly.std + 2 * hw.assembly.subi + 3 * hw.assembly.ld + 2 * hw.assembly.rcall + 2 * hw.assembly.sbci + 1 * hw.assembly.st + 1 * hw.assembly.adiw + 1 * hw.assembly.cp + 1 * hw.assembly.cpc + 1 * hw.assembly.brge; + } + w[0l] = w[0l] + x; + w_ptr = &w[0l]; + generic_timer = generic_timer + 13 * hw.assembly.ldd + 12 * hw.assembly.mov + 5 * hw.assembly.std + 1 * hw.assembly.st + 1 * hw.assembly.ld + 1 * hw.assembly.rcall; + generic_timer = generic_timer + 2 * hw.assembly.std + 1 * hw.assembly.rjmp; + k = 0; + for( ; !(k >= Nb); k = k + 1) + { + double *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + double *tmp_post$4=w_ptr; + w_ptr = w_ptr + 1l; + sum = sum + *tmp_post$3 * *tmp_post$4; + generic_timer = generic_timer + 20 * hw.assembly.ldd + 24 * hw.assembly.mov + 10 * hw.assembly.std + 2 * hw.assembly.rcall + 2 * hw.assembly.ld + 2 * hw.assembly.subi + 2 * hw.assembly.sbci + 1 * hw.assembly.adiw + 1 * hw.assembly.cp + 1 * hw.assembly.cpc + 1 * hw.assembly.brge + 1 * hw.assembly.rjmp; + } + generic_timer = generic_timer + 4 * hw.assembly.ldd + 4 * hw.assembly.mov + 1 * hw.assembly.adiw + 1 * hw.assembly.in + 1 * hw.assembly.cli + 3 * hw.assembly.out + 8 * hw.assembly.pop + 1 * hw.assembly.ret; + return sum; +} + +// generic_timing_double_transposed_direct_form_2 +// file /home/lucascordeiro/dsverifier/bmc/core/realizations.h line 338 +double generic_timing_double_transposed_direct_form_2(double *w, double x, double *a, double *b, signed int Na, signed int Nb) +{ + generic_timer = generic_timer + 8 * hw.assembly.push + 14 * hw.assembly.std + 3 * hw.assembly.out + 3 * hw.assembly.in + 1 * hw.assembly.sbiw + 1 * hw.assembly.cli; + double *a_ptr; + double *b_ptr; + double yout=0.000000; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + signed int Nw=Na > Nb ? Na : Nb; + double *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + yout = *tmp_post$1 * x + w[0l]; + signed int j; + generic_timer = generic_timer + 15 * hw.assembly.std + 22 * hw.assembly.ldd + 24 * hw.assembly.mov + 2 * hw.assembly.rcall + 2 * hw.assembly.ld + 1 * hw.assembly.cp + 1 * hw.assembly.cpc + 1 * hw.assembly.subi + 1 * hw.assembly.sbci + 1 * hw.assembly.brge + 1 * hw.assembly.adiw; + generic_timer = generic_timer + 2 * hw.assembly.std + 1 * hw.assembly.rjmp; + j = 0; + for( ; !(j >= -1 + Nw); j = j + 1) + { + w[(signed long int)j] = w[(signed long int)(j + 1)]; + if(!(j >= -1 + Na)) + { + double *tmp_post$2=a_ptr; + a_ptr = a_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] - *tmp_post$2 * yout; + } + + if(!(j >= -1 + Nb)) + { + double *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] + *tmp_post$3 * x; + } + + generic_timer = generic_timer + 70 * hw.assembly.mov + 65 * hw.assembly.ldd + 12 * hw.assembly.lsl + 12 * hw.assembly.rol + 15 * hw.assembly.std + 6 * hw.assembly.add + 6 * hw.assembly.adc + 2 * hw.assembly.adiw + 3 * hw.assembly.cpc + 3 * hw.assembly.cp + 5 * hw.assembly.ld + 4 * hw.assembly.rcall + 5 * hw.assembly.subi + 3 * hw.assembly.rjmp + 2 * hw.assembly.brlt + 3 * hw.assembly.st + 2 * hw.assembly.sbci + 3 * hw.assembly.sbc + 1 * hw.assembly.brge; + } + generic_timer = generic_timer + 4 * hw.assembly.ldd + 4 * hw.assembly.mov + 8 * hw.assembly.pop + 3 * hw.assembly.out + 1 * hw.assembly.in + 1 * hw.assembly.cli + 1 * hw.assembly.adiw + 1 * hw.assembly.ret; + return yout; +} + +// generic_timing_shift_l_double +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 20 +double generic_timing_shift_l_double(double zIn, double *z, signed int N) +{ + generic_timer = generic_timer + 2 * hw.assembly.push + 3 * hw.assembly.in + 3 * hw.assembly.out + 1 * hw.assembly.sbiw + 1 * hw.assembly.cli + 8 * hw.assembly.std; + signed int i; + double zOut=z[0l]; + generic_timer = generic_timer + 5 * hw.assembly.ldd + 2 * hw.assembly.mov + 4 * hw.assembly.std + 1 * hw.assembly.ld; + generic_timer = generic_timer + 2 * hw.assembly.std + 1 * hw.assembly.rjmp; + i = 0; + for( ; !(i >= -1 + N); i = i + 1) + { + generic_timer = generic_timer + 17 * hw.assembly.ldd + 4 * hw.assembly.lsl + 4 * hw.assembly.rol + 2 * hw.assembly.add + 2 * hw.assembly.adc + 6 * hw.assembly.mov + 2 * hw.assembly.adiw + 5 * hw.assembly.std + 1 * hw.assembly.ld + 1 * hw.assembly.st + 1 * hw.assembly.subi + 1 * hw.assembly.sbc + 1 * hw.assembly.cp + 1 * hw.assembly.cpc + 1 * hw.assembly.brlt; + z[(signed long int)i] = z[(signed long int)(i + 1)]; + } + z[(signed long int)(N - 1)] = zIn; + generic_timer = generic_timer + 12 * hw.assembly.ldd + 6 * hw.assembly.mov + 3 * hw.assembly.std + 2 * hw.assembly.lsl + 2 * hw.assembly.rol + 1 * hw.assembly.adc + 1 * hw.assembly.add + 1 * hw.assembly.subi + 1 * hw.assembly.sbci + 1 * hw.assembly.st + 1 * hw.assembly.adiw + 1 * hw.assembly.in + 1 * hw.assembly.cli; + generic_timer = generic_timer + 3 * hw.assembly.out + 2 * hw.assembly.pop + 1 * hw.assembly.ret; + return zOut; +} + +// generic_timing_shift_r_double +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 37 +double generic_timing_shift_r_double(double zIn, double *z, signed int N) +{ + generic_timer = generic_timer + 2 * hw.assembly.push + 3 * hw.assembly.in + 3 * hw.assembly.out + 1 * hw.assembly.sbiw + 1 * hw.assembly.cli + 8 * hw.assembly.std; + signed int i; + double zOut=z[(signed long int)(N - 1)]; + generic_timer = generic_timer + 7 * hw.assembly.ldd + 2 * hw.assembly.rol + 2 * hw.assembly.lsl + 2 * hw.assembly.mov + 4 * hw.assembly.std + 1 * hw.assembly.add + 1 * hw.assembly.adc + 1 * hw.assembly.ld + 1 * hw.assembly.subi + 1 * hw.assembly.sbci; + generic_timer = generic_timer + 2 * hw.assembly.ldd + 2 * hw.assembly.std + 1 * hw.assembly.sbiw + 1 * hw.assembly.rjmp; + i = N - 1; + for( ; i >= 1; i = i - 1) + { + z[(signed long int)i] = z[(signed long int)(i - 1)]; + generic_timer = generic_timer + 15 * hw.assembly.ldd + 4 * hw.assembly.lsl + 4 * hw.assembly.rol + 2 * hw.assembly.add + 2 * hw.assembly.adc + 4 * hw.assembly.mov + 5 * hw.assembly.std + 1 * hw.assembly.subi + 1 * hw.assembly.sbci + 1 * hw.assembly.ld + 1 * hw.assembly.st + 1 * hw.assembly.sbiw + 1 * hw.assembly.cp + 1 * hw.assembly.cpc + 1 * hw.assembly.brlt; + } + z[0l] = zIn; + generic_timer = generic_timer + 10 * hw.assembly.ldd + 5 * hw.assembly.mov + 3 * hw.assembly.std + 3 * hw.assembly.out + 2 * hw.assembly.pop + 1 * hw.assembly.ret + 1 * hw.assembly.ret + 1 * hw.assembly.cli + 1 * hw.assembly.in + 1 * hw.assembly.st + 1 * hw.assembly.adiw; + return zOut; +} + +// get_delta_transfer_function +// file /home/lucascordeiro/dsverifier/bmc/core/delta-operator.h line 52 +void get_delta_transfer_function(double *b, double *b_out, signed int b_size, double *a, double *a_out, signed int a_size, double delta) +{ + generate_delta_coefficients(b, b_out, b_size, delta); + generate_delta_coefficients(a, a_out, a_size, delta); +} + +// get_delta_transfer_function_with_base +// file /home/lucascordeiro/dsverifier/bmc/core/delta-operator.h line 59 +void get_delta_transfer_function_with_base(double *b, double *b_out, signed int b_size, double *a, double *a_out, signed int a_size, double delta) +{ + signed int i; + signed int j; + signed int N=a_size - 1; + signed int M=b_size - 1; + double sum_delta_operator; + i = 0; + for( ; N >= i; i = i + 1) + { + sum_delta_operator = 0.000000; + j = 0; + for( ; i >= j; j = j + 1) + { + signed int return_value_nchoosek$1=nchoosek(N - j, i - j); + sum_delta_operator = sum_delta_operator + a[(signed long int)j] * (double)return_value_nchoosek$1; + } + double return_value_internal_pow$2=internal_pow(delta, (double)(N - i)); + a_out[(signed long int)i] = return_value_internal_pow$2 * sum_delta_operator; + } + i = 0; + for( ; M >= i; i = i + 1) + { + sum_delta_operator = 0.000000; + j = 0; + for( ; i >= j; j = j + 1) + { + signed int return_value_nchoosek$3=nchoosek(M - j, i - j); + sum_delta_operator = sum_delta_operator + b[(signed long int)j] * (double)return_value_nchoosek$3; + } + double return_value_internal_pow$4=internal_pow(delta, (double)(M - i)); + b_out[(signed long int)i] = return_value_internal_pow$4 * sum_delta_operator; + } +} + +// iirIIOutTime +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 428 +float iirIIOutTime(float *w, float x, float *a, float *b, signed int Na, signed int Nb) +{ + signed int timer1=0; + float *a_ptr; + float *b_ptr; + float *w_ptr; + float sum=0.000000f; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + w_ptr = &w[1l]; + signed int k; + signed int j; + timer1 = timer1 + 71; + j = 1; + for( ; !(j >= Na); j = j + 1) + { + float *tmp_post$1=a_ptr; + a_ptr = a_ptr + 1l; + float *tmp_post$2=w_ptr; + w_ptr = w_ptr + 1l; + w[0l] = w[0l] - *tmp_post$1 * *tmp_post$2; + timer1 = timer1 + 54; + } + w[0l] = w[0l] + x; + w_ptr = &w[0l]; + k = 0; + for( ; !(k >= Nb); k = k + 1) + { + float *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + float *tmp_post$4=w_ptr; + w_ptr = w_ptr + 1l; + sum = sum + *tmp_post$3 * *tmp_post$4; + timer1 = timer1 + 46; + } + timer1 = timer1 + 38; + /* assertion (double)timer1*CYCLE <= (double)DEADLINE */ + assert(((double)timer1 * 1.000000) / 1.600000e+7 <= 1.000000 / 100.000000); + if((double)timer1 / 1.600000e+7 <= 1.000000 / 100.000000) + (void)0; + + return sum; +} + +// iirIItOutTime +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 452 +float iirIItOutTime(float *w, float x, float *a, float *b, signed int Na, signed int Nb) +{ + signed int timer1=0; + float *a_ptr; + float *b_ptr; + float yout=0.000000f; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + signed int Nw=Na > Nb ? Na : Nb; + float *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + yout = *tmp_post$1 * x + w[0l]; + signed int j; + timer1 = timer1 + 105; + j = 0; + for( ; !(j >= -1 + Nw); j = j + 1) + { + w[(signed long int)j] = w[(signed long int)(j + 1)]; + if(!(j >= -1 + Na)) + { + float *tmp_post$2=a_ptr; + a_ptr = a_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] - *tmp_post$2 * yout; + timer1 = timer1 + 41; + } + + if(!(j >= -1 + Nb)) + { + float *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] + *tmp_post$3 * x; + timer1 = timer1 + 38; + } + + timer1 = timer1 + 54; + } + timer1 = timer1 + 7; + /* assertion (double)timer1*CYCLE <= (double)DEADLINE */ + assert(((double)timer1 * 1.000000) / 1.600000e+7 <= 1.000000 / 100.000000); + if((double)timer1 / 1.600000e+7 <= 1.000000 / 100.000000) + (void)0; + + return yout; +} + +// iirIItOutTime_double +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 479 +double iirIItOutTime_double(double *w, double x, double *a, double *b, signed int Na, signed int Nb) +{ + signed int timer1=0; + double *a_ptr; + double *b_ptr; + double yout=0.000000; + a_ptr = &a[1l]; + b_ptr = &b[0l]; + signed int Nw=Na > Nb ? Na : Nb; + double *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + yout = *tmp_post$1 * x + w[0l]; + signed int j; + timer1 = timer1 + 105; + j = 0; + for( ; !(j >= -1 + Nw); j = j + 1) + { + w[(signed long int)j] = w[(signed long int)(j + 1)]; + if(!(j >= -1 + Na)) + { + double *tmp_post$2=a_ptr; + a_ptr = a_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] - *tmp_post$2 * yout; + timer1 = timer1 + 41; + } + + if(!(j >= -1 + Nb)) + { + double *tmp_post$3=b_ptr; + b_ptr = b_ptr + 1l; + w[(signed long int)j] = w[(signed long int)j] + *tmp_post$3 * x; + timer1 = timer1 + 38; + } + + timer1 = timer1 + 54; + } + timer1 = timer1 + 7; + /* assertion (double)timer1*CYCLE <= (double)DEADLINE */ + assert(((double)timer1 * 1.000000) / 1.600000e+7 <= 1.000000 / 100.000000); + if((double)timer1 / 1.600000e+7 <= 1.000000 / 100.000000) + (void)0; + + return yout; +} + +// iirOutBoth +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 506 +void iirOutBoth(float *yf, float *xf, float *af, float *bf, float *sumf_ref, signed long int *y, signed long int *x, signed long int *a, signed long int *b, signed long int *sum_ref, signed int Na, signed int Nb) +{ + signed long int *a_ptr; + signed long int *y_ptr; + signed long int *b_ptr; + signed long int *x_ptr; + float *af_ptr; + float *yf_ptr; + float *bf_ptr; + float *xf_ptr; + signed long int sum=0l; + float sumf=0.000000f; + a_ptr = &a[1l]; + y_ptr = &y[(signed long int)(Na - 1)]; + b_ptr = &b[0l]; + x_ptr = &x[(signed long int)(Nb - 1)]; + af_ptr = &af[1l]; + yf_ptr = &yf[(signed long int)(Na - 1)]; + bf_ptr = &bf[0l]; + xf_ptr = &xf[(signed long int)(Nb - 1)]; + signed int i; + signed int j; + i = 0; + for( ; !(i >= Nb); i = i + 1) + { + signed long int *tmp_post$1=b_ptr; + b_ptr = b_ptr + 1l; + signed long int *tmp_post$2=x_ptr; + x_ptr = x_ptr - 1l; + signed long int return_value_fxp_mult$3=fxp_mult(*tmp_post$1, *tmp_post$2); + sum=fxp_add(sum, return_value_fxp_mult$3); + float *tmp_post$4=bf_ptr; + bf_ptr = bf_ptr + 1l; + float *tmp_post$5=xf_ptr; + xf_ptr = xf_ptr - 1l; + sumf = sumf + *tmp_post$4 * *tmp_post$5; + } + j = 1; + for( ; !(j >= Na); j = j + 1) + { + signed long int *tmp_post$6=a_ptr; + a_ptr = a_ptr + 1l; + signed long int *tmp_post$7=y_ptr; + y_ptr = y_ptr - 1l; + signed long int return_value_fxp_mult$8=fxp_mult(*tmp_post$6, *tmp_post$7); + sum=fxp_sub(sum, return_value_fxp_mult$8); + float *tmp_post$9=af_ptr; + af_ptr = af_ptr + 1l; + float *tmp_post$10=yf_ptr; + yf_ptr = yf_ptr - 1l; + sumf = sumf - *tmp_post$9 * *tmp_post$10; + } + *sum_ref = sum; + *sumf_ref = sumf; +} + +// iirOutBothL +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 586 +float iirOutBothL(float *yf, float *xf, float *af, float *bf, float xfin, signed long int *y, signed long int *x, signed long int *a, signed long int *b, signed long int xin, signed int Na, signed int Nb) +{ + signed long int *a_ptr; + signed long int *y_ptr; + signed long int *b_ptr; + signed long int *x_ptr; + signed long int sum=0l; + a_ptr = &a[(signed long int)(Na - 1)]; + y_ptr = &y[1l]; + b_ptr = &b[(signed long int)(Nb - 1)]; + x_ptr = &x[0l]; + float *af_ptr; + float *yf_ptr; + float *bf_ptr; + float *xf_ptr; + float sumf=0.000000f; + af_ptr = &af[(signed long int)(Na - 1)]; + yf_ptr = &yf[1l]; + bf_ptr = &bf[(signed long int)(Nb - 1)]; + xf_ptr = &xf[0l]; + signed int i; + signed int j; + i = 0; + for( ; !(i >= -1 + Nb); i = i + 1) + { + x[(signed long int)i] = x[(signed long int)(i + 1)]; + signed long int *tmp_post$1=b_ptr; + b_ptr = b_ptr - 1l; + signed long int *tmp_post$2=x_ptr; + x_ptr = x_ptr + 1l; + signed long int return_value_fxp_mult$3=fxp_mult(*tmp_post$1, *tmp_post$2); + sum=fxp_add(sum, return_value_fxp_mult$3); + xf[(signed long int)i] = xf[(signed long int)(i + 1)]; + float *tmp_post$4=bf_ptr; + bf_ptr = bf_ptr - 1l; + float *tmp_post$5=xf_ptr; + xf_ptr = xf_ptr + 1l; + sumf = sumf + *tmp_post$4 * *tmp_post$5; + } + x[(signed long int)(Nb - 1)] = xin; + signed long int *tmp_post$6=b_ptr; + b_ptr = b_ptr - 1l; + signed long int *tmp_post$7=x_ptr; + x_ptr = x_ptr + 1l; + signed long int return_value_fxp_mult$8=fxp_mult(*tmp_post$6, *tmp_post$7); + sum=fxp_add(sum, return_value_fxp_mult$8); + xf[(signed long int)(Nb - 1)] = xfin; + float *tmp_post$9=bf_ptr; + bf_ptr = bf_ptr - 1l; + float *tmp_post$10=xf_ptr; + xf_ptr = xf_ptr + 1l; + sumf = sumf + *tmp_post$9 * *tmp_post$10; + j = 1; + for( ; !(j >= -1 + Na); j = j + 1) + { + signed long int *tmp_post$11=a_ptr; + a_ptr = a_ptr - 1l; + signed long int *tmp_post$12=y_ptr; + y_ptr = y_ptr + 1l; + signed long int return_value_fxp_mult$13=fxp_mult(*tmp_post$11, *tmp_post$12); + sum=fxp_sub(sum, return_value_fxp_mult$13); + y[(signed long int)j] = y[(signed long int)(j + 1)]; + float *tmp_post$14=af_ptr; + af_ptr = af_ptr - 1l; + float *tmp_post$15=yf_ptr; + yf_ptr = yf_ptr + 1l; + sumf = sumf - *tmp_post$14 * *tmp_post$15; + yf[(signed long int)j] = yf[(signed long int)(j + 1)]; + } + signed long int *tmp_post$16; + signed long int *tmp_post$17; + signed long int return_value_fxp_mult$18; + if(Na >= 2) + { + tmp_post$16 = a_ptr; + a_ptr = a_ptr - 1l; + tmp_post$17 = y_ptr; + y_ptr = y_ptr + 1l; + return_value_fxp_mult$18=fxp_mult(*tmp_post$16, *tmp_post$17); + sum=fxp_sub(sum, return_value_fxp_mult$18); + } + + y[(signed long int)(Na - 1)] = sum; + float *tmp_post$19; + float *tmp_post$20; + if(Na >= 2) + { + tmp_post$19 = af_ptr; + af_ptr = af_ptr - 1l; + tmp_post$20 = yf_ptr; + yf_ptr = yf_ptr + 1l; + sumf = sumf - *tmp_post$19 * *tmp_post$20; + } + + yf[(signed long int)(Na - 1)] = sumf; + float return_value_fxp_to_float$21=fxp_to_float(sum); + return return_value_fxp_to_float$21 - sumf; +} + +// iirOutBothL2 +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 626 +float iirOutBothL2(float *yf, float *xf, float *af, float *bf, float xfin, signed long int *y, signed long int *x, signed long int *a, signed long int *b, signed long int xin, signed int Na, signed int Nb) +{ + signed long int *a_ptr; + signed long int *y_ptr; + signed long int *b_ptr; + signed long int *x_ptr; + signed long int sum=0l; + a_ptr = &a[(signed long int)(Na - 1)]; + y_ptr = &y[1l]; + b_ptr = &b[(signed long int)(Nb - 1)]; + x_ptr = &x[0l]; + float *af_ptr; + float *yf_ptr; + float *bf_ptr; + float *xf_ptr; + float sumf=0.000000f; + af_ptr = &af[(signed long int)(Na - 1)]; + yf_ptr = &yf[1l]; + bf_ptr = &bf[(signed long int)(Nb - 1)]; + xf_ptr = &xf[0l]; + signed int i=0; + signed int j=1; + i = 0; + for( ; !(i >= -1 + Nb); i = i + 1) + { + x[(signed long int)i] = x[(signed long int)(i + 1)]; + signed long int return_value_fxp_mult$1=fxp_mult(b[(signed long int)((Nb - 1) - i)], x[(signed long int)i]); + sum=fxp_add(sum, return_value_fxp_mult$1); + xf[(signed long int)i] = xf[(signed long int)(i + 1)]; + sumf = sumf + bf[(signed long int)((Nb - 1) - i)] * xf[(signed long int)i]; + } + x[(signed long int)(Nb - 1)] = xin; + signed long int return_value_fxp_mult$2=fxp_mult(b[(signed long int)((Nb - 1) - i)], x[(signed long int)i]); + sum=fxp_add(sum, return_value_fxp_mult$2); + xf[(signed long int)(Nb - 1)] = xfin; + sumf = sumf + bf[(signed long int)((Nb - 1) - i)] * xf[(signed long int)i]; + j = 1; + for( ; !(j >= -1 + Na); j = j + 1) + { + signed long int return_value_fxp_mult$3=fxp_mult(a[(signed long int)(Na - j)], y[(signed long int)j]); + sum=fxp_sub(sum, return_value_fxp_mult$3); + y[(signed long int)j] = y[(signed long int)(j + 1)]; + sumf = sumf - af[(signed long int)(Na - j)] * yf[(signed long int)j]; + yf[(signed long int)j] = yf[(signed long int)(j + 1)]; + } + signed long int return_value_fxp_mult$4; + if(Na >= 2) + { + return_value_fxp_mult$4=fxp_mult(a[(signed long int)(Na - j)], y[(signed long int)j]); + sum=fxp_sub(sum, return_value_fxp_mult$4); + } + + y[(signed long int)(Na - 1)] = sum; + if(Na >= 2) + sumf = sumf - af[(signed long int)(Na - j)] * yf[(signed long int)j]; + + yf[(signed long int)(Na - 1)] = sumf; + float return_value_fxp_to_float$5=fxp_to_float(sum); + return return_value_fxp_to_float$5 - sumf; +} + +// iirOutFixedL +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 536 +signed long int iirOutFixedL(signed long int *y, signed long int *x, signed long int xin, signed long int *a, signed long int *b, signed int Na, signed int Nb) +{ + signed long int *a_ptr; + signed long int *y_ptr; + signed long int *b_ptr; + signed long int *x_ptr; + signed long int sum=0l; + a_ptr = &a[(signed long int)(Na - 1)]; + y_ptr = &y[1l]; + b_ptr = &b[(signed long int)(Nb - 1)]; + x_ptr = &x[0l]; + signed int i; + signed int j; + i = 0; + for( ; !(i >= -1 + Nb); i = i + 1) + { + x[(signed long int)i] = x[(signed long int)(i + 1)]; + signed long int *tmp_post$1=b_ptr; + b_ptr = b_ptr - 1l; + signed long int *tmp_post$2=x_ptr; + x_ptr = x_ptr + 1l; + signed long int return_value_fxp_mult$3=fxp_mult(*tmp_post$1, *tmp_post$2); + sum=fxp_add(sum, return_value_fxp_mult$3); + } + x[(signed long int)(Nb - 1)] = xin; + signed long int *tmp_post$4=b_ptr; + b_ptr = b_ptr - 1l; + signed long int *tmp_post$5=x_ptr; + x_ptr = x_ptr + 1l; + signed long int return_value_fxp_mult$6=fxp_mult(*tmp_post$4, *tmp_post$5); + sum=fxp_add(sum, return_value_fxp_mult$6); + j = 1; + for( ; !(j >= -1 + Na); j = j + 1) + { + signed long int *tmp_post$7=a_ptr; + a_ptr = a_ptr - 1l; + signed long int *tmp_post$8=y_ptr; + y_ptr = y_ptr + 1l; + signed long int return_value_fxp_mult$9=fxp_mult(*tmp_post$7, *tmp_post$8); + sum=fxp_sub(sum, return_value_fxp_mult$9); + y[(signed long int)j] = y[(signed long int)(j + 1)]; + } + signed long int *tmp_post$10; + signed long int *tmp_post$11; + signed long int return_value_fxp_mult$12; + if(Na >= 2) + { + tmp_post$10 = a_ptr; + a_ptr = a_ptr - 1l; + tmp_post$11 = y_ptr; + y_ptr = y_ptr + 1l; + return_value_fxp_mult$12=fxp_mult(*tmp_post$10, *tmp_post$11); + sum=fxp_sub(sum, return_value_fxp_mult$12); + } + + y[(signed long int)(Na - 1)] = sum; + return sum; +} + +// iirOutFloatL +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 561 +float iirOutFloatL(float *y, float *x, float xin, float *a, float *b, signed int Na, signed int Nb) +{ + float *a_ptr; + float *y_ptr; + float *b_ptr; + float *x_ptr; + float sum=0.000000f; + a_ptr = &a[(signed long int)(Na - 1)]; + y_ptr = &y[1l]; + b_ptr = &b[(signed long int)(Nb - 1)]; + x_ptr = &x[0l]; + signed int i; + signed int j; + i = 0; + for( ; !(i >= -1 + Nb); i = i + 1) + { + x[(signed long int)i] = x[(signed long int)(i + 1)]; + float *tmp_post$1=b_ptr; + b_ptr = b_ptr - 1l; + float *tmp_post$2=x_ptr; + x_ptr = x_ptr + 1l; + sum = sum + *tmp_post$1 * *tmp_post$2; + } + x[(signed long int)(Nb - 1)] = xin; + float *tmp_post$3=b_ptr; + b_ptr = b_ptr - 1l; + float *tmp_post$4=x_ptr; + x_ptr = x_ptr + 1l; + sum = sum + *tmp_post$3 * *tmp_post$4; + j = 1; + for( ; !(j >= -1 + Na); j = j + 1) + { + float *tmp_post$5=a_ptr; + a_ptr = a_ptr - 1l; + float *tmp_post$6=y_ptr; + y_ptr = y_ptr + 1l; + sum = sum - *tmp_post$5 * *tmp_post$6; + y[(signed long int)j] = y[(signed long int)(j + 1)]; + } + float *tmp_post$7; + float *tmp_post$8; + if(Na >= 2) + { + tmp_post$7 = a_ptr; + a_ptr = a_ptr - 1l; + tmp_post$8 = y_ptr; + y_ptr = y_ptr + 1l; + sum = sum - *tmp_post$7 * *tmp_post$8; + } + + y[(signed long int)(Na - 1)] = sum; + return sum; +} + +// initialization +// file /home/lucascordeiro/dsverifier/bmc/core/initialization.h line 24 +void initialization() +{ + if(impl.frac_bits >= 32) + printf("impl.frac_bits must be less than word width!\n"); + + if(impl.int_bits >= 32 + -impl.frac_bits) + { + printf("impl.int_bits must be less than word width subtracted by precision!\n"); + /* assertion 0 */ + assert(0 != 0); + } + + if(impl.frac_bits >= 31) + _fxp_one = 2147483647l; + + else + _fxp_one = (signed long int)(0x1 << impl.frac_bits); + _fxp_half = (signed long int)(0x1 << impl.frac_bits - 1); + _fxp_minus_one = (signed long int)-(0x1 << impl.frac_bits); + _fxp_min = (signed long int)-(0x1 << (impl.frac_bits + impl.int_bits) - 1); + _fxp_max = (signed long int)((0x1 << (impl.frac_bits + impl.int_bits) - 1) - 1); + _fxp_fmask = (signed long int)((1 << impl.frac_bits) - 1); + _fxp_imask = (signed long int)(0x80000000u >> (32 - impl.frac_bits) - 1); + _dbl_min = (double)_fxp_min; + _dbl_min = _dbl_min / (double)(1 << impl.frac_bits); + _dbl_max = (double)_fxp_max; + _dbl_max = _dbl_max / (double)(1 << impl.frac_bits); + if(impl.scale == 0 || impl.scale == 1) + impl.scale = 1; + + else + { + if(IEEE_FLOAT_NOTEQUAL(impl.min, 0.000000)) + impl.min = impl.min / (double)impl.scale; + + if(IEEE_FLOAT_NOTEQUAL(impl.max, 0.000000)) + impl.max = impl.max / (double)impl.scale; + + } +} + +// initialize_array +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 22 +void initialize_array(double *v, signed int n) +{ + signed int i=0; + for( ; !(i >= n); i = i + 1) + v[(signed long int)i] = 0.000000; +} + +// internal_abs +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 49 +double internal_abs(double a) +{ + return a < 0.000000 ? -a : a; +} + +// internal_pow +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 39 +double internal_pow(double a, double b) +{ + signed int i; + double acc=1.000000; + i = 0; + for( ; (double)i < b; i = i + 1) + acc = acc * a; + return acc; +} + +// main +// file /home/lucascordeiro/dsverifier/bmc/dsverifier.h line 60 +signed int main() +{ + initialization(); + validation(); + rounding_mode = 1; + call_closedloop_verification_task((void *)verify_stability_closedloop_using_dslib); + return 0; +} + +// nchoosek +// file /home/lucascordeiro/dsverifier/bmc/core/delta-operator.h line 23 +signed int nchoosek(signed int n, signed int k) +{ + if(k == 0) + return 1; + + else + { + signed int return_value_nchoosek$1=nchoosek(n - 1, k - 1); + return (n * return_value_nchoosek$1) / k; + } +} + +// order +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 158 +signed int order(signed int Na, signed int Nb) +{ + return Na > Nb ? Na - 1 : Nb - 1; +} + +// poly_mult +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 165 +void poly_mult(double *a, signed int Na, double *b, signed int Nb, double *ans, signed int Nans) +{ + signed int i; + signed int j; + signed int k; + Nans = (Na + Nb) - 1; + i = 0; + for( ; !(i >= Na); i = i + 1) + { + j = 0; + for( ; !(j >= Nb); j = j + 1) + { + k = (((Na + Nb) - i) - j) - 2; + ans[(signed long int)k] = 0.000000; + } + } + i = 0; + for( ; !(i >= Na); i = i + 1) + { + j = 0; + for( ; !(j >= Nb); j = j + 1) + { + k = (((Na + Nb) - i) - j) - 2; + ans[(signed long int)k] = ans[(signed long int)k] + a[(signed long int)((Na - i) - 1)] * b[(signed long int)((Nb - j) - 1)]; + } + } +} + +// poly_sum +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 141 +void poly_sum(double *a, signed int Na, double *b, signed int Nb, double *ans, signed int Nans) +{ + signed int i; + Nans = Na > Nb ? Na : Nb; + i = 0; + for( ; !(i >= Nans); i = i + 1) + if(!(Nb >= Na)) + { + ans[(signed long int)i] = a[(signed long int)i]; + if(!(-1 + Na + -Nb >= i)) + ans[(signed long int)i] = ans[(signed long int)i] + b[(signed long int)((i - Na) + Nb)]; + + } + + else + { + ans[(signed long int)i] = b[(signed long int)i]; + if(!(-1 + Nb + -Na >= i)) + ans[(signed long int)i] = ans[(signed long int)i] + a[(signed long int)((i - Nb) + Na)]; + + } +} + +// print_array_elements +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 305 +void print_array_elements(char *name, double *v, signed int n) +{ + printf("%s = {", name); + signed int i=0; + for( ; !(i >= n); i = i + 1) + printf(" %.32f ", v[(signed long int)i]); + printf("}\n"); +} + +// print_fxp_array_elements +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 419 +void print_fxp_array_elements(char *name, signed long int *v, signed int n) +{ + printf("%s = {", name); + signed int i=0; + for( ; !(i >= n); i = i + 1) + printf(" %jd ", v[(signed long int)i]); + printf("}\n"); +} + +// print_matrix +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 481 +void print_matrix(double (*matrix)[20l], unsigned int lines, unsigned int columns) +{ + printf("\nMatrix\n=====================\n\n"); + unsigned int i; + unsigned int j; + i = 0u; + for( ; !(i >= lines); i = i + 1u) + { + j = 0u; + for( ; !(j >= columns); j = j + 1u) + printf("#matrix[%d][%d]: %2.2f ", i, j, matrix[(signed long int)i][(signed long int)j]); + printf("\n"); + } + printf("\n"); +} + +// rand +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 417 +extern signed int rand(void) +{ + next = next * 1103515245ul + 12345ul; + return (signed int)((unsigned int)(next / 65536ul) % 32768u); +} + +// revert_array +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 30 +void revert_array(double *v, double *out, signed int n) +{ + initialize_array(out, n); + signed int i=0; + for( ; !(i >= n); i = i + 1) + out[(signed long int)i] = v[(signed long int)((n - i) - 1)]; +} + +// shiftL +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 53 +signed long int shiftL(signed long int zIn, signed long int *z, signed int N) +{ + signed int i; + signed long int zOut=z[0l]; + i = 0; + for( ; !(i >= -1 + N); i = i + 1) + z[(signed long int)i] = z[(signed long int)(i + 1)]; + z[(signed long int)(N - 1)] = zIn; + return zOut; +} + +// shiftLDouble +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 119 +double shiftLDouble(double zIn, double *z, signed int N) +{ + signed int i; + double zOut=z[0l]; + i = 0; + for( ; !(i >= -1 + N); i = i + 1) + z[(signed long int)i] = z[(signed long int)(i + 1)]; + z[(signed long int)(N - 1)] = zIn; + return zOut; +} + +// shiftLboth +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 130 +void shiftLboth(float zfIn, float *zf, signed long int zIn, signed long int *z, signed int N) +{ + signed int i; + signed long int zOut; + float zfOut; + zOut = z[0l]; + zfOut = zf[0l]; + i = 0; + for( ; !(i >= -1 + N); i = i + 1) + { + z[(signed long int)i] = z[(signed long int)(i + 1)]; + zf[(signed long int)i] = zf[(signed long int)(i + 1)]; + } + z[(signed long int)(N - 1)] = zIn; + zf[(signed long int)(N - 1)] = zfIn; +} + +// shiftLfloat +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 75 +float shiftLfloat(float zIn, float *z, signed int N) +{ + signed int i; + float zOut=z[0l]; + i = 0; + for( ; !(i >= -1 + N); i = i + 1) + z[(signed long int)i] = z[(signed long int)(i + 1)]; + z[(signed long int)(N - 1)] = zIn; + return zOut; +} + +// shiftR +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 64 +signed long int shiftR(signed long int zIn, signed long int *z, signed int N) +{ + signed int i; + signed long int zOut=z[(signed long int)(N - 1)]; + i = N - 1; + for( ; i >= 1; i = i - 1) + z[(signed long int)i] = z[(signed long int)(i - 1)]; + z[0l] = zIn; + return zOut; +} + +// shiftRDdouble +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 97 +double shiftRDdouble(double zIn, double *z, signed int N) +{ + signed int i; + double zOut=z[0l]; + i = 0; + for( ; !(i >= -1 + N); i = i + 1) + z[(signed long int)i] = z[(signed long int)(i + 1)]; + z[(signed long int)(N - 1)] = zIn; + return zOut; +} + +// shiftRboth +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 144 +void shiftRboth(float zfIn, float *zf, signed long int zIn, signed long int *z, signed int N) +{ + signed int i; + signed long int zOut; + float zfOut; + zOut = z[(signed long int)(N - 1)]; + zfOut = zf[(signed long int)(N - 1)]; + i = N - 1; + for( ; i >= 1; i = i - 1) + { + z[(signed long int)i] = z[(signed long int)(i - 1)]; + zf[(signed long int)i] = zf[(signed long int)(i - 1)]; + } + z[0l] = zIn; + zf[0l] = zfIn; +} + +// shiftRdouble +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 108 +double shiftRdouble(double zIn, double *z, signed int N) +{ + signed int i; + double zOut=z[(signed long int)(N - 1)]; + i = N - 1; + for( ; i >= 1; i = i - 1) + z[(signed long int)i] = z[(signed long int)(i - 1)]; + z[0l] = zIn; + return zOut; +} + +// shiftRfloat +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 86 +float shiftRfloat(float zIn, float *z, signed int N) +{ + signed int i; + float zOut=z[(signed long int)(N - 1)]; + i = N - 1; + for( ; i >= 1; i = i - 1) + z[(signed long int)i] = z[(signed long int)(i - 1)]; + z[0l] = zIn; + return zOut; +} + +// snrPoint +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 402 +float snrPoint(float *s, float *n, signed int blksz) +{ + signed int i; + double ratio=0.000000; + double power=0.000000; + i = 0; + for( ; !(i >= blksz); i = i + 1) + if(!IEEE_FLOAT_EQUAL(n[(signed long int)i], 0.000000f)) + { + ratio = (double)(s[(signed long int)i] / n[(signed long int)i]); + if(!(ratio < -150.000000) && !(ratio > 150.000000)) + { + power = ratio * ratio; + /* assertion power >= 1.0f */ + assert(power >= 1.000000); + if(power >= 1.000000) + (void)0; + + } + + } + + return 9.999900e+3f; +} + +// snrPower +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 381 +float snrPower(float *s, float *n, signed int blksz) +{ + signed int i; + double sv=0.000000; + double nv=0.000000; + double snr; + i = 0; + for( ; !(i >= blksz); i = i + 1) + { + sv = sv + (double)(s[(signed long int)i] * s[(signed long int)i]); + nv = nv + (double)(n[(signed long int)i] * n[(signed long int)i]); + } + if(IEEE_FLOAT_NOTEQUAL(nv, 0.000000)) + { + /* assertion sv >= nv */ + assert(sv >= nv); + if(sv >= nv) + (void)0; + + snr = sv / nv; + return (float)snr; + } + + else + return 9.999900e+3f; +} + +// snrVariance +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 357 +float snrVariance(float *s, float *n, signed int blksz) +{ + signed int i; + double sm=0.000000; + double nm=0.000000; + double sv=0.000000; + double nv=0.000000; + double snr; + i = 0; + for( ; !(i >= blksz); i = i + 1) + { + sm = sm + (double)s[(signed long int)i]; + nm = nm + (double)n[(signed long int)i]; + } + sm = sm / (double)blksz; + nm = nm / (double)blksz; + i = 0; + for( ; !(i >= blksz); i = i + 1) + { + sv = sv + ((double)s[(signed long int)i] - sm) * ((double)s[(signed long int)i] - sm); + nv = nv + ((double)n[(signed long int)i] - nm) * ((double)n[(signed long int)i] - nm); + } + if(IEEE_FLOAT_NOTEQUAL(nv, 0.000000)) + { + /* assertion sv >= nv */ + assert(sv >= nv); + if(sv >= nv) + (void)0; + + snr = sv / nv; + return (float)snr; + } + + else + return 9.999900e+3f; +} + +// srand +// file /home/lucascordeiro/dsverifier/bmc/core/functions.h line 423 +extern void srand(unsigned int seed) +{ + next = (unsigned long int)seed; +} + +// transpose +// file /home/lucascordeiro/dsverifier/bmc/core/util.h line 571 +void transpose(double (*a)[20l], double (*b)[20l], signed int n, signed int m) +{ + signed int i; + signed int j; + i = 0; + for( ; !(i >= n); i = i + 1) + { + j = 0; + for( ; !(j >= m); j = j + 1) + b[(signed long int)j][(signed long int)i] = a[(signed long int)i][(signed long int)j]; + } +} + +// validation +// file /home/lucascordeiro/dsverifier/bmc/dsverifier.h line 125 +void validation() +{ + if(controller.a_size == 0 || plant.b_size == 0 || impl.int_bits == 0) + { + printf("\n\n*****************************************************************************************************\n"); + printf("* set (controller, plant, and impl) parameters to check CLOSED LOOP with DSVerifier *\n"); + printf("*****************************************************************************************************\n"); + __DSVERIFIER_assert((_Bool)0); + } + + else + { + printf("\n\n*****************************************************************************************************\n"); + printf("* set (controller and impl) parameters so that they do not overflow *\n"); + printf("*****************************************************************************************************\n"); + unsigned int j=0u; + for( ; !(j >= (unsigned int)controller.a_size); j = j + 1u) + { + const double validation$$1$$6$$2$$1$$1$$value=controller.a[(signed long int)j]; + __DSVERIFIER_assert(validation$$1$$6$$2$$1$$1$$value <= _dbl_max); + __DSVERIFIER_assert(validation$$1$$6$$2$$1$$1$$value >= _dbl_min); + } + j = 0u; + for( ; !(j >= (unsigned int)controller.b_size); j = j + 1u) + { + const double value=controller.b[(signed long int)j]; + __DSVERIFIER_assert(value <= _dbl_max); + __DSVERIFIER_assert(value >= _dbl_min); + } + } +} + +// verify_controllability +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_controllability.h line 16 +signed int verify_controllability(void) +{ + signed int i; + signed int j; + signed long int A_fpx[20l][20l]; + signed long int B_fpx[20l][20l]; + signed long int controllabilityMatrix[20l][20l]; + signed long int backup[20l][20l]; + signed long int backupSecond[20l][20l]; + double controllabilityMatrix_double[20l][20l]; + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs * nStates); j = j + 1) + { + A_fpx[(signed long int)i][(signed long int)j] = 0l; + B_fpx[(signed long int)i][(signed long int)j] = 0l; + controllabilityMatrix[(signed long int)i][(signed long int)j] = 0l; + backup[(signed long int)i][(signed long int)j] = 0l; + backupSecond[(signed long int)i][(signed long int)j] = 0l; + controllabilityMatrix_double[(signed long int)i][(signed long int)j] = 0.000000; + } + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + A_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.A[(signed long int)i][(signed long int)j]); + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs); j = j + 1) + B_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.B[(signed long int)i][(signed long int)j]); + } + if(nInputs >= 2) + { + signed int l=0; + j = 0; + while(!(j >= nInputs * nStates)) + { + fxp_exp_matrix((unsigned int)nStates, (unsigned int)nStates, A_fpx, (unsigned int)l, backup); + l = l + 1; + fxp_matrix_multiplication((unsigned int)nStates, (unsigned int)nStates, (unsigned int)nStates, (unsigned int)nInputs, backup, B_fpx, backupSecond); + signed int k=0; + for( ; !(k >= nInputs); k = k + 1) + { + i = 0; + for( ; !(i >= nStates); i = i + 1) + controllabilityMatrix[(signed long int)i][(signed long int)j] = backupSecond[(signed long int)i][(signed long int)k]; + j = j + 1; + } + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs * nStates); j = j + 1) + backup[(signed long int)i][(signed long int)j] = 0l; + } + fxp_transpose(controllabilityMatrix, backup, nStates, nStates * nInputs); + signed long int mimo_controllabilityMatrix_fxp[20l][20l]; + fxp_matrix_multiplication((unsigned int)nStates, (unsigned int)(nStates * nInputs), (unsigned int)(nStates * nInputs), (unsigned int)nStates, controllabilityMatrix, backup, mimo_controllabilityMatrix_fxp); + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + controllabilityMatrix_double[(signed long int)i][(signed long int)j]=fxp_to_double(mimo_controllabilityMatrix_fxp[(signed long int)i][(signed long int)j]); + } + double return_value_determinant$1=determinant(controllabilityMatrix_double, nStates); + /* assertion determinant(controllabilityMatrix_double,nStates) != 0 */ + assert(IEEE_FLOAT_NOTEQUAL(return_value_determinant$1, 0.000000)); + if(IEEE_FLOAT_NOTEQUAL(return_value_determinant$1, 0.000000)) + (void)0; + + } + + else + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + { + fxp_exp_matrix((unsigned int)nStates, (unsigned int)nStates, A_fpx, (unsigned int)j, backup); + fxp_matrix_multiplication((unsigned int)nStates, (unsigned int)nStates, (unsigned int)nStates, (unsigned int)nInputs, backup, B_fpx, backupSecond); + i = 0; + for( ; !(i >= nStates); i = i + 1) + controllabilityMatrix[(signed long int)i][(signed long int)j] = backupSecond[(signed long int)i][0l]; + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + controllabilityMatrix_double[(signed long int)i][(signed long int)j]=fxp_to_double(controllabilityMatrix[(signed long int)i][(signed long int)j]); + } + double return_value_determinant$2=determinant(controllabilityMatrix_double, nStates); + /* assertion determinant(controllabilityMatrix_double,nStates) != 0 */ + assert(IEEE_FLOAT_NOTEQUAL(return_value_determinant$2, 0.000000)); + if(IEEE_FLOAT_NOTEQUAL(return_value_determinant$2, 0.000000)) + (void)0; + + } + return 0; +} + +// verify_controllability_double +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_controllability.h line 120 +signed int verify_controllability_double(void) +{ + signed int i; + signed int j; + double controllabilityMatrix[20l][20l]; + double backup[20l][20l]; + double backupSecond[20l][20l]; + double controllabilityMatrix_double[20l][20l]; + if(nInputs >= 2) + { + signed int l=0; + j = 0; + while(!(j >= nInputs * nStates)) + { + double_exp_matrix((unsigned int)nStates, (unsigned int)nStates, _controller.A, (unsigned int)l, backup); + l = l + 1; + double_matrix_multiplication((unsigned int)nStates, (unsigned int)nStates, (unsigned int)nStates, (unsigned int)nInputs, backup, _controller.B, backupSecond); + signed int k=0; + for( ; !(k >= nInputs); k = k + 1) + { + i = 0; + for( ; !(i >= nStates); i = i + 1) + controllabilityMatrix[(signed long int)i][(signed long int)j] = backupSecond[(signed long int)i][(signed long int)k]; + j = j + 1; + } + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs * nStates); j = j + 1) + backup[(signed long int)i][(signed long int)j] = 0.000000; + } + transpose(controllabilityMatrix, backup, nStates, nStates * nInputs); + double mimo_controllabilityMatrix_double[20l][20l]; + double_matrix_multiplication((unsigned int)nStates, (unsigned int)(nStates * nInputs), (unsigned int)(nStates * nInputs), (unsigned int)nStates, controllabilityMatrix, backup, mimo_controllabilityMatrix_double); + double return_value_determinant$1=determinant(mimo_controllabilityMatrix_double, nStates); + /* assertion determinant(mimo_controllabilityMatrix_double,nStates) != 0 */ + assert(IEEE_FLOAT_NOTEQUAL(return_value_determinant$1, 0.000000)); + if(IEEE_FLOAT_NOTEQUAL(return_value_determinant$1, 0.000000)) + (void)0; + + } + + else + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + { + double_exp_matrix((unsigned int)nStates, (unsigned int)nStates, _controller.A, (unsigned int)j, backup); + double_matrix_multiplication((unsigned int)nStates, (unsigned int)nStates, (unsigned int)nStates, (unsigned int)nInputs, backup, _controller.B, backupSecond); + i = 0; + for( ; !(i >= nStates); i = i + 1) + controllabilityMatrix[(signed long int)i][(signed long int)j] = backupSecond[(signed long int)i][0l]; + } + double return_value_determinant$2=determinant(controllabilityMatrix, nStates); + /* assertion determinant(controllabilityMatrix,nStates) != 0 */ + assert(IEEE_FLOAT_NOTEQUAL(return_value_determinant$2, 0.000000)); + if(IEEE_FLOAT_NOTEQUAL(return_value_determinant$2, 0.000000)) + (void)0; + + } + return 0; +} + +// verify_error +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_error.h line 20 +signed int verify_error(void) +{ + overflow_mode = 2; + double a_cascade[100l]; + signed int a_cascade_size; + double b_cascade[100l]; + signed int b_cascade_size; + signed long int min_fxp=fxp_double_to_fxp(impl.min); + signed long int max_fxp=fxp_double_to_fxp(impl.max); + const signed long int max_fxp$array_size0=(signed long int)X_SIZE_VALUE; + signed long int y[max_fxp$array_size0]; + const signed long int y$array_size0=(signed long int)X_SIZE_VALUE; + signed long int x[y$array_size0]; + const signed long int x$array_size0=(signed long int)X_SIZE_VALUE; + double yf[x$array_size0]; + const signed long int yf$array_size0=(signed long int)X_SIZE_VALUE; + double xf[yf$array_size0]; + signed int Nw=0; + Nw = ds.a_size > ds.b_size ? ds.a_size : ds.b_size; + const signed long int Nw$array_size0=(signed long int)ds.a_size; + signed long int yaux[Nw$array_size0]; + const signed long int yaux$array_size0=(signed long int)ds.b_size; + signed long int xaux[yaux$array_size0]; + const signed long int xaux$array_size0=(signed long int)Nw; + signed long int waux[xaux$array_size0]; + const signed long int waux$array_size0=(signed long int)ds.a_size; + double yfaux[waux$array_size0]; + const signed long int yfaux$array_size0=(signed long int)ds.b_size; + double xfaux[yfaux$array_size0]; + const signed long int xfaux$array_size0=(signed long int)Nw; + double wfaux[xfaux$array_size0]; + signed int i=0; + for( ; !(i >= ds.a_size); i = i + 1) + { + yaux[(signed long int)i] = 0l; + yfaux[(signed long int)i] = 0.000000; + } + i = 0; + for( ; !(i >= ds.b_size); i = i + 1) + { + xaux[(signed long int)i] = 0l; + xfaux[(signed long int)i] = 0.000000; + } + i = 0; + for( ; !(i >= Nw); i = i + 1) + { + waux[(signed long int)i] = 0l; + wfaux[(signed long int)i] = 0.000000; + } + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + y[(signed long int)i] = 0l; + signed int return_value_nondet_int$1=nondet_int(); + x[(signed long int)i] = (signed long int)return_value_nondet_int$1; + _Bool tmp_if_expr$2; + if(x[(signed long int)i] >= min_fxp) + tmp_if_expr$2 = x[(signed long int)i] <= max_fxp ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$2 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$2); + yf[(signed long int)i] = 0.000000; + xf[(signed long int)i]=fxp_to_double(x[(signed long int)i]); + } + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + double absolute_error; + double return_value_fxp_to_double$3=fxp_to_double(y[(signed long int)i]); + absolute_error = yf[(signed long int)i] - return_value_fxp_to_double$3; + __DSVERIFIER_assert(absolute_error < impl.max_error && absolute_error > -impl.max_error); + } + return 0; +} + +// verify_error_closedloop +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_error_closedloop.h line 27 +signed int verify_error_closedloop(void) +{ + overflow_mode = 3; + double *c_num=controller.b; + signed int c_num_size=controller.b_size; + double *c_den=controller.a; + signed int c_den_size=controller.a_size; + const signed long int c_den_size$array_size0=(signed long int)controller.b_size; + signed long int c_num_fxp[c_den_size$array_size0]; + fxp_double_to_fxp_array(c_num, c_num_fxp, controller.b_size); + const signed long int c_num_fxp$array_size0=(signed long int)controller.a_size; + signed long int c_den_fxp[c_num_fxp$array_size0]; + fxp_double_to_fxp_array(c_den, c_den_fxp, controller.a_size); + const signed long int c_den_fxp$array_size0=(signed long int)controller.b_size; + double c_num_qtz[c_den_fxp$array_size0]; + fxp_to_double_array(c_num_qtz, c_num_fxp, controller.b_size); + const signed long int c_num_qtz$array_size0=(signed long int)controller.a_size; + double c_den_qtz[c_num_qtz$array_size0]; + fxp_to_double_array(c_den_qtz, c_den_fxp, controller.a_size); + double *p_num=plant_cbmc.b; + signed int p_num_size=plant.b_size; + double *p_den=plant_cbmc.a; + signed int p_den_size=plant.a_size; + double ans_num_double[100l]; + double ans_num_qtz[100l]; + signed int ans_num_size=(controller.b_size + plant.b_size) - 1; + double ans_den_qtz[100l]; + double ans_den_double[100l]; + signed int ans_den_size=(controller.a_size + plant.a_size) - 1; + ft_closedloop_series(c_num_qtz, c_num_size, c_den_qtz, c_den_size, p_num, p_num_size, p_den, p_den_size, ans_num_qtz, ans_num_size, ans_den_qtz, ans_den_size); + ft_closedloop_series(c_num, c_num_size, c_den, c_den_size, p_num, p_num_size, p_den, p_den_size, ans_num_double, ans_num_size, ans_den_double, ans_den_size); + signed int i; + const signed long int i$array_size0=(signed long int)X_SIZE_VALUE; + double y_qtz[i$array_size0]; + const signed long int y_qtz$array_size0=(signed long int)X_SIZE_VALUE; + double y_double[y_qtz$array_size0]; + const signed long int y_double$array_size0=(signed long int)X_SIZE_VALUE; + double x_qtz[y_double$array_size0]; + const signed long int x_qtz$array_size0=(signed long int)X_SIZE_VALUE; + double x_double[x_qtz$array_size0]; + const signed long int x_double$array_size0=(signed long int)ans_num_size; + double xaux_qtz[x_double$array_size0]; + const signed long int xaux_qtz$array_size0=(signed long int)ans_num_size; + double xaux_double[xaux_qtz$array_size0]; + const signed long int xaux_double$array_size0=(signed long int)ans_num_size; + double xaux[xaux_double$array_size0]; + double nondet_constant_input=nondet_double(); + __DSVERIFIER_assume(nondet_constant_input >= impl.min && nondet_constant_input <= impl.max); + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + x_qtz[(signed long int)i] = nondet_constant_input; + x_double[(signed long int)i] = nondet_constant_input; + y_qtz[(signed long int)i] = 0.000000; + y_double[(signed long int)i] = 0.000000; + } + i = 0; + for( ; !(i >= ans_num_size); i = i + 1) + { + xaux_qtz[(signed long int)i] = nondet_constant_input; + xaux_double[(signed long int)i] = nondet_constant_input; + } + const signed long int nondet_constant_input$array_size0=(signed long int)ans_den_size; + double yaux_qtz[nondet_constant_input$array_size0]; + const signed long int yaux_qtz$array_size0=(signed long int)ans_den_size; + double yaux_double[yaux_qtz$array_size0]; + const signed long int yaux_double$array_size0=(signed long int)ans_den_size; + double y0_qtz[yaux_double$array_size0]; + const signed long int y0_qtz$array_size0=(signed long int)ans_den_size; + double y0_double[y0_qtz$array_size0]; + signed int Nw=ans_den_size > ans_num_size ? ans_den_size : ans_num_size; + const signed long int Nw$array_size0=(signed long int)Nw; + double waux_qtz[Nw$array_size0]; + const signed long int waux_qtz$array_size0=(signed long int)Nw; + double waux_double[waux_qtz$array_size0]; + const signed long int waux_double$array_size0=(signed long int)Nw; + double w0_qtz[waux_double$array_size0]; + const signed long int w0_qtz$array_size0=(signed long int)Nw; + double w0_double[w0_qtz$array_size0]; + i = 0; + for( ; !(i >= Nw); i = i + 1) + { + waux_qtz[(signed long int)i] = 0.000000; + waux_double[(signed long int)i] = 0.000000; + } + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + double absolute_error; + double return_value_fxp_to_double$1=fxp_to_double((signed long int)y_qtz[(signed long int)i]); + absolute_error = y_double[(signed long int)i] - return_value_fxp_to_double$1; + __DSVERIFIER_assert(absolute_error < impl.max_error && absolute_error > -impl.max_error); + } + return 0; +} + +// verify_error_state_space +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_error_state_space.h line 20 +signed int verify_error_state_space(void) +{ + overflow_mode = 0; + struct anonymous$1 __backupController; + signed int i; + signed int j; + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + __backupController.A[(signed long int)i][(signed long int)j] = _controller.A[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs); j = j + 1) + __backupController.B[(signed long int)i][(signed long int)j] = _controller.B[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + __backupController.C[(signed long int)i][(signed long int)j] = _controller.C[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs); j = j + 1) + __backupController.D[(signed long int)i][(signed long int)j] = _controller.D[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + __backupController.states[(signed long int)i][(signed long int)j] = _controller.states[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nInputs); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + __backupController.inputs[(signed long int)i][(signed long int)j] = _controller.inputs[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + __backupController.outputs[(signed long int)i][(signed long int)j] = _controller.outputs[(signed long int)i][(signed long int)j]; + } + double __quant_error=0.000000; + double output_double=double_state_space_representation(); + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + _controller.A[(signed long int)i][(signed long int)j] = __backupController.A[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs); j = j + 1) + _controller.B[(signed long int)i][(signed long int)j] = __backupController.B[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + _controller.C[(signed long int)i][(signed long int)j] = __backupController.C[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= nInputs); j = j + 1) + _controller.D[(signed long int)i][(signed long int)j] = __backupController.D[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + _controller.states[(signed long int)i][(signed long int)j] = __backupController.states[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nInputs); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + _controller.inputs[(signed long int)i][(signed long int)j] = __backupController.inputs[(signed long int)i][(signed long int)j]; + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= 1); j = j + 1) + _controller.outputs[(signed long int)i][(signed long int)j] = __backupController.outputs[(signed long int)i][(signed long int)j]; + } + double output_fxp=fxp_state_space_representation(); + fxp_verify_overflow((signed long int)output_fxp); + __quant_error = ((output_fxp - output_double) / output_double) * 100.000000; + /* assertion __quant_error < error_limit && __quant_error > (-error_limit) */ + assert(__quant_error < error_limit && __quant_error > -error_limit); + if(__quant_error < error_limit && __quant_error > -error_limit) + (void)0; + + return 0; +} + +// verify_generic_timing +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_generic_timing.h line 25 +signed int verify_generic_timing(void) +{ + const signed long int verify_generic_timing$array_size0=(signed long int)X_SIZE_VALUE; + double y[verify_generic_timing$array_size0]; + const signed long int y$array_size0=(signed long int)X_SIZE_VALUE; + double x[y$array_size0]; + signed int i=0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + y[(signed long int)i] = 0.000000; + float return_value_nondet_float$1=nondet_float(); + x[(signed long int)i] = (double)return_value_nondet_float$1; + _Bool tmp_if_expr$2; + if(x[(signed long int)i] >= impl.min) + tmp_if_expr$2 = x[(signed long int)i] <= impl.max ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$2 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$2); + } + signed int Nw=0; + Nw = ds.a_size > ds.b_size ? ds.a_size : ds.b_size; + const signed long int Nw$array_size0=(signed long int)ds.a_size; + double yaux[Nw$array_size0]; + const signed long int yaux$array_size0=(signed long int)ds.b_size; + double xaux[yaux$array_size0]; + const signed long int xaux$array_size0=(signed long int)Nw; + double waux[xaux$array_size0]; + i = 0; + for( ; !(i >= ds.a_size); i = i + 1) + yaux[(signed long int)i] = 0.000000; + i = 0; + for( ; !(i >= ds.b_size); i = i + 1) + xaux[(signed long int)i] = 0.000000; + i = 0; + for( ; !(i >= Nw); i = i + 1) + waux[(signed long int)i] = 0.000000; + double xk; + double temp; + double *aptr; + double *bptr; + double *xptr; + double *yptr; + double *wptr; + signed int j; + generic_timer = generic_timer + 2 * hw.assembly.std + 1 * hw.assembly.rjmp; + double initial_timer=(double)generic_timer; + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + generic_timer = generic_timer + 2 * hw.assembly.ldd + 1 * hw.assembly.adiw + 2 * hw.assembly.std; + generic_timer = generic_timer + 2 * hw.assembly.ldd + 1 * hw.assembly.cpi + 1 * hw.assembly.cpc + 1 * hw.assembly.brlt; + double spent_time=(double)generic_timer * hw.cycle; + /* assertion spent_time <= ds.sample_time */ + assert(spent_time <= ds.sample_time); + if(spent_time <= ds.sample_time) + (void)0; + + generic_timer = (signed int)initial_timer; + } + return 0; +} + +// verify_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_limit_cycle.h line 111 +signed int verify_limit_cycle(void) +{ + overflow_mode = 3; + signed int i; + signed int Set_xsize_at_least_two_times_Na=2 * ds.a_size; + printf("X_SIZE must be at least 2 * ds.a_size"); + __DSVERIFIER_assert(X_SIZE_VALUE >= Set_xsize_at_least_two_times_Na); + const signed long int Set_xsize_at_least_two_times_Na$array_size0=(signed long int)X_SIZE_VALUE; + signed long int y[Set_xsize_at_least_two_times_Na$array_size0]; + const signed long int y$array_size0=(signed long int)X_SIZE_VALUE; + signed long int x[y$array_size0]; + signed long int min_fxp=fxp_double_to_fxp(impl.min); + signed long int max_fxp=fxp_double_to_fxp(impl.max); + const signed long int max_fxp$array_size0=(signed long int)ds.b_size; + signed long int xaux[max_fxp$array_size0]; + signed int nondet_constant_input=nondet_int(); + __DSVERIFIER_assume((signed long int)nondet_constant_input >= min_fxp && (signed long int)nondet_constant_input <= max_fxp); + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + x[(signed long int)i] = (signed long int)nondet_constant_input; + y[(signed long int)i] = 0l; + } + i = 0; + for( ; !(i >= ds.b_size); i = i + 1) + xaux[(signed long int)i] = (signed long int)nondet_constant_input; + signed int Nw=0; + Nw = ds.a_size > ds.b_size ? ds.a_size : ds.b_size; + const signed long int Nw$array_size0=(signed long int)ds.a_size; + signed long int yaux[Nw$array_size0]; + const signed long int yaux$array_size0=(signed long int)ds.a_size; + signed long int y0[yaux$array_size0]; + const signed long int y0$array_size0=(signed long int)Nw; + signed long int waux[y0$array_size0]; + const signed long int waux$array_size0=(signed long int)Nw; + signed long int w0[waux$array_size0]; + i = 0; + for( ; !(i >= Nw); i = i + 1) + { + signed int return_value_nondet_int$1=nondet_int(); + waux[(signed long int)i] = (signed long int)return_value_nondet_int$1; + _Bool tmp_if_expr$2; + if(waux[(signed long int)i] >= min_fxp) + tmp_if_expr$2 = waux[(signed long int)i] <= max_fxp ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$2 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$2); + w0[(signed long int)i] = waux[(signed long int)i]; + } + signed long int xk; + signed long int temp; + signed long int *aptr; + signed long int *bptr; + signed long int *xptr; + signed long int *yptr; + signed long int *wptr; + signed int j; + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + ; + fxp_check_persistent_limit_cycle(y, X_SIZE_VALUE); + return 0; +} + +// verify_limit_cycle_closed_loop +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_limit_cycle_closedloop.h line 29 +signed int verify_limit_cycle_closed_loop(void) +{ + overflow_mode = 3; + double *c_num=controller.b; + signed int c_num_size=controller.b_size; + double *c_den=controller.a; + signed int c_den_size=controller.a_size; + const signed long int c_den_size$array_size0=(signed long int)controller.b_size; + signed long int c_num_fxp[c_den_size$array_size0]; + fxp_double_to_fxp_array(c_num, c_num_fxp, controller.b_size); + const signed long int c_num_fxp$array_size0=(signed long int)controller.a_size; + signed long int c_den_fxp[c_num_fxp$array_size0]; + fxp_double_to_fxp_array(c_den, c_den_fxp, controller.a_size); + const signed long int c_den_fxp$array_size0=(signed long int)controller.b_size; + double c_num_qtz[c_den_fxp$array_size0]; + fxp_to_double_array(c_num_qtz, c_num_fxp, controller.b_size); + const signed long int c_num_qtz$array_size0=(signed long int)controller.a_size; + double c_den_qtz[c_num_qtz$array_size0]; + fxp_to_double_array(c_den_qtz, c_den_fxp, controller.a_size); + double *p_num=plant_cbmc.b; + signed int p_num_size=plant.b_size; + double *p_den=plant_cbmc.a; + signed int p_den_size=plant.a_size; + double ans_num[100l]; + signed int ans_num_size=(controller.b_size + plant.b_size) - 1; + double ans_den[100l]; + signed int ans_den_size=(controller.a_size + plant.a_size) - 1; + ft_closedloop_series(c_num_qtz, c_num_size, c_den_qtz, c_den_size, p_num, p_num_size, p_den, p_den_size, ans_num, ans_num_size, ans_den, ans_den_size); + signed int i; + const signed long int i$array_size0=(signed long int)X_SIZE_VALUE; + double y[i$array_size0]; + const signed long int y$array_size0=(signed long int)X_SIZE_VALUE; + double x[y$array_size0]; + const signed long int x$array_size0=(signed long int)ans_num_size; + double xaux[x$array_size0]; + double nondet_constant_input=nondet_double(); + __DSVERIFIER_assume(nondet_constant_input >= impl.min && nondet_constant_input <= impl.max); + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + x[(signed long int)i] = nondet_constant_input; + y[(signed long int)i] = 0.000000; + } + i = 0; + for( ; !(i >= ans_num_size); i = i + 1) + xaux[(signed long int)i] = nondet_constant_input; + const signed long int nondet_constant_input$array_size0=(signed long int)ans_den_size; + double yaux[nondet_constant_input$array_size0]; + const signed long int yaux$array_size0=(signed long int)ans_den_size; + double y0[yaux$array_size0]; + signed int Nw=ans_den_size > ans_num_size ? ans_den_size : ans_num_size; + const signed long int Nw$array_size0=(signed long int)Nw; + double waux[Nw$array_size0]; + const signed long int waux$array_size0=(signed long int)Nw; + double w0[waux$array_size0]; + i = 0; + for( ; !(i >= Nw); i = i + 1) + { + signed int return_value_nondet_int$1=nondet_int(); + waux[(signed long int)i] = (double)return_value_nondet_int$1; + _Bool tmp_if_expr$2; + if(waux[(signed long int)i] >= impl.min) + tmp_if_expr$2 = waux[(signed long int)i] <= impl.max ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$2 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$2); + w0[(signed long int)i] = waux[(signed long int)i]; + } + double xk; + double temp; + double *aptr; + double *bptr; + double *xptr; + double *yptr; + double *wptr; + signed int j; + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + ; + double_check_persistent_limit_cycle(y, X_SIZE_VALUE); + return 0; +} + +// verify_limit_cycle_state_space +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_limit_cycle.h line 21 +signed int verify_limit_cycle_state_space(void) +{ + double stateMatrix[20l][20l]; + double outputMatrix[20l][20l]; + double arrayLimitCycle[20l]; + double result1[20l][20l]; + double result2[20l][20l]; + signed int i; + signed int j; + signed int k; + i = 0; + for( ; !(i >= 20); i = i + 1) + { + j = 0; + for( ; !(j >= 20); j = j + 1) + { + result1[(signed long int)i][(signed long int)j] = 0.000000; + result2[(signed long int)i][(signed long int)j] = 0.000000; + stateMatrix[(signed long int)i][(signed long int)j] = 0.000000; + outputMatrix[(signed long int)i][(signed long int)j] = 0.000000; + } + } + double_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nStates, (unsigned int)nStates, 1u, _controller.C, _controller.states, result1); + double_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nInputs, (unsigned int)nInputs, 1u, _controller.D, _controller.inputs, result2); + double_add_matrix((unsigned int)nOutputs, 1u, result1, result2, _controller.outputs); + k = 0; + i = 1; + for( ; !(i >= 0); i = i + 1) + { + double_matrix_multiplication((unsigned int)nStates, (unsigned int)nStates, (unsigned int)nStates, 1u, _controller.A, _controller.states, result1); + double_matrix_multiplication((unsigned int)nStates, (unsigned int)nInputs, (unsigned int)nInputs, 1u, _controller.B, _controller.inputs, result2); + double_add_matrix((unsigned int)nStates, 1u, result1, result2, _controller.states); + double_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nStates, (unsigned int)nStates, 1u, _controller.C, _controller.states, result1); + double_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nInputs, (unsigned int)nInputs, 1u, _controller.D, _controller.inputs, result2); + double_add_matrix((unsigned int)nOutputs, 1u, result1, result2, _controller.outputs); + signed int l=0; + for( ; !(l >= nStates); l = l + 1) + stateMatrix[(signed long int)l][(signed long int)k] = _controller.states[(signed long int)l][0l]; + l = 0; + for( ; !(l >= nOutputs); l = l + 1) + stateMatrix[(signed long int)l][(signed long int)k] = _controller.outputs[(signed long int)l][0l]; + k = k + 1; + } + printf("#matrix STATES -------------------------------"); + print_matrix(stateMatrix, (unsigned int)nStates, 0u); + printf("#matrix OUTPUTS -------------------------------"); + print_matrix(outputMatrix, (unsigned int)nOutputs, 0u); + /* assertion 0 */ + assert(0 != 0); + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= 0); j = j + 1) + arrayLimitCycle[(signed long int)j] = stateMatrix[(signed long int)i][(signed long int)j]; + double_check_persistent_limit_cycle(arrayLimitCycle, 0); + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= 0); j = j + 1) + arrayLimitCycle[(signed long int)j] = outputMatrix[(signed long int)i][(signed long int)j]; + double_check_persistent_limit_cycle(arrayLimitCycle, 0); + } + /* assertion 0 */ + assert(0 != 0); +} + +// verify_minimum_phase +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_minimum_phase.h line 24 +signed int verify_minimum_phase(void) +{ + overflow_mode = 0; + return 0; +} + +// verify_observability +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_observability.h line 19 +signed int verify_observability(void) +{ + signed int i; + signed int j; + signed long int A_fpx[20l][20l]; + signed long int C_fpx[20l][20l]; + signed long int observabilityMatrix[20l][20l]; + signed long int backup[20l][20l]; + signed long int backupSecond[20l][20l]; + double observabilityMatrix_double[20l][20l]; + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + { + observabilityMatrix[(signed long int)i][(signed long int)j] = 0l; + A_fpx[(signed long int)i][(signed long int)j] = 0l; + C_fpx[(signed long int)i][(signed long int)j] = 0l; + backup[(signed long int)i][(signed long int)j] = 0l; + backupSecond[(signed long int)i][(signed long int)j] = 0l; + } + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + A_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.A[(signed long int)i][(signed long int)j]); + } + i = 0; + for( ; !(i >= nOutputs); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + C_fpx[(signed long int)i][(signed long int)j]=fxp_double_to_fxp(_controller.C[(signed long int)i][(signed long int)j]); + } + if(nOutputs >= 2) + { + signed int l; + j = 0; + l = 0; + while(!(l >= nStates)) + { + fxp_exp_matrix((unsigned int)nStates, (unsigned int)nStates, A_fpx, (unsigned int)l, backup); + l = l + 1; + fxp_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nStates, (unsigned int)nStates, (unsigned int)nStates, C_fpx, backup, backupSecond); + signed int k=0; + for( ; !(k >= nOutputs); k = k + 1) + { + i = 0; + for( ; !(i >= nStates); i = i + 1) + observabilityMatrix[(signed long int)j][(signed long int)i] = backupSecond[(signed long int)k][(signed long int)i]; + j = j + 1; + } + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nOutputs * nStates); j = j + 1) + backup[(signed long int)i][(signed long int)j] = 0l; + } + fxp_transpose(observabilityMatrix, backup, nStates * nOutputs, nStates); + signed long int mimo_observabilityMatrix_fxp[20l][20l]; + fxp_matrix_multiplication((unsigned int)nStates, (unsigned int)(nStates * nOutputs), (unsigned int)(nStates * nOutputs), (unsigned int)nStates, backup, observabilityMatrix, mimo_observabilityMatrix_fxp); + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + observabilityMatrix_double[(signed long int)i][(signed long int)j]=fxp_to_double(mimo_observabilityMatrix_fxp[(signed long int)i][(signed long int)j]); + } + double return_value_determinant$1=determinant(observabilityMatrix_double, nStates); + /* assertion determinant(observabilityMatrix_double,nStates) != 0 */ + assert(IEEE_FLOAT_NOTEQUAL(return_value_determinant$1, 0.000000)); + if(IEEE_FLOAT_NOTEQUAL(return_value_determinant$1, 0.000000)) + (void)0; + + } + + else + { + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + fxp_exp_matrix((unsigned int)nStates, (unsigned int)nStates, A_fpx, (unsigned int)i, backup); + fxp_matrix_multiplication((unsigned int)nOutputs, (unsigned int)nStates, (unsigned int)nStates, (unsigned int)nStates, C_fpx, backup, backupSecond); + j = 0; + for( ; !(j >= nStates); j = j + 1) + observabilityMatrix[(signed long int)i][(signed long int)j] = backupSecond[0l][(signed long int)j]; + } + i = 0; + for( ; !(i >= nStates); i = i + 1) + { + j = 0; + for( ; !(j >= nStates); j = j + 1) + observabilityMatrix_double[(signed long int)i][(signed long int)j]=fxp_to_double(observabilityMatrix[(signed long int)i][(signed long int)j]); + } + double return_value_determinant$2=determinant(observabilityMatrix_double, nStates); + /* assertion determinant(observabilityMatrix_double,nStates) != 0 */ + assert(IEEE_FLOAT_NOTEQUAL(return_value_determinant$2, 0.000000)); + if(IEEE_FLOAT_NOTEQUAL(return_value_determinant$2, 0.000000)) + (void)0; + + } + return 0; +} + +// verify_overflow +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_overflow.h line 23 +signed int verify_overflow(void) +{ + overflow_mode = 1; + signed long int min_fxp=fxp_double_to_fxp(impl.min); + signed long int max_fxp=fxp_double_to_fxp(impl.max); + const signed long int max_fxp$array_size0=(signed long int)X_SIZE_VALUE; + signed long int y[max_fxp$array_size0]; + const signed long int y$array_size0=(signed long int)X_SIZE_VALUE; + signed long int x[y$array_size0]; + signed int i=0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + y[(signed long int)i] = 0l; + signed int return_value_nondet_int$1=nondet_int(); + x[(signed long int)i] = (signed long int)return_value_nondet_int$1; + _Bool tmp_if_expr$2; + if(x[(signed long int)i] >= min_fxp) + tmp_if_expr$2 = x[(signed long int)i] <= max_fxp ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$2 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$2); + } + signed int Nw=0; + Nw = ds.a_size > ds.b_size ? ds.a_size : ds.b_size; + const signed long int Nw$array_size0=(signed long int)ds.a_size; + signed long int yaux[Nw$array_size0]; + const signed long int yaux$array_size0=(signed long int)ds.b_size; + signed long int xaux[yaux$array_size0]; + const signed long int xaux$array_size0=(signed long int)Nw; + signed long int waux[xaux$array_size0]; + i = 0; + for( ; !(i >= ds.a_size); i = i + 1) + yaux[(signed long int)i] = 0l; + i = 0; + for( ; !(i >= ds.b_size); i = i + 1) + xaux[(signed long int)i] = 0l; + i = 0; + for( ; !(i >= Nw); i = i + 1) + waux[(signed long int)i] = 0l; + signed long int xk; + signed long int temp; + signed long int *aptr; + signed long int *bptr; + signed long int *xptr; + signed long int *yptr; + signed long int *wptr; + signed int j; + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + ; + fxp_verify_overflow_array(y, X_SIZE_VALUE); + return 0; +} + +// verify_stability +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_stability.h line 24 +signed int verify_stability(void) +{ + overflow_mode = 0; + return 0; +} + +// verify_stability_closedloop_using_dslib +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_stability_closedloop.h line 21 +signed int verify_stability_closedloop_using_dslib(void) +{ + double *c_num=controller.b; + signed int c_num_size=controller.b_size; + double *c_den=controller.a; + signed int c_den_size=controller.a_size; + const signed long int c_den_size$array_size0=(signed long int)controller.b_size; + signed long int c_num_fxp[c_den_size$array_size0]; + fxp_double_to_fxp_array(c_num, c_num_fxp, controller.b_size); + const signed long int c_num_fxp$array_size0=(signed long int)controller.a_size; + signed long int c_den_fxp[c_num_fxp$array_size0]; + fxp_double_to_fxp_array(c_den, c_den_fxp, controller.a_size); + const signed long int c_den_fxp$array_size0=(signed long int)controller.b_size; + double c_num_qtz[c_den_fxp$array_size0]; + fxp_to_double_array(c_num_qtz, c_num_fxp, controller.b_size); + const signed long int c_num_qtz$array_size0=(signed long int)controller.a_size; + double c_den_qtz[c_num_qtz$array_size0]; + fxp_to_double_array(c_den_qtz, c_den_fxp, controller.a_size); + double *p_num=plant_cbmc.b; + signed int p_num_size=plant.b_size; + double *p_den=plant_cbmc.a; + signed int p_den_size=plant.a_size; + double ans_num[100l]; + signed int ans_num_size=(controller.b_size + plant.b_size) - 1; + double ans_den[100l]; + signed int ans_den_size=(controller.a_size + plant.a_size) - 1; + ft_closedloop_series(c_num_qtz, c_num_size, c_den_qtz, c_den_size, p_num, p_num_size, p_den, p_den_size, ans_num, ans_num_size, ans_den, ans_den_size); + printf("Verifying stability for closedloop function\n"); + signed int return_value_check_stability_closedloop$1=check_stability_closedloop(ans_den, ans_den_size, p_num, p_num_size, p_den, p_den_size); + __DSVERIFIER_assert((_Bool)return_value_check_stability_closedloop$1); + return 0; +} + +// verify_timing_msp_430 +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_timing_msp430.h line 22 +signed int verify_timing_msp_430(void) +{ + const signed long int verify_timing_msp_430$array_size0=(signed long int)X_SIZE_VALUE; + double y[verify_timing_msp_430$array_size0]; + const signed long int y$array_size0=(signed long int)X_SIZE_VALUE; + double x[y$array_size0]; + signed int i=0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + y[(signed long int)i] = 0.000000; + float return_value_nondet_float$1=nondet_float(); + x[(signed long int)i] = (double)return_value_nondet_float$1; + _Bool tmp_if_expr$2; + if(x[(signed long int)i] >= impl.min) + tmp_if_expr$2 = x[(signed long int)i] <= impl.max ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$2 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$2); + } + signed int Nw=0; + Nw = ds.a_size > ds.b_size ? ds.a_size : ds.b_size; + const signed long int Nw$array_size0=(signed long int)ds.a_size; + double yaux[Nw$array_size0]; + const signed long int yaux$array_size0=(signed long int)ds.b_size; + double xaux[yaux$array_size0]; + const signed long int xaux$array_size0=(signed long int)Nw; + double waux[xaux$array_size0]; + i = 0; + for( ; !(i >= ds.a_size); i = i + 1) + yaux[(signed long int)i] = 0.000000; + i = 0; + for( ; !(i >= ds.b_size); i = i + 1) + xaux[(signed long int)i] = 0.000000; + i = 0; + for( ; !(i >= Nw); i = i + 1) + waux[(signed long int)i] = 0.000000; + double xk; + double temp; + double *aptr; + double *bptr; + double *xptr; + double *yptr; + double *wptr; + signed int j; + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + ; + return 0; +} + +// verify_zero_input_limit_cycle +// file /home/lucascordeiro/dsverifier/bmc/engine/verify_zero_input_limit_cycle.h line 16 +signed int verify_zero_input_limit_cycle(void) +{ + overflow_mode = 3; + signed int i; + signed int j; + signed int Set_xsize_at_least_two_times_Na=2 * ds.a_size; + printf("X_SIZE must be at least 2 * ds.a_size"); + /* assertion X_SIZE_VALUE >= Set_xsize_at_least_two_times_Na */ + assert(X_SIZE_VALUE >= Set_xsize_at_least_two_times_Na); + if(X_SIZE_VALUE >= Set_xsize_at_least_two_times_Na) + (void)0; + + signed long int min_fxp=fxp_double_to_fxp(impl.min); + signed long int max_fxp=fxp_double_to_fxp(impl.max); + const signed long int max_fxp$array_size0=(signed long int)X_SIZE_VALUE; + signed long int y[max_fxp$array_size0]; + const signed long int y$array_size0=(signed long int)X_SIZE_VALUE; + signed long int x[y$array_size0]; + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + { + y[(signed long int)i] = 0l; + x[(signed long int)i] = 0l; + } + signed int Nw=0; + Nw = ds.a_size > ds.b_size ? ds.a_size : ds.b_size; + const signed long int Nw$array_size0=(signed long int)ds.a_size; + signed long int yaux[Nw$array_size0]; + const signed long int yaux$array_size0=(signed long int)ds.b_size; + signed long int xaux[yaux$array_size0]; + const signed long int xaux$array_size0=(signed long int)Nw; + signed long int waux[xaux$array_size0]; + const signed long int waux$array_size0=(signed long int)ds.a_size; + signed long int y0[waux$array_size0]; + const signed long int y0$array_size0=(signed long int)Nw; + signed long int w0[y0$array_size0]; + i = 0; + for( ; !(i >= Nw); i = i + 1) + { + signed int return_value_nondet_int$1=nondet_int(); + waux[(signed long int)i] = (signed long int)return_value_nondet_int$1; + _Bool tmp_if_expr$2; + if(waux[(signed long int)i] >= min_fxp) + tmp_if_expr$2 = waux[(signed long int)i] <= max_fxp ? (_Bool)1 : (_Bool)0; + + else + tmp_if_expr$2 = (_Bool)0; + __DSVERIFIER_assume(tmp_if_expr$2); + w0[(signed long int)i] = waux[(signed long int)i]; + } + i = 0; + for( ; !(i >= ds.b_size); i = i + 1) + xaux[(signed long int)i] = 0l; + signed long int xk; + signed long int temp; + signed long int *aptr; + signed long int *bptr; + signed long int *xptr; + signed long int *yptr; + signed long int *wptr; + i = 0; + for( ; !(i >= X_SIZE_VALUE); i = i + 1) + ; + fxp_check_persistent_limit_cycle(y, X_SIZE_VALUE); + return 0; +} + +// wrap +// file /home/lucascordeiro/dsverifier/bmc/core/fixed-point.h line 100 +signed long int wrap(signed long int kX, signed long int kLowerBound, signed long int kUpperBound) +{ + signed int range_size=(signed int)((kUpperBound - kLowerBound) + 1l); + if(!(kX >= kLowerBound)) + kX = kX + (signed long int)range_size * ((kLowerBound - kX) / (signed long int)range_size + 1l); + + return kLowerBound + (kX - kLowerBound) % (signed long int)range_size; +} + diff --git a/regression/cegis/cegis_control_benchmark_05/cegis_control_benchmark_05.zip b/regression/cegis/cegis_control_benchmark_05/cegis_control_benchmark_05.zip new file mode 100644 index 0000000000000000000000000000000000000000..548a448ce7240ae6347cc5fd91143c73698a531b GIT binary patch literal 109010 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�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 literal 0 HcmV?d00001 diff --git a/regression/cegis/cegis_control_benchmark_05/controller.h b/regression/cegis/cegis_control_benchmark_05/controller.h new file mode 100644 index 00000000000..c144be52ec7 --- /dev/null +++ b/regression/cegis/cegis_control_benchmark_05/controller.h @@ -0,0 +1 @@ +struct anonymous3 controller={ .den={ (control_floatt)1.000000, (control_floatt)-4.200000e-1f, (control_floatt)-3.465000e-1f, (control_floatt)-3.915000e-2f }, .den_uncertainty={ (control_floatt)0.000000, (control_floatt)0.000000, (control_floatt)0.000000, (control_floatt)0.000000 }, .den_size=4, .num={ (control_floatt)2.880000e+0, (control_floatt)-4.896000e+0f, (control_floatt)2.074000e+0 }, .num_uncertainty={ (control_floatt)0.000000, (control_floatt)0.000000, (control_floatt)0.000000 }, .num_size=3 }; diff --git a/regression/cegis/cegis_control_benchmark_05/plant.h b/regression/cegis/cegis_control_benchmark_05/plant.h new file mode 100644 index 00000000000..b8bf5575f9e --- /dev/null +++ b/regression/cegis/cegis_control_benchmark_05/plant.h @@ -0,0 +1 @@ +struct anonymous3 plant={ .den={ (control_floatt)1.000000, (control_floatt)-2.000000f, (control_floatt)1.000000 }, .den_uncertainty={ (control_floatt)0.000000, (control_floatt)0.000000, (control_floatt)0.000000 }, .den_size=3, .num={ (control_floatt)1.250000e-1, (control_floatt)1.250000e-1 }, .num_uncertainty={ (control_floatt)0.000000, (control_floatt)0.000000 }, .num_size=2 }; diff --git a/regression/cegis/cegis_control_benchmark_05/simplified_noise.c b/regression/cegis/cegis_control_benchmark_05/simplified_noise.c new file mode 100644 index 00000000000..5763bdcae90 --- /dev/null +++ b/regression/cegis/cegis_control_benchmark_05/simplified_noise.c @@ -0,0 +1,518 @@ +#include +#include + +/*#define __CONTROLLER_DEN_SIZE 3 +#define __CONTROLLER_NUM_SIZE 3 +#define __PLANT_DEN_SIZE 2 +#define __PLANT_NUM_SIZE 1 +#define SOLUTION_DEN_SIZE 3 +#define SOLUTION_NUM_SIZE 3*/ +#include "sizes.h" +#define __OPENLOOP_DEN_SIZE (__CONTROLLER_DEN_SIZE+__PLANT_DEN_SIZE-1) +#define __OPENLOOP_NUM_SIZE (__CONTROLLER_NUM_SIZE+__PLANT_NUM_SIZE-1) + +#define __NORMALIZED +#ifdef __CPROVER +#ifndef _FIXEDBV + #ifndef _EXPONENT_WIDTH + #define _EXPONENT_WIDTH 16 + #endif + #ifndef _FRACTION_WIDTH + #define _FRACTION_WIDTH 11 + #endif + typedef __CPROVER_floatbv[_EXPONENT_WIDTH][_FRACTION_WIDTH] control_floatt; + control_floatt _imp_max=(((1 <<(_EXPONENT_WIDTH-1))-1)<<1)+1; +#else + #ifndef _CONTROL_FLOAT_WIDTH + #define _CONTROL_FLOAT_WIDTH 16 + #endif + #ifndef _CONTORL_RADIX_WIDTH + #define _CONTORL_RADIX_WIDTH _CONTROL_FLOAT_WIDTH / 2 + #endif + typedef __CPROVER_fixedbv[_CONTROL_FLOAT_WIDTH][_CONTORL_RADIX_WIDTH] control_floatt; + control_floatt _imp_max=(((1 <<(_CONTROL_FLOAT_WIDTH-1))-1)<<1)+1; +#endif + typedef unsigned char cnttype; +#else + typedef double control_floatt; + typedef unsigned int cnttype; + #include + #include +#endif + +struct anonymous0 +{ + cnttype int_bits; + cnttype frac_bits; +}; + +struct anonymous3 +{ + control_floatt den[SOLUTION_DEN_SIZE]; + control_floatt den_uncertainty[SOLUTION_DEN_SIZE]; + cnttype den_size; + control_floatt num[SOLUTION_NUM_SIZE]; + control_floatt num_uncertainty[SOLUTION_NUM_SIZE]; + cnttype num_size; +}; + +control_floatt _dbl_max; +control_floatt _dbl_min; +signed long int _fxp_max; +signed long int _fxp_min; +signed long int _fxp_one; +control_floatt _dbl_lsb; +control_floatt _poly_error; +control_floatt _sum_error; +control_floatt _plant_norm; + +struct anonymous0 impl={ .int_bits=_CONTROLER_INT_BITS, .frac_bits=_CONTROLER_FRAC_BITS}; + +#include "plant.h" +/*struct anonymous3 plant={ .den={ 1.0, -9.998000e-1, 0.0}, .den_uncertainty={0.0, 0.0, 0.0}, .den_size=2, +.num={ 2.640000e-2, 0.0, 0.0}, .num_uncertainty={0.0, 0.0, 0.0}, .num_size=1};*/ +/*struct anonymous3 plant={ .den={ 1.0, -3.32481248817168, 1.64872127070013 }, .den_size=3, + .num={ 0.548693198268086, -0.886738807003861, 0.0 }, .num_size=2};*/ + +struct anonymous3 plant_cbmc,controller_cbmc; +//#ifdef __CPROVER +#include "controller.h" +//extern struct anonymous3 controller; +/*#else +//struct anonymous3 controller = { .den={ 32218.8125, 3544.125, 29723.25 }, .den_uncertainty={0.0, 0.0, 0.0}, .den_size=3, +// .num={ 17509.4375, 7878.25, 12107.6875 }, .num_uncertainty={0.0, 0.0, 0.0}, .num_size=3}; +struct anonymous3 controller = { .den={ 25868.375, -12550.9375, 5127.375 },.den_uncertainty={0.0, 0.0, 0.0}, .den_size=3, + .num={ 26097, -303.0625, -23076.25 }, .num_uncertainty={0.0, 0.0, 0.0}, .num_size=3}; +#endif*/ + +void __DSVERIFIER_assume(_Bool expression) +{ +#ifdef __CPROVER + __CPROVER_assume(expression != (_Bool)0); +#endif +} + +void __DSVERIFIER_assert(_Bool expression) +{ + /* assertion expression */ + assert(expression != (_Bool)0); +} + +void initialization() +{ + __DSVERIFIER_assert(impl.int_bits+impl.frac_bits < 32); +#ifdef __NORMALIZED + _fxp_one = 1 << (impl.frac_bits + impl.int_bits); + _dbl_lsb=1.0/(1 << impl.frac_bits + impl.int_bits); + _fxp_min = -(1 << (impl.frac_bits + impl.int_bits -1)); + _fxp_max = (1 << (impl.frac_bits + impl.int_bits-1))-1; + _dbl_max = (1.0-_dbl_lsb);//Fractional part +#else + if(impl.frac_bits >= 31) + _fxp_one = 2147483647l; + else + _fxp_one = (1 << impl.frac_bits); + _dbl_lsb=1.0/(1 << impl.frac_bits); + _fxp_min = -(1 << (impl.frac_bits + impl.int_bits -1)); + _fxp_max = (1 << (impl.frac_bits + impl.int_bits-1))-1; + _dbl_max = (1 << (impl.int_bits-1))-1;//Integer part + _dbl_max += (1.0-_dbl_lsb);//Fractional part +#endif + _dbl_min = -_dbl_max; +#ifdef __CHECK_FP + if (SOLUTION_DEN_SIZE>SOLUTION_NUM_SIZE) + { + _poly_error=2*_dbl_lsb*SOLUTION_DEN_SIZE; + _sum_error=2*_poly_error*SOLUTION_DEN_SIZE; + } + else + { + _poly_error=2*_dbl_lsb*SOLUTION_NUM_SIZE; + _sum_error=2*_poly_error*SOLUTION_DEN_SIZE; + } +#else + _poly_error=0; + _sum_error=0; +#endif +} + +int validation() +{ + cnttype i; + control_floatt max=0; + for (i=0;imax) max=plant.num[i]; + else if (-plant.num[i]>max) max=-plant.num[i]; + } + for (i=0;imax) max=plant.den[i]; + else if (-plant.den[i]>max) max=-plant.den[i]; + } + unsigned int max_int=max; +#ifdef __NORMALIZED + cnttype mult_bits=1; +#else + cnttype mult_bits=12; +#endif + while (max_int>0) + { + mult_bits++; + max_int>>=1; + } + _plant_norm=1<= _dbl_min); +#else + printf("value=%f", value); + if(value > _dbl_max) return 10; + if(value < _dbl_min) return 10; +#endif + } + for(i = 0 ; i < __CONTROLLER_NUM_SIZE; i++) + { + const control_floatt value=controller.num[i]; +#ifdef __CPROVER + __DSVERIFIER_assume(value <= _dbl_max); + __DSVERIFIER_assume(value >= _dbl_min); +#else + if (value > _dbl_max) return 10; + if (value < _dbl_min) return 10; +#endif + } + return 0; +} + +#ifndef __CPROVER +void print_poly(control_floatt *pol,cnttype n) +{ + cnttype i; + for (i=0;i 0.0) + { + control_floatt factor=(plant.num[i] * plant.num_uncertainty[i]) / 100.0; + factor = factor < 0.0 ? -factor : factor; + control_floatt min=plant.num[i] -factor; + control_floatt max=plant.num[i] +factor; + plant_cbmc.num[i] = nondet_double(); + __DSVERIFIER_assume(plant_cbmc.num[i] >= min); + __DSVERIFIER_assume(plant_cbmc.num[i] <= max); +#ifdef __NORMALIZED + plant_cbmc.num[i]/=_plant_norm; +#endif + } + else +#endif +#ifdef __NORMALIZED + plant_cbmc.num[i] = plant.num[i]/_plant_norm; +#else + plant_cbmc.num[i] = plant.num[i]; +#endif + plant_cbmc.den_size=plant.den_size; + for(i = 0; i < plant.den_size; i++) +#ifdef __CPROVER + if(plant.den_uncertainty[i] > 0.0) + { + control_floatt factor=(plant.den[i] * plant.den_uncertainty[i]) / 100.0; + factor = factor < 0.000000 ? -factor : factor; + control_floatt min=plant.den[i] -factor; + control_floatt max=plant.den[i] +factor; + plant_cbmc.den[i] = nondet_double(); + __DSVERIFIER_assume(plant_cbmc.den[i] >= min); + __DSVERIFIER_assume(plant_cbmc.den[i] <= max); +#ifdef __NORMALIZED + plant_cbmc.den[i]/=_plant_norm; +#endif + } + else +#endif +#ifdef __NORMALIZED + plant_cbmc.den[i] = plant.den[i]/_plant_norm; +#else + plant_cbmc.den[i] = plant.den[i]; +#endif +} + +int assert_nonzero_controller(void) +{ + unsigned int zero_count = 0; + for(unsigned int i=0; i < __CONTROLLER_DEN_SIZE; i++) + if (controller.den[i] == 0.0) ++zero_count; +#ifdef __CPROVER + __DSVERIFIER_assert(zero_count < __CONTROLLER_DEN_SIZE); +#else + if (zero_count >= __CONTROLLER_DEN_SIZE) return 0; +#endif + zero_count = 0; + for(unsigned int i = 0 ; i < __CONTROLLER_NUM_SIZE; i++) + if (controller.num[i] == 0.0) ++zero_count; +#ifdef __CPROVER + __DSVERIFIER_assert(zero_count < __CONTROLLER_NUM_SIZE); +#else + if (zero_count >= __CONTROLLER_NUM_SIZE) return 0; +#endif + return 1; +} + +signed int check_stability_closedloop(control_floatt *a, cnttype n) +{ + cnttype columns=n; + control_floatt m[n][n]; + cnttype i; + cnttype j; + control_floatt sum=0.0; + for(i = 0 ; i < n; i++) { sum += a[i]; } +#ifdef __CPROVER + __DSVERIFIER_assert(a[0] > _poly_error); + __DSVERIFIER_assert(sum > _sum_error); + __DSVERIFIER_assert(a[n-1]+_poly_error < a[0]); + __DSVERIFIER_assert(-a[n-1]+_poly_error < a[0]); +#else + printf("m[0]=%f>0\n", a[0]); + //std::cout << "m[0]=" << a[0] << ">0" << std::endl; + printf("fabs(m[%d]=%f)0\n", sum); + //std::cout << "sum=" << sum << ">0" << std::endl; + if (!(a[0] > _poly_error)) return 0; + if (!(sum > _sum_error)) return 0; + if (!(a[n - 1]+_poly_error < a[0])) return 0; + if (!(-a[n - 1]+_poly_error < a[0])) return 0; +#endif + sum = 0.0; + for(i = 0 ; i < n; i++) + { + if (((n -i)&1)!=0) sum+=a[i]; + else sum-=a[i]; + } + if ((n&1)==0) sum=-sum; +#ifdef __CPROVER + __DSVERIFIER_assert(sum > _sum_error); +#else + printf("sumEven-sumOdd=%f>0\n", sum); + //std::cout << "sumEven-sumOdd=" << sum << ">0" << std::endl; + if (!(sum > _sum_error)) return 0; +#endif + for(j=0;j0 + __DSVERIFIER_assert(m[i-1][0] > 0.0); + control_floatt factor=m[i-1][columns] / m[i-1][0]; +#ifdef __CHECK_FP + if (m[i-1][0]<0) __DSVERIFIER_assert(m[i-1][0]<-(mag*mag/_imp_max+_poly_error)); + else __DSVERIFIER_assert(m[i-1][0]> (mag*mag/_imp_max+_poly_error));//check for overflow. + control_floatt efactor=m[i-1][columns]; + if (efactor<0) efactor=-efactor; + efactor+=_poly_error; + efactor/=m[i-1][0]-_poly_error; + efactor-=factor; + __DSVERIFIER_assert(efactor<_poly_error*mag); + if (factor>0) + { + _poly_error*=2+factor;//Unsound! does not consider the error in factor (a+e/b-e = a/(b-e) +e/(b-e)) + mag+=mag*factor; + } + else + { + _poly_error*=2-factor; + mag-=mag*factor; + } +#endif + for(j=0;j= _poly_error); +#else + printf("m[%d]=%f>0\n", i, m[i][0]); + //std::cout << "m[" << i << "]=" << m[i][0] << ">0" << std::endl; + if (!(m[i][0] >= _poly_error)) return 0; +#endif + columns--; + } + return 1; +} + +signed long int fxp_control_floatt_to_fxp(control_floatt value) +{ + signed long int tmp; + control_floatt ftemp=value * _fxp_one; + tmp = ftemp; + control_floatt residue=ftemp - tmp; + if(value < 0.0 && (residue != 0.0)) + { + ftemp = ftemp - 1.0; + tmp = ftemp; + } + return tmp; +} + +void fxp_check(control_floatt *value) +{ +#ifdef __CPROVER + control_floatt tmp_value=*value; + if (tmp_value < 0.0) tmp_value=-tmp_value; + __DSVERIFIER_assert((~_dbl_max&tmp_value)==0); +#else + *value=fxp_control_floatt_to_fxp(*value); + *value/=_fxp_one; +#endif +} + +void fxp_check_array(control_floatt *f, cnttype N) +{ + for(cnttype i=0; i < N; i++) fxp_check(&f[i]); +} + +void poly_mult(control_floatt *a, cnttype Na, control_floatt *b, cnttype Nb, control_floatt *ans, cnttype Nans) +{ + cnttype i; + cnttype j; + cnttype k; + Nans = Na + Nb - 1; + for(i = 0 ; i + +/*******************************************************************\ + +Function: build_class_identifier + + Inputs: Struct expression + + Outputs: Member expression giving the clsid field of the input, + or its parent, grandparent, etc. + + Purpose: + +\*******************************************************************/ + +static exprt build_class_identifier( + const exprt &src, + const namespacet &ns) +{ + // the class identifier is in the root class + exprt e=src; + + while(1) + { + const typet &type=ns.follow(e.type()); + assert(type.id()==ID_struct); + + const struct_typet &struct_type=to_struct_type(type); + const struct_typet::componentst &components=struct_type.components(); + assert(!components.empty()); + + member_exprt member_expr( + e, + components.front().get_name(), + components.front().type()); + + if(components.front().get_name()=="@class_identifier") + { + // found it + return member_expr; + } + else + { + e=member_expr; + } + } +} + +/*******************************************************************\ + +Function: get_class_identifier_field + + Inputs: Pointer expression of any pointer type, including void*, + and a recommended access type if the pointer is void-typed. + + Outputs: Member expression to access a class identifier, as above. + + Purpose: + +\*******************************************************************/ + +exprt get_class_identifier_field( + exprt this_expr, + const symbol_typet &suggested_type, + const namespacet &ns) +{ + // Get a pointer from which we can extract a clsid. + // If it's already a pointer to an object of some sort, just use it; + // if it's void* then use the suggested type. + + assert(this_expr.type().id()==ID_pointer && + "Non-pointer this-arg in remove-virtuals?"); + const auto& points_to=this_expr.type().subtype(); + if(points_to==empty_typet()) + this_expr=typecast_exprt(this_expr, pointer_typet(suggested_type)); + exprt deref=dereference_exprt(this_expr, this_expr.type().subtype()); + return build_class_identifier(deref, ns); +} diff --git a/src/goto-programs/class_identifier.h b/src/goto-programs/class_identifier.h new file mode 100644 index 00000000000..343a041a547 --- /dev/null +++ b/src/goto-programs/class_identifier.h @@ -0,0 +1,21 @@ +/*******************************************************************\ + +Module: Extract class identifier + +Author: Chris Smowton, chris.smowton@diffblue.com + +\*******************************************************************/ + +#ifndef CPROVER_GOTO_PROGRAMS_CLASS_IDENTIFIER_H +#define CPROVER_GOTO_PROGRAMS_CLASS_IDENTIFIER_H + +#include +#include +#include + +exprt get_class_identifier_field( + exprt this_expr, + const symbol_typet &suggested_type, + const namespacet &ns); + +#endif diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index 4da7d62631b..68c388a8cdf 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -10,6 +10,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include "class_hierarchy.h" +#include "class_identifier.h" #include "remove_virtual_functions.h" /*******************************************************************\ @@ -61,8 +62,6 @@ class remove_virtual_functionst exprt get_method( const irep_idt &class_id, const irep_idt &component_name) const; - - exprt build_class_identifier(const exprt &); }; /*******************************************************************\ @@ -88,48 +87,6 @@ remove_virtual_functionst::remove_virtual_functionst( /*******************************************************************\ -Function: remove_virtual_functionst::build_class_identifier - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -exprt remove_virtual_functionst::build_class_identifier( - const exprt &src) -{ - // the class identifier is in the root class - exprt e=src; - - while(1) - { - const typet &type=ns.follow(e.type()); - assert(type.id()==ID_struct); - - const struct_typet &struct_type=to_struct_type(type); - const struct_typet::componentst &components=struct_type.components(); - assert(!components.empty()); - - member_exprt member_expr( - e, components.front().get_name(), components.front().type()); - - if(components.front().get_name()=="@class_identifier") - { - // found it - return member_expr; - } - else - { - e=member_expr; - } - } -} - -/*******************************************************************\ - Function: remove_virtual_functionst::remove_virtual_function Inputs: @@ -181,22 +138,12 @@ void remove_virtual_functionst::remove_virtual_function( goto_programt new_code_calls; goto_programt new_code_gotos; - // Get a pointer from which we can extract a clsid. - // If it's already a pointer to an object of some sort, just use it; - // if it's void* then use the parent of all possible candidates, - // which by the nature of get_functions happens to be the last candidate. - exprt this_expr=code.arguments()[0]; - assert(this_expr.type().id()==ID_pointer && - "Non-pointer this-arg in remove-virtuals?"); - const auto &points_to=this_expr.type().subtype(); - if(points_to==empty_typet()) - { - symbol_typet symbol_type(functions.back().class_id); - this_expr=typecast_exprt(this_expr, pointer_typet(symbol_type)); - } - exprt deref=dereference_exprt(this_expr, this_expr.type().subtype()); - exprt c_id2=build_class_identifier(deref); + // If necessary, cast to the last candidate function to get the object's clsid. + // By the structure of get_functions, this is the parent of all other classes + // under consideration. + symbol_typet suggested_type(functions.back().class_id); + exprt c_id2=get_class_identifier_field(this_expr, suggested_type, ns); goto_programt::targett last_function; for(const auto &fun : functions) From c85f573ad423335dca7373d3b8fe77c12d5bdd17 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 26 Jan 2017 10:42:24 +0000 Subject: [PATCH 104/166] Remove virtuals style improvements No functional changes intended --- src/goto-programs/class_identifier.cpp | 15 ++++++++------- src/goto-programs/class_identifier.h | 8 ++++---- src/goto-programs/remove_virtual_functions.cpp | 16 +++++++++------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/goto-programs/class_identifier.cpp b/src/goto-programs/class_identifier.cpp index df41fc9c5be..6e814174e51 100644 --- a/src/goto-programs/class_identifier.cpp +++ b/src/goto-programs/class_identifier.cpp @@ -9,6 +9,7 @@ Author: Chris Smowton, chris.smowton@diffblue.com #include "class_identifier.h" #include +#include /*******************************************************************\ @@ -33,25 +34,24 @@ static exprt build_class_identifier( while(1) { const typet &type=ns.follow(e.type()); - assert(type.id()==ID_struct); - const struct_typet &struct_type=to_struct_type(type); const struct_typet::componentst &components=struct_type.components(); assert(!components.empty()); + const auto &first_member_name=components.front().get_name(); member_exprt member_expr( e, - components.front().get_name(), + first_member_name, components.front().type()); - if(components.front().get_name()=="@class_identifier") + if(first_member_name=="@class_identifier") { // found it return member_expr; } else { - e=member_expr; + e.swap(member_expr); } } } @@ -70,7 +70,7 @@ Function: get_class_identifier_field \*******************************************************************/ exprt get_class_identifier_field( - exprt this_expr, + const exprt &this_expr_in, const symbol_typet &suggested_type, const namespacet &ns) { @@ -78,9 +78,10 @@ exprt get_class_identifier_field( // If it's already a pointer to an object of some sort, just use it; // if it's void* then use the suggested type. + exprt this_expr=this_expr_in; assert(this_expr.type().id()==ID_pointer && "Non-pointer this-arg in remove-virtuals?"); - const auto& points_to=this_expr.type().subtype(); + const auto &points_to=this_expr.type().subtype(); if(points_to==empty_typet()) this_expr=typecast_exprt(this_expr, pointer_typet(suggested_type)); exprt deref=dereference_exprt(this_expr, this_expr.type().subtype()); diff --git a/src/goto-programs/class_identifier.h b/src/goto-programs/class_identifier.h index 343a041a547..8ae6dc4ce71 100644 --- a/src/goto-programs/class_identifier.h +++ b/src/goto-programs/class_identifier.h @@ -9,12 +9,12 @@ Author: Chris Smowton, chris.smowton@diffblue.com #ifndef CPROVER_GOTO_PROGRAMS_CLASS_IDENTIFIER_H #define CPROVER_GOTO_PROGRAMS_CLASS_IDENTIFIER_H -#include -#include -#include +class exprt; +class namespacet; +class symbol_typet; exprt get_class_identifier_field( - exprt this_expr, + const exprt &this_expr, const symbol_typet &suggested_type, const namespacet &ns); diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index 68c388a8cdf..56c89dac3f0 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -139,9 +139,9 @@ void remove_virtual_functionst::remove_virtual_function( goto_programt new_code_gotos; exprt this_expr=code.arguments()[0]; - // If necessary, cast to the last candidate function to get the object's clsid. - // By the structure of get_functions, this is the parent of all other classes - // under consideration. + // If necessary, cast to the last candidate function to + // get the object's clsid. By the structure of get_functions, + // this is the parent of all other classes under consideration. symbol_typet suggested_type(functions.back().class_id); exprt c_id2=get_class_identifier_field(this_expr, suggested_type, ns); @@ -196,8 +196,10 @@ void remove_virtual_functionst::remove_virtual_function( const irep_idt comment=it->source_location.get_comment(); it->source_location=target->source_location; it->function=target->function; - if(!property_class.empty()) it->source_location.set_property_class(property_class); - if(!comment.empty()) it->source_location.set_comment(comment); + if(!property_class.empty()) + it->source_location.set_property_class(property_class); + if(!comment.empty()) + it->source_location.set_comment(comment); } goto_programt::targett next_target=target; @@ -302,7 +304,8 @@ void remove_virtual_functionst::get_functions( const class_hierarchyt::idst &parents= class_hierarchy.class_map[c].parents; - if(parents.empty()) break; + if(parents.empty()) + break; c=parents.front(); } @@ -380,7 +383,6 @@ bool remove_virtual_functionst::remove_virtual_functions( if(did_something) { - //remove_skip(goto_program); goto_program.update(); } From c83c5cc57ae8a24cfb23c7bfa1df97ba38310e53 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 24 Jan 2017 13:32:11 +0000 Subject: [PATCH 105/166] Discover lexical scopes for anonymous variables This enables tight variable scoping even when Java debug information is not available, which helps with analyses that benefit from DEAD instructions keeping their domains as small as possible. --- .../java_bytecode_convert_method.cpp | 130 ++++++++++++------ .../java_bytecode_convert_method_class.h | 2 +- 2 files changed, 90 insertions(+), 42 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index a2ca21ef80d..08f3b185425 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -712,6 +712,43 @@ code_blockt &java_bytecode_convert_methodt::get_or_create_block_for_pcrange( to_code(this_block_children[child_offset])).code()); } +static void gather_symbol_live_ranges( + unsigned pc, + const exprt &e, + std::map &result) +{ + if(e.id()==ID_symbol) + { + const auto &symexpr=to_symbol_expr(e); + auto findit= + result.insert({ + symexpr.get_identifier(), + java_bytecode_convert_methodt::variablet()}); + auto &var=findit.first->second; + if(findit.second) + { + var.symbol_expr=symexpr; + var.start_pc=pc; + var.length=1; + } + else + { + if(pc1; } + // Find out where temporaries are used: + std::map temporary_variable_live_ranges; + for(const auto &aentry : address_map) + gather_symbol_live_ranges( + aentry.first, + aentry.second.code, + temporary_variable_live_ranges); + + std::vector vars_to_process; for(const auto &vlist : variables) - { for(const auto &v : vlist) - { - if(v.is_parameter) - continue; - // Merge lexical scopes as far as possible to allow us to - // declare these variable scopes faithfully. - // Don't insert yet, as for the time being the blocks' only - // operands must be other blocks. - // The declarations will be inserted in the next pass instead. - get_or_create_block_for_pcrange( - root, - root_block, - v.start_pc, - v.start_pc+v.length, - std::numeric_limits::max(), - address_map); - } + vars_to_process.push_back(&v); + + for(const auto &v : tmp_vars) + vars_to_process.push_back( + &temporary_variable_live_ranges.at(v.get_identifier())); + + for(const auto &v : used_local_names) + vars_to_process.push_back( + &temporary_variable_live_ranges.at(v.get_identifier())); + + for(const auto vp : vars_to_process) + { + const auto &v=*vp; + if(v.is_parameter) + continue; + // Merge lexical scopes as far as possible to allow us to + // declare these variable scopes faithfully. + // Don't insert yet, as for the time being the blocks' only + // operands must be other blocks. + // The declarations will be inserted in the next pass instead. + get_or_create_block_for_pcrange( + root, + root_block, + v.start_pc, + v.start_pc+v.length, + std::numeric_limits::max(), + address_map); } - for(const auto &vlist : variables) + for(const auto vp : vars_to_process) { - for(const auto &v : vlist) - { - if(v.is_parameter) - continue; - // Skip anonymous variables: - if(v.symbol_expr.get_identifier()==irep_idt()) - continue; - auto &block=get_block_for_pcrange( - root, - root_block, - v.start_pc, - v.start_pc+v.length, - std::numeric_limits::max()); - code_declt d(v.symbol_expr); - block.operands().insert(block.operands().begin(), d); - } + const auto &v=*vp; + if(v.is_parameter) + continue; + // Skip anonymous variables: + if(v.symbol_expr.get_identifier()==irep_idt()) + continue; + auto &block=get_block_for_pcrange( + root, + root_block, + v.start_pc, + v.start_pc+v.length, + std::numeric_limits::max()); + code_declt d(v.symbol_expr); + block.operands().insert(block.operands().begin(), d); } for(auto &block : root_block.operands()) diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index b5ee7b28f55..43f51269aab 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -73,7 +73,6 @@ class java_bytecode_convert_methodt:public messaget typedef std::vector local_variable_table_with_holest; -protected: class variablet { public: @@ -85,6 +84,7 @@ class java_bytecode_convert_methodt:public messaget variablet() : symbol_expr(), start_pc(0), length(0), is_parameter(false) {} }; + protected: typedef std::vector variablest; expanding_vector variables; std::set used_local_names; From 04f699807730d1a92ea06adf7e66a00c0bf74462 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 24 Jan 2017 13:50:54 +0000 Subject: [PATCH 106/166] Add test for anonymous local scoping This creates three source-level variables that are notionally live for the whole function, but then uses the function's dominator tree information to show that they actually have disjoint scopes. Similarly the temporary used to hold a new instance between creation and assignment to a local variable should be given a bounded scope. --- .../cbmc-java/LocalVarTable5/test.class | Bin 0 -> 329 bytes regression/cbmc-java/LocalVarTable5/test.desc | 10 ++++++ regression/cbmc-java/LocalVarTable5/test.java | 29 ++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 regression/cbmc-java/LocalVarTable5/test.class create mode 100644 regression/cbmc-java/LocalVarTable5/test.desc create mode 100644 regression/cbmc-java/LocalVarTable5/test.java diff --git a/regression/cbmc-java/LocalVarTable5/test.class b/regression/cbmc-java/LocalVarTable5/test.class new file mode 100644 index 0000000000000000000000000000000000000000..b3a59b41f299dcc1935e2f7bdfc0e6c0619287d0 GIT binary patch literal 329 zcmXX=yGjF56r8hr#xmLnf}pX82$px(i`SaBRMzh7d)R)Fe!&<-ACu8-d68LCw$u|h%?ql-PnRQqt#B;ci_Sxx@|*gG)! literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/LocalVarTable5/test.desc b/regression/cbmc-java/LocalVarTable5/test.desc new file mode 100644 index 00000000000..bfe77ab09ad --- /dev/null +++ b/regression/cbmc-java/LocalVarTable5/test.desc @@ -0,0 +1,10 @@ +CORE +test.class +--show-goto-functions +dead anonlocal::1i +dead anonlocal::2i +dead anonlocal::3a +dead new_tmp0 +^EXIT=0$ +^SIGNAL=0$ +-- diff --git a/regression/cbmc-java/LocalVarTable5/test.java b/regression/cbmc-java/LocalVarTable5/test.java new file mode 100644 index 00000000000..32f52af80e6 --- /dev/null +++ b/regression/cbmc-java/LocalVarTable5/test.java @@ -0,0 +1,29 @@ + + +public class test +{ + public static void main(int unknown) + { + int i; + int j; + if(unknown==1) + { + // Check that anonymous locals + // get assigned scopes: + i = 0; + i++; + } + else if(unknown==2) + { + j = 0; + j++; + } + else + { + // Check that temporaries (here + // a new_tmp variable) are treated + // likewise + test t = new test(); + } + } +} From 175bc4e67b414eb419268e588af7308e481a489f Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 16 Jan 2017 08:03:29 -0500 Subject: [PATCH 107/166] Replace gen_zero/gen_one by from_integer where possible Also remove all (now) unnecessary #include Includes cleanup of string construction. --- src/aa-path-symex/path_symex.cpp | 5 +- src/aa-path-symex/path_symex_state.cpp | 1 - src/analyses/ai.cpp | 1 - src/analyses/flow_insensitive_analysis.cpp | 1 - src/analyses/goto_check.cpp | 16 ++-- src/analyses/invariant_propagation.cpp | 1 - src/analyses/invariant_set.cpp | 3 +- src/analyses/local_may_alias.cpp | 5 +- src/analyses/static_analysis.cpp | 1 - src/ansi-c/ansi_c_entry_point.cpp | 27 ++++--- src/ansi-c/ansi_c_language.cpp | 1 - src/ansi-c/c_typecast.cpp | 3 +- src/ansi-c/c_typecheck_argc_argv.cpp | 1 - src/ansi-c/c_typecheck_expr.cpp | 9 +-- src/ansi-c/c_typecheck_initializer.cpp | 1 - src/ansi-c/c_typecheck_type.cpp | 3 +- src/ansi-c/literals/convert_float_literal.cpp | 4 +- .../literals/convert_integer_literal.cpp | 3 +- src/ansi-c/parser_static.inc | 1 - src/cbmc/cbmc_parse_options.cpp | 1 - src/cbmc/counterexample_beautification.cpp | 1 - src/cbmc/fault_localization.cpp | 1 - .../symex/learn/danger_learn_config.cpp | 4 +- .../symex/verify/extract_counterexample.cpp | 5 +- .../symex/verify/insert_constraint.cpp | 1 - .../jsa/constraint/jsa_constraint_factory.cpp | 8 +- src/cegis/jsa/instrument/temps_helper.cpp | 5 +- src/cegis/jsa/learn/execute_jsa_programs.cpp | 12 ++- src/cegis/jsa/learn/insert_counterexample.cpp | 6 +- .../learn/insert_predicates_and_queries.cpp | 5 +- src/cegis/jsa/learn/instrument_pred_ops.cpp | 3 +- .../preprocessing/create_temp_variables.cpp | 4 +- .../jsa/verify/extract_counterexample.cpp | 1 - .../constraint/constraint_factory.cpp | 4 +- .../cegis_processor_body_factory.cpp | 5 +- .../instructionset/execute_cegis_program.cpp | 3 +- .../learn/instrument_counterexamples.cpp | 3 +- .../symex/learn/safety_learn_config.cpp | 4 +- src/cegis/seed/literals_seed.cpp | 5 +- src/cpp/cpp_typecheck.cpp | 1 - src/cpp/cpp_typecheck_code.cpp | 1 - src/cpp/cpp_typecheck_compound_type.cpp | 1 - src/cpp/cpp_typecheck_constructor.cpp | 1 - src/cpp/cpp_typecheck_conversions.cpp | 1 - src/cpp/cpp_typecheck_declaration.cpp | 2 - src/cpp/cpp_typecheck_expr.cpp | 1 - src/cpp/cpp_typecheck_function.cpp | 2 - src/cpp/cpp_typecheck_initializer.cpp | 3 +- src/cpp/cpp_typecheck_resolve.cpp | 1 - src/cpp/cpp_typecheck_template.cpp | 1 - src/cpp/cpp_typecheck_virtual_table.cpp | 1 - src/goto-diff/goto_diff_parse_options.cpp | 1 - src/goto-instrument/cover.cpp | 1 - src/goto-instrument/function.cpp | 7 +- .../goto_instrument_parse_options.cpp | 1 - src/goto-instrument/mmio.cpp | 1 - src/goto-programs/builtin_functions.cpp | 12 +-- src/goto-programs/goto_clean_expr.cpp | 1 - .../goto_convert_function_call.cpp | 1 - .../goto_convert_new_switch_case.cpp | 1 - .../goto_convert_side_effect.cpp | 26 +++++-- src/goto-programs/goto_inline.cpp | 1 - src/goto-programs/pointer_arithmetic.cpp | 4 +- src/goto-programs/remove_complex.cpp | 4 +- .../remove_function_pointers.cpp | 1 - src/goto-programs/string_abstraction.cpp | 14 +++- src/goto-programs/string_instrumentation.cpp | 28 ++++--- src/goto-symex/postcondition.cpp | 1 - src/goto-symex/rewrite_union.cpp | 6 +- src/goto-symex/symex_assign.cpp | 1 - src/goto-symex/symex_builtin_functions.cpp | 7 +- src/goto-symex/symex_clean_expr.cpp | 4 +- src/goto-symex/symex_dead.cpp | 1 - src/goto-symex/symex_decl.cpp | 1 - src/goto-symex/symex_dereference.cpp | 13 ++-- src/goto-symex/symex_function_call.cpp | 3 +- src/goto-symex/symex_goto.cpp | 1 - src/goto-symex/symex_other.cpp | 4 +- src/goto-symex/symex_target_equation.cpp | 1 - .../java_bytecode_convert_method.cpp | 6 +- src/java_bytecode/java_entry_point.cpp | 13 ++-- src/java_bytecode/java_object_factory.cpp | 3 +- src/jsil/jsil_entry_point.cpp | 4 +- src/linking/static_lifetime_init.cpp | 3 +- src/linking/zero_initializer.cpp | 2 +- src/musketeer/fence_shared.cpp | 1 - src/musketeer/fencer.cpp | 1 - src/musketeer/pensieve.cpp | 1 - src/path-symex/path_symex.cpp | 4 +- src/path-symex/path_symex_state.cpp | 1 - src/pointer-analysis/dereference.cpp | 4 +- src/pointer-analysis/value_set.cpp | 3 +- .../value_set_dereference.cpp | 8 +- src/pointer-analysis/value_set_fi.cpp | 3 +- src/pointer-analysis/value_set_fivr.cpp | 3 +- src/pointer-analysis/value_set_fivrns.cpp | 3 +- src/solvers/cvc/cvc_conv.cpp | 3 +- src/solvers/dplib/dplib_conv.cpp | 3 +- src/solvers/flattening/boolbv_member.cpp | 3 +- src/solvers/flattening/boolbv_update.cpp | 1 - src/solvers/flattening/boolbv_with.cpp | 1 - src/solvers/flattening/bv_pointers.cpp | 1 - src/solvers/floatbv/float_bv.cpp | 78 +++++++++++-------- src/solvers/smt1/smt1_conv.cpp | 3 +- src/solvers/smt2/smt2_conv.cpp | 2 +- src/util/arith_tools.cpp | 19 ++++- src/util/expr_util.cpp | 7 +- src/util/pointer_offset_size.cpp | 10 +-- src/util/pointer_predicates.cpp | 2 +- src/util/simplify_expr.cpp | 8 +- src/util/simplify_expr_int.cpp | 38 ++++----- src/util/simplify_expr_pointer.cpp | 4 +- 112 files changed, 288 insertions(+), 289 deletions(-) diff --git a/src/aa-path-symex/path_symex.cpp b/src/aa-path-symex/path_symex.cpp index 0ead6c840ba..0c18e34bb8e 100644 --- a/src/aa-path-symex/path_symex.cpp +++ b/src/aa-path-symex/path_symex.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include @@ -353,7 +352,7 @@ void path_symext::symex_malloc( rhs.type()=pointer_typet(value_symbol.type.subtype()); index_exprt index_expr(value_symbol.type.subtype()); index_expr.array()=value_symbol.symbol_expr(); - index_expr.index()=gen_zero(index_type()); + index_expr.index()=from_integer(0, index_type()); rhs.op0()=index_expr; } else @@ -486,7 +485,7 @@ void path_symext::assign_rec( else if(compound_type.id()==ID_union) { // rewrite into byte_extract, and do again - exprt offset=gen_zero(index_type()); + exprt offset=from_integer(0, index_type()); byte_extract_exprt new_lhs(byte_update_id(), struct_op, offset, ssa_rhs.type()); diff --git a/src/aa-path-symex/path_symex_state.cpp b/src/aa-path-symex/path_symex_state.cpp index 124b0e7fea9..f0f21b1b8b5 100644 --- a/src/aa-path-symex/path_symex_state.cpp +++ b/src/aa-path-symex/path_symex_state.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include diff --git a/src/analyses/ai.cpp b/src/analyses/ai.cpp index 4bc490a726b..06dd02af83f 100644 --- a/src/analyses/ai.cpp +++ b/src/analyses/ai.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include "is_threaded.h" diff --git a/src/analyses/flow_insensitive_analysis.cpp b/src/analyses/flow_insensitive_analysis.cpp index 0f9e15991f0..257e4b70890 100644 --- a/src/analyses/flow_insensitive_analysis.cpp +++ b/src/analyses/flow_insensitive_analysis.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include "flow_insensitive_analysis.h" diff --git a/src/analyses/goto_check.cpp b/src/analyses/goto_check.cpp index 131b7890de5..e5c1ec0290a 100644 --- a/src/analyses/goto_check.cpp +++ b/src/analyses/goto_check.cpp @@ -188,7 +188,7 @@ void goto_checkt::div_by_zero_check( // add divison by zero subgoal - exprt zero=gen_zero(expr.op1().type()); + exprt zero=from_integer(0, expr.op1().type()); if(zero.is_nil()) throw "no zero of argument type of operator "+expr.id_string(); @@ -233,7 +233,7 @@ void goto_checkt::undefined_shift_check( if(distance_type.id()==ID_signedbv) { binary_relation_exprt inequality( - expr.distance(), ID_ge, gen_zero(distance_type)); + expr.distance(), ID_ge, from_integer(0, distance_type)); add_guarded_claim( inequality, @@ -289,7 +289,7 @@ void goto_checkt::mod_by_zero_check( // add divison by zero subgoal - exprt zero=gen_zero(expr.op1().type()); + exprt zero=from_integer(0, expr.op1().type()); if(zero.is_nil()) throw "no zero of argument type of operator "+expr.id_string(); @@ -802,8 +802,8 @@ void goto_checkt::nan_check( // 0/0 = NaN and x/inf = NaN // (note that x/0 = +-inf for x!=0 and x!=inf) exprt zero_div_zero=and_exprt( - ieee_float_equal_exprt(expr.op0(), gen_zero(expr.op0().type())), - ieee_float_equal_exprt(expr.op1(), gen_zero(expr.op1().type()))); + ieee_float_equal_exprt(expr.op0(), from_integer(0, expr.op0().type())), + ieee_float_equal_exprt(expr.op1(), from_integer(0, expr.op1().type()))); exprt div_inf=unary_exprt(ID_isinf, expr.op1(), bool_typet()); @@ -819,10 +819,10 @@ void goto_checkt::nan_check( // Inf * 0 is NaN exprt inf_times_zero=and_exprt( unary_exprt(ID_isinf, expr.op0(), bool_typet()), - ieee_float_equal_exprt(expr.op1(), gen_zero(expr.op1().type()))); + ieee_float_equal_exprt(expr.op1(), from_integer(0, expr.op1().type()))); exprt zero_times_inf=and_exprt( - ieee_float_equal_exprt(expr.op1(), gen_zero(expr.op1().type())), + ieee_float_equal_exprt(expr.op1(), from_integer(0, expr.op1().type())), unary_exprt(ID_isinf, expr.op0(), bool_typet())); isnan=or_exprt(inf_times_zero, zero_times_inf); @@ -1175,7 +1175,7 @@ void goto_checkt::bounds_check( effective_offset=plus_exprt(p_offset, effective_offset); } - exprt zero=gen_zero(ode.offset().type()); + exprt zero=from_integer(0, ode.offset().type()); assert(zero.is_not_nil()); // the final offset must not be negative diff --git a/src/analyses/invariant_propagation.cpp b/src/analyses/invariant_propagation.cpp index c7ed805eddf..8e73d7e151b 100644 --- a/src/analyses/invariant_propagation.cpp +++ b/src/analyses/invariant_propagation.cpp @@ -6,7 +6,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include #include #include #include diff --git a/src/analyses/invariant_set.cpp b/src/analyses/invariant_set.cpp index 171e6510233..725a0fbc648 100644 --- a/src/analyses/invariant_set.cpp +++ b/src/analyses/invariant_set.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -992,7 +991,7 @@ void invariant_sett::nnf(exprt &expr, bool negate) { equal_exprt tmp; tmp.lhs()=expr.op0(); - tmp.rhs()=gen_zero(expr.op0().type()); + tmp.rhs()=from_integer(0, expr.op0().type()); nnf(tmp, !negate); expr.swap(tmp); } diff --git a/src/analyses/local_may_alias.cpp b/src/analyses/local_may_alias.cpp index c69158aebd7..25e3c4d5211 100644 --- a/src/analyses/local_may_alias.cpp +++ b/src/analyses/local_may_alias.cpp @@ -9,6 +9,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include #include #include @@ -272,7 +273,7 @@ void local_may_aliast::get_rec( if(index_expr.array().id()==ID_symbol) { index_exprt tmp1=index_expr; - tmp1.index()=gen_zero(index_type()); + tmp1.index()=from_integer(0, index_type()); address_of_exprt tmp2(tmp1); unsigned object_nr=objects.number(tmp2); dest.insert(object_nr); @@ -284,7 +285,7 @@ void local_may_aliast::get_rec( else if(index_expr.array().id()==ID_string_constant) { index_exprt tmp1=index_expr; - tmp1.index()=gen_zero(index_type()); + tmp1.index()=from_integer(0, index_type()); address_of_exprt tmp2(tmp1); unsigned object_nr=objects.number(tmp2); dest.insert(object_nr); diff --git a/src/analyses/static_analysis.cpp b/src/analyses/static_analysis.cpp index 2888ac26ec5..266b0131580 100644 --- a/src/analyses/static_analysis.cpp +++ b/src/analyses/static_analysis.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include "is_threaded.h" diff --git a/src/ansi-c/ansi_c_entry_point.cpp b/src/ansi-c/ansi_c_entry_point.cpp index 995ccf6ba03..bfb3f8663b1 100644 --- a/src/ansi-c/ansi_c_entry_point.cpp +++ b/src/ansi-c/ansi_c_entry_point.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -90,7 +89,7 @@ exprt::operandst build_function_environment( // record as an input input.op0()=address_of_exprt( - index_exprt(string_constantt(base_name), gen_zero(index_type()))); + index_exprt(string_constantt(base_name), from_integer(0, index_type()))); input.op1()=symbol_expr; input.add_source_location()=p.source_location(); @@ -131,9 +130,11 @@ void record_function_outputs( const symbolt &return_symbol=symbol_table.lookup("return'"); - output.op0()=address_of_exprt( - index_exprt(string_constantt(return_symbol.base_name), - gen_zero(index_type()))); + output.op0()= + address_of_exprt( + index_exprt( + string_constantt(return_symbol.base_name), + from_integer(0, index_type()))); output.op1()=return_symbol.symbol_expr(); output.add_source_location()=function.location; @@ -158,9 +159,11 @@ void record_function_outputs( codet output(ID_output); output.operands().resize(2); - output.op0()=address_of_exprt( - index_exprt(string_constantt(symbol.base_name), - gen_zero(index_type()))); + output.op0()= + address_of_exprt( + index_exprt( + string_constantt(symbol.base_name), + from_integer(0, index_type()))); output.op1()=symbol.symbol_expr(); output.add_source_location()=p.source_location(); @@ -350,7 +353,7 @@ bool ansi_c_entry_point( codet input(ID_input); input.operands().resize(2); input.op0()=address_of_exprt( - index_exprt(string_constantt("argc"), gen_zero(index_type()))); + index_exprt(string_constantt("argc"), from_integer(0, index_type()))); input.op1()=argc_symbol.symbol_expr(); init_code.move_to_operands(input); } @@ -392,7 +395,7 @@ bool ansi_c_entry_point( zero_string.type().subtype()=char_type(); zero_string.type().set(ID_size, "infinity"); exprt index(ID_index, char_type()); - index.copy_to_operands(zero_string, gen_zero(uint_type())); + index.copy_to_operands(zero_string, from_integer(0, uint_type())); exprt address_of("address_of", pointer_typet()); address_of.type().subtype()=char_type(); address_of.copy_to_operands(index); @@ -470,7 +473,7 @@ bool ansi_c_entry_point( exprt index_expr(ID_index, arg1.type().subtype()); index_expr.copy_to_operands( argv_symbol.symbol_expr(), - gen_zero(index_type())); + from_integer(0, index_type())); // disable bounds check on that one index_expr.set("bounds_check", false); @@ -489,7 +492,7 @@ bool ansi_c_entry_point( exprt index_expr(ID_index, arg2.type().subtype()); index_expr.copy_to_operands( - envp_symbol.symbol_expr(), gen_zero(index_type())); + envp_symbol.symbol_expr(), from_integer(0, index_type())); op2=exprt(ID_address_of, arg2.type()); op2.move_to_operands(index_expr); diff --git a/src/ansi-c/ansi_c_language.cpp b/src/ansi-c/ansi_c_language.cpp index 26be3f18935..dc69515ede2 100644 --- a/src/ansi-c/ansi_c_language.cpp +++ b/src/ansi-c/ansi_c_language.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include diff --git a/src/ansi-c/c_typecast.cpp b/src/ansi-c/c_typecast.cpp index 8486a01b406..06698fbd564 100644 --- a/src/ansi-c/c_typecast.cpp +++ b/src/ansi-c/c_typecast.cpp @@ -10,6 +10,7 @@ Author: Daniel Kroening, kroening@kroening.com #include +#include #include #include #include @@ -853,7 +854,7 @@ void c_typecastt::do_typecast(exprt &expr, const typet &dest_type) { index_exprt index; index.array()=expr; - index.index()=gen_zero(index_type()); + index.index()=from_integer(0, index_type()); index.type()=src_type.subtype(); expr=address_of_exprt(index); if(ns.follow(expr.type())!=ns.follow(dest_type)) diff --git a/src/ansi-c/c_typecheck_argc_argv.cpp b/src/ansi-c/c_typecheck_argc_argv.cpp index 71ac609d4b3..a528a630042 100644 --- a/src/ansi-c/c_typecheck_argc_argv.cpp +++ b/src/ansi-c/c_typecheck_argc_argv.cpp @@ -7,7 +7,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ #include -#include #include "c_typecheck_base.h" diff --git a/src/ansi-c/c_typecheck_expr.cpp b/src/ansi-c/c_typecheck_expr.cpp index abe2b49a1d1..1b9e8edae81 100644 --- a/src/ansi-c/c_typecheck_expr.cpp +++ b/src/ansi-c/c_typecheck_expr.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include #include @@ -100,7 +99,7 @@ void c_typecheck_baset::add_rounding_mode(exprt &expr) else assert(false); - expr.op2()=gen_zero(unsigned_int_type()); + expr.op2()=from_integer(0, unsigned_int_type()); } } } @@ -604,7 +603,7 @@ void c_typecheck_baset::typecheck_expr_builtin_offsetof(exprt &expr) exprt &member=static_cast(expr.add(ID_designator)); - exprt result=gen_zero(size_type()); + exprt result=from_integer(0, size_type()); forall_operands(m_it, member) { @@ -1286,7 +1285,7 @@ void c_typecheck_baset::typecheck_expr_typecast(exprt &expr) { index_exprt index; index.array()=op; - index.index()=gen_zero(index_type()); + index.index()=from_integer(0, index_type()); index.type()=op_type.subtype(); op=address_of_exprt(index); } @@ -2031,7 +2030,7 @@ void c_typecheck_baset::typecheck_expr_dereference(exprt &expr) // *a is the same as a[0] expr.id(ID_index); expr.type()=op_type.subtype(); - expr.copy_to_operands(gen_zero(index_type())); + expr.copy_to_operands(from_integer(0, index_type())); assert(expr.operands().size()==2); } else if(op_type.id()==ID_pointer) diff --git a/src/ansi-c/c_typecheck_initializer.cpp b/src/ansi-c/c_typecheck_initializer.cpp index c700210149e..4448f8f8de0 100644 --- a/src/ansi-c/c_typecheck_initializer.cpp +++ b/src/ansi-c/c_typecheck_initializer.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include #include diff --git a/src/ansi-c/c_typecheck_type.cpp b/src/ansi-c/c_typecheck_type.cpp index 879fbc34efc..f6af7da7a1a 100644 --- a/src/ansi-c/c_typecheck_type.cpp +++ b/src/ansi-c/c_typecheck_type.cpp @@ -12,7 +12,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include "c_typecheck_base.h" @@ -949,7 +948,7 @@ void c_typecheck_baset::typecheck_compound_body( // make it zero-length c_type.id(ID_array); - c_type.set(ID_size, gen_zero(index_type())); + c_type.set(ID_size, from_integer(0, index_type())); } } } diff --git a/src/ansi-c/literals/convert_float_literal.cpp b/src/ansi-c/literals/convert_float_literal.cpp index a7e256bf869..6eeaecb0dd8 100644 --- a/src/ansi-c/literals/convert_float_literal.cpp +++ b/src/ansi-c/literals/convert_float_literal.cpp @@ -11,9 +11,9 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include -#include #include "../c_types.h" #include "parse_float.h" @@ -142,7 +142,7 @@ exprt convert_float_literal(const std::string &src) complex_type.subtype()=result.type(); exprt complex_expr(ID_complex, complex_type); complex_expr.operands().resize(2); - complex_expr.op0()=gen_zero(result.type()); + complex_expr.op0()=from_integer(0, result.type()); complex_expr.op1()=result; return complex_expr; } diff --git a/src/ansi-c/literals/convert_integer_literal.cpp b/src/ansi-c/literals/convert_integer_literal.cpp index 81fa0da5ac3..705fa23c645 100644 --- a/src/ansi-c/literals/convert_integer_literal.cpp +++ b/src/ansi-c/literals/convert_integer_literal.cpp @@ -13,7 +13,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include "convert_integer_literal.h" @@ -187,7 +186,7 @@ exprt convert_integer_literal(const std::string &src) complex_type.subtype()=type; result=exprt(ID_complex, complex_type); result.operands().resize(2); - result.op0()=gen_zero(type); + result.op0()=from_integer(0, type); result.op1()=from_integer(value, type); } else diff --git a/src/ansi-c/parser_static.inc b/src/ansi-c/parser_static.inc index 791c91fc6b7..eb91ce52983 100644 --- a/src/ansi-c/parser_static.inc +++ b/src/ansi-c/parser_static.inc @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "c_types.h" diff --git a/src/cbmc/cbmc_parse_options.cpp b/src/cbmc/cbmc_parse_options.cpp index 35a5002572d..51fd717edb2 100644 --- a/src/cbmc/cbmc_parse_options.cpp +++ b/src/cbmc/cbmc_parse_options.cpp @@ -13,7 +13,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include diff --git a/src/cbmc/counterexample_beautification.cpp b/src/cbmc/counterexample_beautification.cpp index 8475f122040..c0e5d1ba230 100644 --- a/src/cbmc/counterexample_beautification.cpp +++ b/src/cbmc/counterexample_beautification.cpp @@ -7,7 +7,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ #include -#include #include #include #include diff --git a/src/cbmc/fault_localization.cpp b/src/cbmc/fault_localization.cpp index 1554efa4b13..d1d711fe274 100644 --- a/src/cbmc/fault_localization.cpp +++ b/src/cbmc/fault_localization.cpp @@ -7,7 +7,6 @@ Author: Peter Schrammel \*******************************************************************/ #include -#include #include #include #include diff --git a/src/cegis/danger/symex/learn/danger_learn_config.cpp b/src/cegis/danger/symex/learn/danger_learn_config.cpp index 159af723b91..7a085695713 100644 --- a/src/cegis/danger/symex/learn/danger_learn_config.cpp +++ b/src/cegis/danger/symex/learn/danger_learn_config.cpp @@ -9,7 +9,7 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include +#include #include #include @@ -61,7 +61,7 @@ void danger_learn_configt::process(const size_t max_solution_size) get_invariant_constraint_vars(ce_vars, original_program); counterexamplet dummy_ce; const typet type(cegis_default_integer_type()); // XXX: Currently single data type - const exprt zero(gen_zero(type)); + const exprt zero(from_integer(0, type)); for (const symbol_exprt &var : ce_vars) dummy_ce.insert(std::make_pair(var.get_identifier(), zero)); counterexamplest empty(1, dummy_ce); diff --git a/src/cegis/invariant/symex/verify/extract_counterexample.cpp b/src/cegis/invariant/symex/verify/extract_counterexample.cpp index 4a2d9cf211f..b02412176a0 100644 --- a/src/cegis/invariant/symex/verify/extract_counterexample.cpp +++ b/src/cegis/invariant/symex/verify/extract_counterexample.cpp @@ -10,7 +10,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include + #include #include @@ -63,7 +64,7 @@ class extract_counterexamplet for (const goto_programt::targett &pos : q) { const irep_idt &var=get_affected_variable(*pos); - const exprt value(gen_zero(get_affected_type(*pos))); + const exprt value(from_integer(0, get_affected_type(*pos))); result.insert(std::make_pair(var, value)); } q.clear(); diff --git a/src/cegis/invariant/symex/verify/insert_constraint.cpp b/src/cegis/invariant/symex/verify/insert_constraint.cpp index 0eb89c01e09..1e8b84fdfe3 100644 --- a/src/cegis/invariant/symex/verify/insert_constraint.cpp +++ b/src/cegis/invariant/symex/verify/insert_constraint.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include diff --git a/src/cegis/jsa/constraint/jsa_constraint_factory.cpp b/src/cegis/jsa/constraint/jsa_constraint_factory.cpp index 00b611f9d36..7db0d975c79 100644 --- a/src/cegis/jsa/constraint/jsa_constraint_factory.cpp +++ b/src/cegis/jsa/constraint/jsa_constraint_factory.cpp @@ -7,7 +7,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +#include #include #include @@ -30,7 +30,7 @@ const notequal_exprt get_base_case(const jsa_programt &prog) { const irep_idt &id=get_affected_variable(*prog.base_case); const symbol_exprt symbol(prog.st.lookup(id).symbol_expr()); - return notequal_exprt(symbol, gen_zero(symbol.type())); + return notequal_exprt(symbol, from_integer(0, symbol.type())); } void imply_true(const jsa_programt &prog, goto_programt &body, @@ -40,10 +40,10 @@ void imply_true(const jsa_programt &prog, goto_programt &body, const goto_programt::targett restriction=body.insert_after(pos); restriction->type=instr_type; const symbol_exprt smb(as_symbol(prog.st, get_affected_variable(*pos))); - const notequal_exprt consequent(smb, gen_zero(smb.type())); + const notequal_exprt consequent(smb, from_integer(0, smb.type())); const irep_idt &sid=get_affected_variable(*prog.inductive_assumption); const symbol_exprt si(as_symbol(prog.st, sid)); - const equal_exprt antecedent(si, gen_zero(si.type())); + const equal_exprt antecedent(si, from_integer(0, si.type())); const or_exprt safety_implication(antecedent, consequent); restriction->guard=and_exprt(get_base_case(prog), safety_implication); restriction->source_location=jsa_builtin_source_location(); diff --git a/src/cegis/jsa/instrument/temps_helper.cpp b/src/cegis/jsa/instrument/temps_helper.cpp index d70f9c5ef50..7bb7510c2f3 100644 --- a/src/cegis/jsa/instrument/temps_helper.cpp +++ b/src/cegis/jsa/instrument/temps_helper.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include @@ -39,7 +38,7 @@ goto_programt::targett zero_jsa_temps(jsa_programt &prog, { if (!is_tmp(symbol)) continue; const symbol_exprt lhs(symbol.second.symbol_expr()); - pos=jsa_assign(st, gf, pos, lhs, gen_zero(lhs.type())); + pos=jsa_assign(st, gf, pos, lhs, from_integer(0, lhs.type())); } return pos; } @@ -77,7 +76,7 @@ void add_zero_jsa_temps_to_pred_exec(jsa_programt &prog) const constant_exprt index(from_integer(i, signed_int_type())); const index_exprt elem(ops, index); const dereference_exprt lhs(elem, jsa_word_type()); - const exprt rhs(gen_zero(lhs.type())); + const exprt rhs(from_integer(0, lhs.type())); pos=cegis_assign(st, body, pos, lhs, rhs, loc); } move_labels(body, return_pos, pos); diff --git a/src/cegis/jsa/learn/execute_jsa_programs.cpp b/src/cegis/jsa/learn/execute_jsa_programs.cpp index 27fed92b3fc..5e1433c3e14 100644 --- a/src/cegis/jsa/learn/execute_jsa_programs.cpp +++ b/src/cegis/jsa/learn/execute_jsa_programs.cpp @@ -7,8 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include + #include -#include #include #include @@ -47,7 +48,8 @@ void make_constraint_call(const symbol_tablet &st, goto_functionst &gf, args.push_back(address_of_exprt(get_user_heap(gf))); args.push_back(address_of_exprt(get_queried_heap(st))); const symbol_exprt p(st.lookup(get_cegis_meta_name(JSA_INV)).symbol_expr()); - args.push_back(address_of_exprt(index_exprt(p, gen_zero(signed_int_type())))); + constant_exprt zero=from_integer(0, signed_int_type()); + args.push_back(address_of_exprt(index_exprt(p, zero))); args.push_back(st.lookup(get_cegis_meta_name(JSA_INV_SZ)).symbol_expr()); make_constraint_call(st, gf, pos, args); } @@ -73,7 +75,8 @@ void make_query_call(jsa_programt &prog, const symbol_tablet &st, code_function_callt::argumentst &args=call.arguments(); args.push_back(address_of_exprt(get_queried_heap(st))); const symbol_exprt p(st.lookup(get_cegis_meta_name(JSA_QUERY)).symbol_expr()); - args.push_back(address_of_exprt(index_exprt(p, gen_zero(signed_int_type())))); + constant_exprt zero=from_integer(0, signed_int_type()); + args.push_back(address_of_exprt(index_exprt(p, zero))); args.push_back(st.lookup(get_cegis_meta_name(JSA_QUERY_SZ)).symbol_expr()); pos->code=call; } @@ -91,7 +94,8 @@ void make_sync_call(const symbol_tablet &st, goto_functionst &gf, args.push_back(address_of_exprt(get_user_heap(gf))); args.push_back(address_of_exprt(get_queried_heap(st))); const symbol_exprt p(st.lookup(get_cegis_meta_name(JSA_QUERY)).symbol_expr()); - args.push_back(address_of_exprt(index_exprt(p, gen_zero(signed_int_type())))); + constant_exprt zero=from_integer(0, signed_int_type()); + args.push_back(address_of_exprt(index_exprt(p, zero))); args.push_back(st.lookup(get_cegis_meta_name(JSA_QUERY_SZ)).symbol_expr()); pos->code=call; } diff --git a/src/cegis/jsa/learn/insert_counterexample.cpp b/src/cegis/jsa/learn/insert_counterexample.cpp index 6d277d54e2a..531c60df191 100644 --- a/src/cegis/jsa/learn/insert_counterexample.cpp +++ b/src/cegis/jsa/learn/insert_counterexample.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include @@ -93,7 +92,8 @@ void add_array_index(jsa_programt &prog) pos=body.insert_after(pos); const typet type(signed_int_type()); declare_jsa_meta_variable(st, pos, CE_ARRAY_INDEX, type); - pos=assign_jsa_meta_variable(st, gf, pos, CE_ARRAY_INDEX, gen_zero(type)); + constant_exprt zero=from_integer(0, signed_int_type()); + pos=assign_jsa_meta_variable(st, gf, pos, CE_ARRAY_INDEX, zero); } symbol_exprt get_ce_array_index(const symbol_tablet &st) @@ -110,7 +110,7 @@ void add_ce_goto(jsa_programt &prog, const size_t ces_size) pos->type=goto_program_instruction_typet::ASSIGN; const symbol_exprt lhs(get_ce_array_index(prog.st)); const typet &type=lhs.type(); - const plus_exprt inc(lhs, gen_one(type), type); + const plus_exprt inc(lhs, from_integer(1, type), type); pos->code=code_assignt(lhs, inc); pos=body.insert_after(pos); pos->source_location=jsa_builtin_source_location(); diff --git a/src/cegis/jsa/learn/insert_predicates_and_queries.cpp b/src/cegis/jsa/learn/insert_predicates_and_queries.cpp index 4aaf9e38cb5..2727450b193 100644 --- a/src/cegis/jsa/learn/insert_predicates_and_queries.cpp +++ b/src/cegis/jsa/learn/insert_predicates_and_queries.cpp @@ -12,7 +12,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include @@ -36,7 +35,7 @@ goto_programt::targett assume_less_than(goto_programt &body, pos->type=goto_program_instruction_typet::ASSUME; const constant_exprt max_expr(from_integer(max, jsa_internal_index_type())); const binary_relation_exprt size_limit(lhs, ID_le, max_expr); - const exprt min(gen_one(jsa_internal_index_type())); + const exprt min(from_integer(1, jsa_internal_index_type())); const binary_relation_exprt min_size(lhs, ID_ge, min); pos->guard=and_exprt(min_size, size_limit); return pos; @@ -72,7 +71,7 @@ void declare_jsa_predicates(jsa_programt &prog, const size_t max_sz) const bv_arithmetict bv(to_array_type(preds.type()).size()); const mp_integer::ullong_t num_preds=bv.to_integer().to_ulong(); const typet sz_type(signed_int_type()); - const exprt zero(gen_zero(sz_type)); + const exprt zero(from_integer(0, sz_type)); const size_t max_pred_size=get_max_pred_size(st); for (mp_integer::ullong_t i=0; i < num_preds; ++i) { diff --git a/src/cegis/jsa/learn/instrument_pred_ops.cpp b/src/cegis/jsa/learn/instrument_pred_ops.cpp index 9e001bdb34d..7f477b1cd2b 100644 --- a/src/cegis/jsa/learn/instrument_pred_ops.cpp +++ b/src/cegis/jsa/learn/instrument_pred_ops.cpp @@ -12,7 +12,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include @@ -71,7 +70,7 @@ void mark_dead(goto_programt &body, goto_programt::targett pos, pos=body.insert_after(pos); pos->type=goto_program_instruction_typet::ASSIGN; pos->source_location=jsa_builtin_source_location(); - pos->code=code_assignt(op_elem, gen_zero(op_elem.type())); + pos->code=code_assignt(op_elem, from_integer(0, op_elem.type())); } } diff --git a/src/cegis/jsa/preprocessing/create_temp_variables.cpp b/src/cegis/jsa/preprocessing/create_temp_variables.cpp index 4f142e7210e..95f552f94b0 100644 --- a/src/cegis/jsa/preprocessing/create_temp_variables.cpp +++ b/src/cegis/jsa/preprocessing/create_temp_variables.cpp @@ -7,7 +7,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include +#include #include @@ -30,7 +30,7 @@ void create_jsa_temp_variables(jsa_programt &prog, const size_t max_size) pos=body.insert_after(pos); const std::string base_name(tmp_prefix + std::to_string(i)); declare_jsa_meta_variable(st, pos, base_name, type); - pos=assign_jsa_meta_variable(st, gf, pos, base_name, gen_zero(type)); + pos=assign_jsa_meta_variable(st, gf, pos, base_name, from_integer(0, type)); } prog.synthetic_variables=pos; } diff --git a/src/cegis/jsa/verify/extract_counterexample.cpp b/src/cegis/jsa/verify/extract_counterexample.cpp index 662dacdb6c9..3fd5a2f2d2c 100644 --- a/src/cegis/jsa/verify/extract_counterexample.cpp +++ b/src/cegis/jsa/verify/extract_counterexample.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include #include #include diff --git a/src/cegis/refactor/constraint/constraint_factory.cpp b/src/cegis/refactor/constraint/constraint_factory.cpp index 42a2c324f71..66f0dd9ab7c 100644 --- a/src/cegis/refactor/constraint/constraint_factory.cpp +++ b/src/cegis/refactor/constraint/constraint_factory.cpp @@ -9,8 +9,8 @@ Author: Daniel Kroening, kroening@kroening.com #include +#include #include -#include #include #include #include @@ -88,7 +88,7 @@ void create_constraint_function_caller(refactor_programt &prog) call.function()=symbol.symbol_expr(); code_function_callt::argumentst &args=call.arguments(); for (const code_typet::parametert ¶m : type.parameters()) - args.push_back(gen_zero(param.type())); + args.push_back(from_integer(0, param.type())); pos->code=call; } body.add_instruction(goto_program_instruction_typet::END_FUNCTION); diff --git a/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp b/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp index 567276dc536..a7ccb540296 100644 --- a/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp +++ b/src/cegis/refactor/instructionset/cegis_processor_body_factory.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include @@ -163,7 +162,7 @@ class body_factoryt void declare_instruction_loop_head() { - decl(CEGIS_PROC_INSTR_INDEX, gen_zero(cegis_size_type())); + decl(CEGIS_PROC_INSTR_INDEX, from_integer(0, cegis_size_type())); const member_exprt opcode(cegis_opcode(st, func_name)); const size_t size(num_instrs(ordered_instructions)); assume_less(pos=body.insert_after(pos), opcode, size); @@ -178,7 +177,7 @@ class body_factoryt const char * const base_idx_name=CEGIS_PROC_INSTR_INDEX; const std::string idx(meta_name(base_idx_name)); const symbol_exprt idx_expr(st.lookup(idx).symbol_expr()); - const plus_exprt rhs(idx_expr, gen_one(idx_expr.type())); + const plus_exprt rhs(idx_expr, from_integer(1, idx_expr.type())); cegis_assign_local_variable(st, body, pos, func_name, base_idx_name, rhs); pos=std::prev(body.instructions.end(), 2); const std::string index(meta_name(CEGIS_PROC_INSTR_INDEX)); diff --git a/src/cegis/refactor/instructionset/execute_cegis_program.cpp b/src/cegis/refactor/instructionset/execute_cegis_program.cpp index 347f550bde5..663ddcb8b20 100644 --- a/src/cegis/refactor/instructionset/execute_cegis_program.cpp +++ b/src/cegis/refactor/instructionset/execute_cegis_program.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include @@ -56,7 +55,7 @@ void call_processor(const symbol_tablet &st, goto_programt::instructiont &instr, code_function_callt::argumentst &args=call.arguments(); const symbolt &prog_symbol=st.lookup(program_name); const symbol_exprt prog(prog_symbol.symbol_expr()); - const index_exprt first_instr(prog, gen_zero(signed_int_type())); + const index_exprt first_instr(prog, from_integer(0, signed_int_type())); args.push_back(address_of_exprt(first_instr)); const bv_arithmetict bv(get_size(prog_symbol)); const mp_integer sz_val(bv.to_integer()); diff --git a/src/cegis/refactor/learn/instrument_counterexamples.cpp b/src/cegis/refactor/learn/instrument_counterexamples.cpp index 58af6e51c03..4e6051f8283 100644 --- a/src/cegis/refactor/learn/instrument_counterexamples.cpp +++ b/src/cegis/refactor/learn/instrument_counterexamples.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include @@ -73,7 +72,7 @@ void create_ce_arrays(symbol_tablet &st, goto_functionst &gf, void create_ce_array_indexes(const std::set &ce_keys, symbol_tablet &st, goto_functionst &gf) { - const exprt zero(gen_zero(signed_int_type())); + const exprt zero(from_integer(0, signed_int_type())); declare_global_meta_variable(st, gf, CE_ARRAY_INDEX, zero); goto_programt &body=get_body(gf, CONSTRAINT_CALLER_ID); goto_programt::targett pos=body.instructions.begin(); diff --git a/src/cegis/safety/symex/learn/safety_learn_config.cpp b/src/cegis/safety/symex/learn/safety_learn_config.cpp index da2331cbda3..ec8c97de57a 100644 --- a/src/cegis/safety/symex/learn/safety_learn_config.cpp +++ b/src/cegis/safety/symex/learn/safety_learn_config.cpp @@ -9,7 +9,7 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include +#include #include @@ -65,7 +65,7 @@ void safety_learn_configt::process(const size_t max_solution_size) constraint_varst ce_vars; get_invariant_constraint_vars(ce_vars, original_program); const typet type(cegis_default_integer_type()); // XXX: Currently single data type - const exprt zero(gen_zero(type)); + const exprt zero(from_integer(0, type)); counterexamplet dummy_ce; dummy_ce.x.push_back(counterexamplet::assignmentst()); counterexamplet::assignmentst &x=dummy_ce.x.front(); diff --git a/src/cegis/seed/literals_seed.cpp b/src/cegis/seed/literals_seed.cpp index 7e7c7b63639..6cd402d5467 100644 --- a/src/cegis/seed/literals_seed.cpp +++ b/src/cegis/seed/literals_seed.cpp @@ -10,7 +10,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include +#include #include #include @@ -275,7 +275,8 @@ class value_poolt const size_t index) const { const valuest &values=operator[](id); - if (values.empty()) return to_constant_expr(gen_zero(type)); + if(values.empty()) + return from_integer(0, type); return values.at(index % values.size()); } diff --git a/src/cpp/cpp_typecheck.cpp b/src/cpp/cpp_typecheck.cpp index 6a53c0aa04d..5d0387840fe 100644 --- a/src/cpp/cpp_typecheck.cpp +++ b/src/cpp/cpp_typecheck.cpp @@ -8,7 +8,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include -#include #include #include #include diff --git a/src/cpp/cpp_typecheck_code.cpp b/src/cpp/cpp_typecheck_code.cpp index 05f5491dc9a..0914df233d1 100644 --- a/src/cpp/cpp_typecheck_code.cpp +++ b/src/cpp/cpp_typecheck_code.cpp @@ -6,7 +6,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include #include #include "cpp_typecheck.h" diff --git a/src/cpp/cpp_typecheck_compound_type.cpp b/src/cpp/cpp_typecheck_compound_type.cpp index 83dea257569..f8057808f38 100644 --- a/src/cpp/cpp_typecheck_compound_type.cpp +++ b/src/cpp/cpp_typecheck_compound_type.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include -#include #include #include diff --git a/src/cpp/cpp_typecheck_constructor.cpp b/src/cpp/cpp_typecheck_constructor.cpp index d3ce33b2871..65e97dfd263 100644 --- a/src/cpp/cpp_typecheck_constructor.cpp +++ b/src/cpp/cpp_typecheck_constructor.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include #include -#include #include diff --git a/src/cpp/cpp_typecheck_conversions.cpp b/src/cpp/cpp_typecheck_conversions.cpp index 37017ec41d9..32878368f1f 100644 --- a/src/cpp/cpp_typecheck_conversions.cpp +++ b/src/cpp/cpp_typecheck_conversions.cpp @@ -10,7 +10,6 @@ Module: C++ Language Type Checking #include #include -#include #include #include #include diff --git a/src/cpp/cpp_typecheck_declaration.cpp b/src/cpp/cpp_typecheck_declaration.cpp index 2b73f05d39c..bef63d1eda1 100644 --- a/src/cpp/cpp_typecheck_declaration.cpp +++ b/src/cpp/cpp_typecheck_declaration.cpp @@ -6,8 +6,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \********************************************************************/ -#include - #include "cpp_typecheck.h" #include "cpp_declarator_converter.h" diff --git a/src/cpp/cpp_typecheck_expr.cpp b/src/cpp/cpp_typecheck_expr.cpp index 1bc298665f3..a8e8fed5651 100644 --- a/src/cpp/cpp_typecheck_expr.cpp +++ b/src/cpp/cpp_typecheck_expr.cpp @@ -8,7 +8,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include -#include #include #include #include diff --git a/src/cpp/cpp_typecheck_function.cpp b/src/cpp/cpp_typecheck_function.cpp index e0e1c5bf822..ccbd2dd58b2 100644 --- a/src/cpp/cpp_typecheck_function.cpp +++ b/src/cpp/cpp_typecheck_function.cpp @@ -6,8 +6,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include - #include #include "cpp_template_type.h" diff --git a/src/cpp/cpp_typecheck_initializer.cpp b/src/cpp/cpp_typecheck_initializer.cpp index a225902d543..225f6d5aa5c 100644 --- a/src/cpp/cpp_typecheck_initializer.cpp +++ b/src/cpp/cpp_typecheck_initializer.cpp @@ -6,7 +6,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include #include #include @@ -296,7 +295,7 @@ void cpp_typecheckt::zero_initializer( typet enum_type(ID_unsignedbv); enum_type.add(ID_width)=final_type.find(ID_width); - exprt zero(gen_zero(enum_type)); + exprt zero(from_integer(0, enum_type)); zero.make_typecast(type); already_typechecked(zero); diff --git a/src/cpp/cpp_typecheck_resolve.cpp b/src/cpp/cpp_typecheck_resolve.cpp index e8502c1419a..6655eb258f6 100644 --- a/src/cpp/cpp_typecheck_resolve.cpp +++ b/src/cpp/cpp_typecheck_resolve.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include -#include #include #include #include diff --git a/src/cpp/cpp_typecheck_template.cpp b/src/cpp/cpp_typecheck_template.cpp index 73997bb5aff..61aa6504968 100644 --- a/src/cpp/cpp_typecheck_template.cpp +++ b/src/cpp/cpp_typecheck_template.cpp @@ -6,7 +6,6 @@ Author: Daniel Kroening, kroening@cs.cmu.edu \*******************************************************************/ -#include #include #include "cpp_type2name.h" diff --git a/src/cpp/cpp_typecheck_virtual_table.cpp b/src/cpp/cpp_typecheck_virtual_table.cpp index 151ea1034e2..74efcad31c9 100644 --- a/src/cpp/cpp_typecheck_virtual_table.cpp +++ b/src/cpp/cpp_typecheck_virtual_table.cpp @@ -12,7 +12,6 @@ Function: cpp_typecheckt::do_virtual_table #include #include -#include #include "cpp_typecheck.h" diff --git a/src/goto-diff/goto_diff_parse_options.cpp b/src/goto-diff/goto_diff_parse_options.cpp index c819d1537d0..c22766492bb 100644 --- a/src/goto-diff/goto_diff_parse_options.cpp +++ b/src/goto-diff/goto_diff_parse_options.cpp @@ -13,7 +13,6 @@ Author: Peter Schrammel #include #include -#include #include #include diff --git a/src/goto-instrument/cover.cpp b/src/goto-instrument/cover.cpp index f27bbd5f19c..b7c8381a224 100644 --- a/src/goto-instrument/cover.cpp +++ b/src/goto-instrument/cover.cpp @@ -12,7 +12,6 @@ Date: May 2016 #include #include -#include #include "cover.h" diff --git a/src/goto-instrument/function.cpp b/src/goto-instrument/function.cpp index e7a08a5c1c2..1ad749814bd 100644 --- a/src/goto-instrument/function.cpp +++ b/src/goto-instrument/function.cpp @@ -6,10 +6,10 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include #include #include #include -#include #include #include @@ -79,8 +79,9 @@ code_function_callt function_to_call( call.arguments().resize(1); call.arguments()[0]= typecast_exprt( - address_of_exprt(index_exprt( - function_id_string, gen_zero(index_type()))), + address_of_exprt( + index_exprt( + function_id_string, from_integer(0, index_type()))), to_code_type(s_it->second.type).parameters()[0].type()); return call; diff --git a/src/goto-instrument/goto_instrument_parse_options.cpp b/src/goto-instrument/goto_instrument_parse_options.cpp index 11c3ffc6620..45a5a964812 100644 --- a/src/goto-instrument/goto_instrument_parse_options.cpp +++ b/src/goto-instrument/goto_instrument_parse_options.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include diff --git a/src/goto-instrument/mmio.cpp b/src/goto-instrument/mmio.cpp index 098e8378e18..fbd2fc5989c 100644 --- a/src/goto-instrument/mmio.cpp +++ b/src/goto-instrument/mmio.cpp @@ -15,7 +15,6 @@ Date: September 2011 #if 0 #include -#include #include #include diff --git a/src/goto-programs/builtin_functions.cpp b/src/goto-programs/builtin_functions.cpp index 687b13a664a..d6a67946730 100644 --- a/src/goto-programs/builtin_functions.cpp +++ b/src/goto-programs/builtin_functions.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -316,8 +315,11 @@ void goto_convertt::do_scanf( const symbolt &tmp_symbol= new_tmp_symbol(type, "scanf_string", dest, function.source_location()); - exprt rhs=address_of_exprt( - index_exprt(tmp_symbol.symbol_expr(), gen_zero(index_type()))); + exprt rhs= + address_of_exprt( + index_exprt( + tmp_symbol.symbol_expr(), + from_integer(0, index_type()))); // now use array copy codet array_copy_statement; @@ -838,11 +840,11 @@ void goto_convertt::do_java_new_array( side_effect_exprt inc(ID_assign); inc.operands().resize(2); inc.op0()=tmp_i; - inc.op1()=plus_exprt(tmp_i, gen_one(tmp_i.type())); + inc.op1()=plus_exprt(tmp_i, from_integer(1, tmp_i.type())); dereference_exprt deref_expr(plus_exprt(data, tmp_i), data.type().subtype()); - for_loop.init()=code_assignt(tmp_i, gen_zero(tmp_i.type())); + for_loop.init()=code_assignt(tmp_i, from_integer(0, tmp_i.type())); for_loop.cond()=binary_relation_exprt(tmp_i, ID_lt, rhs.op0()); for_loop.iter()=inc; for_loop.body()=code_skipt(); diff --git a/src/goto-programs/goto_clean_expr.cpp b/src/goto-programs/goto_clean_expr.cpp index ff9a8068c34..45c37242883 100644 --- a/src/goto-programs/goto_clean_expr.cpp +++ b/src/goto-programs/goto_clean_expr.cpp @@ -7,7 +7,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ #include -#include #include #include #include diff --git a/src/goto-programs/goto_convert_function_call.cpp b/src/goto-programs/goto_convert_function_call.cpp index badeebc29fb..9735f994297 100644 --- a/src/goto-programs/goto_convert_function_call.cpp +++ b/src/goto-programs/goto_convert_function_call.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include diff --git a/src/goto-programs/goto_convert_new_switch_case.cpp b/src/goto-programs/goto_convert_new_switch_case.cpp index 83b82b034c8..063fc579ead 100644 --- a/src/goto-programs/goto_convert_new_switch_case.cpp +++ b/src/goto-programs/goto_convert_new_switch_case.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include diff --git a/src/goto-programs/goto_convert_side_effect.cpp b/src/goto-programs/goto_convert_side_effect.cpp index da2d8ca7cad..6312e38f04b 100644 --- a/src/goto-programs/goto_convert_side_effect.cpp +++ b/src/goto-programs/goto_convert_side_effect.cpp @@ -6,6 +6,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include #include #include #include @@ -197,14 +198,14 @@ void goto_convertt::remove_pre( if(op_type.id()==ID_bool) { - rhs.copy_to_operands(expr.op0(), gen_one(signed_int_type())); + rhs.copy_to_operands(expr.op0(), from_integer(1, signed_int_type())); rhs.op0().make_typecast(signed_int_type()); rhs.type()=signed_int_type(); rhs=is_not_zero(rhs, ns); } else if(op_type.id()==ID_c_bool) { - rhs.copy_to_operands(expr.op0(), gen_one(signed_int_type())); + rhs.copy_to_operands(expr.op0(), from_integer(1, signed_int_type())); rhs.op0().make_typecast(signed_int_type()); rhs.type()=signed_int_type(); rhs=is_not_zero(rhs, ns); @@ -213,7 +214,7 @@ void goto_convertt::remove_pre( else if(op_type.id()==ID_c_enum || op_type.id()==ID_c_enum_tag) { - rhs.copy_to_operands(expr.op0(), gen_one(signed_int_type())); + rhs.copy_to_operands(expr.op0(), from_integer(1, signed_int_type())); rhs.op0().make_typecast(signed_int_type()); rhs.type()=signed_int_type(); rhs.make_typecast(op_type); @@ -233,7 +234,7 @@ void goto_convertt::remove_pre( throw 0; } - exprt constant=gen_one(constant_type); + exprt constant=from_integer(1, constant_type); rhs.copy_to_operands(expr.op0()); rhs.move_to_operands(constant); @@ -301,14 +302,14 @@ void goto_convertt::remove_post( if(op_type.id()==ID_bool) { - rhs.copy_to_operands(expr.op0(), gen_one(signed_int_type())); + rhs.copy_to_operands(expr.op0(), from_integer(1, signed_int_type())); rhs.op0().make_typecast(signed_int_type()); rhs.type()=signed_int_type(); rhs=is_not_zero(rhs, ns); } else if(op_type.id()==ID_c_bool) { - rhs.copy_to_operands(expr.op0(), gen_one(signed_int_type())); + rhs.copy_to_operands(expr.op0(), from_integer(1, signed_int_type())); rhs.op0().make_typecast(signed_int_type()); rhs.type()=signed_int_type(); rhs=is_not_zero(rhs, ns); @@ -317,7 +318,7 @@ void goto_convertt::remove_post( else if(op_type.id()==ID_c_enum || op_type.id()==ID_c_enum_tag) { - rhs.copy_to_operands(expr.op0(), gen_one(signed_int_type())); + rhs.copy_to_operands(expr.op0(), from_integer(1, signed_int_type())); rhs.op0().make_typecast(signed_int_type()); rhs.type()=signed_int_type(); rhs.make_typecast(op_type); @@ -337,7 +338,16 @@ void goto_convertt::remove_post( throw 0; } - exprt constant=gen_one(constant_type); + exprt constant; + + if(constant_type.id()==ID_complex) + { + exprt real=from_integer(1, constant_type.subtype()); + exprt imag=from_integer(0, constant_type.subtype()); + constant=complex_exprt(real, imag, to_complex_type(constant_type)); + } + else + constant=from_integer(1, constant_type); rhs.copy_to_operands(expr.op0()); rhs.move_to_operands(constant); diff --git a/src/goto-programs/goto_inline.cpp b/src/goto-programs/goto_inline.cpp index d392de25170..830798c289e 100644 --- a/src/goto-programs/goto_inline.cpp +++ b/src/goto-programs/goto_inline.cpp @@ -13,7 +13,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include "remove_skip.h" #include "goto_inline.h" diff --git a/src/goto-programs/pointer_arithmetic.cpp b/src/goto-programs/pointer_arithmetic.cpp index c080329cb75..0639a0dbca4 100644 --- a/src/goto-programs/pointer_arithmetic.cpp +++ b/src/goto-programs/pointer_arithmetic.cpp @@ -6,8 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include #include -#include #include "pointer_arithmetic.h" @@ -76,7 +76,7 @@ void pointer_arithmetict::read(const exprt &src) add_to_offset(index_expr.index()); // produce &x[0] + i instead of &x[i] exprt new_src=src; - new_src.op0().op1()=gen_zero(index_expr.index().type()); + new_src.op0().op1()=from_integer(0, index_expr.index().type()); make_pointer(new_src); } } diff --git a/src/goto-programs/remove_complex.cpp b/src/goto-programs/remove_complex.cpp index 553a70dab50..4bb030299a2 100644 --- a/src/goto-programs/remove_complex.cpp +++ b/src/goto-programs/remove_complex.cpp @@ -8,7 +8,7 @@ Date: September 2014 \*******************************************************************/ -#include +#include #include "remove_complex.h" @@ -166,7 +166,7 @@ void remove_complex(exprt &expr) struct_expr.operands().resize(2); struct_expr.op0()=typecast_exprt(expr.op0(), subtype); - struct_expr.op1()=gen_zero(subtype); + struct_expr.op1()=from_integer(0, subtype); struct_expr.add_source_location()=expr.source_location(); expr=struct_expr; diff --git a/src/goto-programs/remove_function_pointers.cpp b/src/goto-programs/remove_function_pointers.cpp index 7a25def3823..1baca8d11d5 100644 --- a/src/goto-programs/remove_function_pointers.cpp +++ b/src/goto-programs/remove_function_pointers.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include diff --git a/src/goto-programs/string_abstraction.cpp b/src/goto-programs/string_abstraction.cpp index 114eddb2d3e..a12b766eb1e 100644 --- a/src/goto-programs/string_abstraction.cpp +++ b/src/goto-programs/string_abstraction.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -764,7 +763,7 @@ void string_abstractiont::abstract_function_call( assert(type_eq(str_args.back().type().subtype(), abstract_type.subtype(), ns)); - index_exprt idx(str_args.back(), gen_zero(index_type())); + index_exprt idx(str_args.back(), from_integer(0, index_type())); // disable bounds check on that one idx.set("bounds_check", false); @@ -1533,8 +1532,15 @@ goto_programt::targett string_abstractiont::abstract_char_assign( assert(i2.is_not_nil()); make_type(ptr.offset, build_type(LENGTH)); - return char_assign(dest, target, new_lhs, i2, - ptr.offset.is_nil()?gen_zero(build_type(LENGTH)):ptr.offset); + return + char_assign( + dest, + target, + new_lhs, + i2, + ptr.offset.is_nil()? + from_integer(0, build_type(LENGTH)): + ptr.offset); } } diff --git a/src/goto-programs/string_instrumentation.cpp b/src/goto-programs/string_instrumentation.cpp index d5a269a6018..67d8a430b57 100644 --- a/src/goto-programs/string_instrumentation.cpp +++ b/src/goto-programs/string_instrumentation.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -549,7 +548,7 @@ void string_instrumentationt::do_format_string_read( { index_exprt index; index.array()=temp; - index.index()=gen_zero(index_type()); + index.index()=from_integer(0, index_type()); index.type()=arg_type.subtype(); temp=address_of_exprt(index); } @@ -597,7 +596,7 @@ void string_instrumentationt::do_format_string_read( { index_exprt index; index.array()=temp; - index.index()=gen_zero(index_type()); + index.index()=from_integer(0, index_type()); index.type()=arg_type.subtype(); temp=address_of_exprt(index); } @@ -664,7 +663,7 @@ void string_instrumentationt::do_format_string_write( { exprt fwidth = from_integer(token.field_width, unsigned_int_type()); exprt fw_1(ID_plus, unsigned_int_type()); - exprt one = gen_one(unsigned_int_type()); + exprt one=from_integer(1, unsigned_int_type()); fw_1.move_to_operands(fwidth); fw_1.move_to_operands(one); // +1 for 0-char @@ -676,7 +675,7 @@ void string_instrumentationt::do_format_string_write( { index_exprt index; index.array()=argument; - index.index()=gen_zero(unsigned_int_type()); + index.index()=from_integer(0, unsigned_int_type()); address_of_exprt aof(index); fw_lt_bs=binary_relation_exprt(fw_1, ID_le, buffer_size(aof)); } @@ -1018,16 +1017,20 @@ void string_instrumentationt::do_strerror( goto_programt::targett assumption1=tmp.add_instruction(); - assumption1->make_assumption(binary_relation_exprt( - symbol_size.symbol_expr(), ID_notequal, - gen_zero(symbol_size.type))); + assumption1->make_assumption( + binary_relation_exprt( + symbol_size.symbol_expr(), + ID_notequal, + from_integer(0, symbol_size.type))); assumption1->source_location=it->source_location; } // return a pointer to some magic buffer exprt index=exprt(ID_index, char_type()); - index.copy_to_operands(symbol_buf.symbol_expr(), gen_zero(index_type())); + index.copy_to_operands( + symbol_buf.symbol_expr(), + from_integer(0, index_type())); exprt ptr=exprt(ID_address_of, pointer_typet()); ptr.type().subtype()=char_type(); @@ -1096,7 +1099,8 @@ void string_instrumentationt::invalidate_buffer( goto_programt::targett init=dest.add_instruction(ASSIGN); init->source_location=target->source_location; - init->code=code_assignt(cntr_sym.symbol_expr(), gen_zero(cntr_sym.type)); + init->code= + code_assignt(cntr_sym.symbol_expr(), from_integer(0, cntr_sym.type)); goto_programt::targett check=dest.add_instruction(); check->source_location=target->source_location; @@ -1109,7 +1113,7 @@ void string_instrumentationt::invalidate_buffer( exprt plus(ID_plus, unsigned_int_type()); plus.copy_to_operands(cntr_sym.symbol_expr()); - plus.copy_to_operands(gen_one(unsigned_int_type())); + plus.copy_to_operands(from_integer(1, unsigned_int_type())); increment->code=code_assignt(cntr_sym.symbol_expr(), plus); @@ -1130,7 +1134,7 @@ void string_instrumentationt::invalidate_buffer( { index_exprt index; index.array()=buffer; - index.index()=gen_zero(index_type()); + index.index()=from_integer(0, index_type()); index.type()=buf_type.subtype(); bufp = address_of_exprt(index); } diff --git a/src/goto-symex/postcondition.cpp b/src/goto-symex/postcondition.cpp index 003f0ac60a8..d290a6335b6 100644 --- a/src/goto-symex/postcondition.cpp +++ b/src/goto-symex/postcondition.cpp @@ -7,7 +7,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ #include -#include #include #include "goto_symex_state.h" diff --git a/src/goto-symex/rewrite_union.cpp b/src/goto-symex/rewrite_union.cpp index 26b9282dfdf..903ec267466 100644 --- a/src/goto-symex/rewrite_union.cpp +++ b/src/goto-symex/rewrite_union.cpp @@ -6,9 +6,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include #include #include -#include #include #include @@ -42,7 +42,7 @@ void rewrite_union( if(op_type.id()==ID_union) { - exprt offset=gen_zero(index_type()); + exprt offset=from_integer(0, index_type()); byte_extract_exprt tmp(byte_extract_id(), op, offset, expr.type()); expr=tmp; } @@ -50,7 +50,7 @@ void rewrite_union( else if(expr.id()==ID_union) { const union_exprt &union_expr=to_union_expr(expr); - exprt offset=gen_zero(index_type()); + exprt offset=from_integer(0, index_type()); side_effect_expr_nondett nondet(expr.type()); byte_update_exprt tmp( byte_update_id(), nondet, offset, union_expr.op()); diff --git a/src/goto-symex/symex_assign.cpp b/src/goto-symex/symex_assign.cpp index f251a1884ac..b8200280648 100644 --- a/src/goto-symex/symex_assign.cpp +++ b/src/goto-symex/symex_assign.cpp @@ -6,7 +6,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include #include #include diff --git a/src/goto-symex/symex_builtin_functions.cpp b/src/goto-symex/symex_builtin_functions.cpp index 19cfe1f7e5c..1eaf30353d3 100644 --- a/src/goto-symex/symex_builtin_functions.cpp +++ b/src/goto-symex/symex_builtin_functions.cpp @@ -8,7 +8,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include #include #include #include @@ -176,7 +175,7 @@ void goto_symext::symex_malloc( rhs.type()=pointer_typet(value_symbol.type.subtype()); index_exprt index_expr(value_symbol.type.subtype()); index_expr.array()=value_symbol.symbol_expr(); - index_expr.index()=gen_zero(index_type()); + index_expr.index()=from_integer(0, index_type()); rhs.op0()=index_expr; } else @@ -498,7 +497,9 @@ void goto_symext::symex_cpp_new( if(do_array) { exprt index_expr(ID_index, code.type().subtype()); - index_expr.copy_to_operands(symbol.symbol_expr(), gen_zero(index_type())); + index_expr.copy_to_operands( + symbol.symbol_expr(), + from_integer(0, index_type())); rhs.move_to_operands(index_expr); } else diff --git a/src/goto-symex/symex_clean_expr.cpp b/src/goto-symex/symex_clean_expr.cpp index 338854922b3..a88075d4a62 100644 --- a/src/goto-symex/symex_clean_expr.cpp +++ b/src/goto-symex/symex_clean_expr.cpp @@ -6,8 +6,8 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include #include -#include #include #include @@ -78,7 +78,7 @@ void goto_symext::process_array_expr_rec( byte_extract_exprt be(byte_extract_id()); be.type()=type; be.op()=expr; - be.offset()=gen_zero(index_type()); + be.offset()=from_integer(0, index_type()); expr.swap(be); } diff --git a/src/goto-symex/symex_dead.cpp b/src/goto-symex/symex_dead.cpp index cb954a6fad0..ec9440bc5e8 100644 --- a/src/goto-symex/symex_dead.cpp +++ b/src/goto-symex/symex_dead.cpp @@ -8,7 +8,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include #include #include diff --git a/src/goto-symex/symex_decl.cpp b/src/goto-symex/symex_decl.cpp index 60a94a610de..d46c449c755 100644 --- a/src/goto-symex/symex_decl.cpp +++ b/src/goto-symex/symex_decl.cpp @@ -8,7 +8,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include #include #include diff --git a/src/goto-symex/symex_dereference.cpp b/src/goto-symex/symex_dereference.cpp index dbe5e9aed3c..2234f7d8eaa 100644 --- a/src/goto-symex/symex_dereference.cpp +++ b/src/goto-symex/symex_dereference.cpp @@ -6,7 +6,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include #include #include #include @@ -150,7 +149,7 @@ exprt goto_symext::address_arithmetic( for(const typet *t=&(ns.follow(a.type().subtype())); t->id()==ID_array && !base_type_eq(expr.type(), *t, ns); t=&(ns.follow(*t).subtype())) - a.object()=index_exprt(a.object(), gen_zero(index_type())); + a.object()=index_exprt(a.object(), from_integer(0, index_type())); } // do (expr.type() *)(((char *)op)+offset) @@ -224,7 +223,7 @@ exprt goto_symext::address_arithmetic( // turn &array into &array[0] if(ns.follow(result.type()).id()==ID_array && !keep_array) - result=index_exprt(result, gen_zero(index_type())); + result=index_exprt(result, from_integer(0, index_type())); // handle field-sensitive SSA symbol mp_integer offset=0; @@ -360,9 +359,11 @@ void goto_symext::dereference_rec( pointer_typet(to_address_of_expr(tc_op).object().type().subtype()), ns)) { - expr=address_of_exprt(index_exprt( - to_address_of_expr(tc_op).object(), - gen_zero(index_type())));; + expr= + address_of_exprt( + index_exprt( + to_address_of_expr(tc_op).object(), + from_integer(0, index_type()))); dereference_rec(expr, state, guard, write); } diff --git a/src/goto-symex/symex_function_call.cpp b/src/goto-symex/symex_function_call.cpp index 16574d5679f..b333ebbc3a1 100644 --- a/src/goto-symex/symex_function_call.cpp +++ b/src/goto-symex/symex_function_call.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -135,7 +134,7 @@ void goto_symext::parameter_assignments( byte_extract_exprt( byte_extract_id(), rhs, - gen_zero(index_type()), + from_integer(0, index_type()), parameter_type); } else diff --git a/src/goto-symex/symex_goto.cpp b/src/goto-symex/symex_goto.cpp index 17149677965..2c64e62b15e 100644 --- a/src/goto-symex/symex_goto.cpp +++ b/src/goto-symex/symex_goto.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include "goto_symex.h" diff --git a/src/goto-symex/symex_other.cpp b/src/goto-symex/symex_other.cpp index 87f5428fe68..315447093ea 100644 --- a/src/goto-symex/symex_other.cpp +++ b/src/goto-symex/symex_other.cpp @@ -8,7 +8,7 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include +#include #include #include #include @@ -116,7 +116,7 @@ void goto_symext::symex_other( byte_extract_exprt be(byte_extract_id()); be.type()=clean_code.op0().type(); be.op()=clean_code.op1(); - be.offset()=gen_zero(index_type()); + be.offset()=from_integer(0, index_type()); clean_code.op1()=be; } diff --git a/src/goto-symex/symex_target_equation.cpp b/src/goto-symex/symex_target_equation.cpp index 8b2aecfbcaa..66b9a87e9af 100644 --- a/src/goto-symex/symex_target_equation.cpp +++ b/src/goto-symex/symex_target_equation.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 08f3b185425..a9a67ddd556 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -16,7 +16,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include + #include #include @@ -1390,7 +1390,7 @@ codet java_bytecode_convert_methodt::convert_instructions( code_ifthenelset code_branch; code_branch.cond()= - binary_relation_exprt(op[0], id, gen_zero(op[0].type())); + binary_relation_exprt(op[0], id, from_integer(0, op[0].type())); code_branch.cond().add_source_location()=i_it->source_location; code_branch.cond().add_source_location().set_function(method_id); code_branch.then_case()=code_gotot(label(number)); @@ -1561,7 +1561,7 @@ codet java_bytecode_convert_methodt::convert_instructions( nan_result, if_exprt( ieee_float_equal_exprt(op[0], op[1]), - gen_zero(result_type), + from_integer(0, result_type), if_exprt( binary_relation_exprt(op[0], ID_lt, op[1]), minus_one, diff --git a/src/java_bytecode/java_entry_point.cpp b/src/java_bytecode/java_entry_point.cpp index e2c71735fec..d4d40beff3b 100644 --- a/src/java_bytecode/java_entry_point.cpp +++ b/src/java_bytecode/java_entry_point.cpp @@ -15,7 +15,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include #include @@ -63,7 +62,8 @@ static void create_initialize(symbol_tablet &symbol_table) symbol_exprt rounding_mode= ns.lookup(CPROVER_PREFIX "rounding_mode").symbol_expr(); - init_code.add(code_assignt(rounding_mode, gen_zero(rounding_mode.type()))); + init_code.add( + code_assignt(rounding_mode, from_integer(0, rounding_mode.type()))); initialize.value=init_code; @@ -241,10 +241,11 @@ exprt::operandst java_build_arguments( // record as an input codet input(ID_input); input.operands().resize(2); - input.op0()=address_of_exprt( - index_exprt( - string_constantt(p_symbol.base_name), - from_integer(0, index_type()))); + input.op0()= + address_of_exprt( + index_exprt( + string_constantt(p_symbol.base_name), + from_integer(0, index_type()))); input.op1()=main_arguments[param_number]; input.add_source_location()=function.location; diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index f8f3d98748f..e7ab2f1a658 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -17,7 +17,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include @@ -302,7 +301,7 @@ void java_object_factoryt::gen_nondet_init( } else if(name=="@lock") { - code_assignt code(me, gen_zero(me.type())); + code_assignt code(me, from_integer(0, me.type())); code.add_source_location()=loc; init_code.copy_to_operands(code); } diff --git a/src/jsil/jsil_entry_point.cpp b/src/jsil/jsil_entry_point.cpp index 2963ebb514f..c6f9c26abe8 100644 --- a/src/jsil/jsil_entry_point.cpp +++ b/src/jsil/jsil_entry_point.cpp @@ -6,12 +6,12 @@ Author: Michael Tautschnig, tautschn@amazon.com \*******************************************************************/ +#include #include #include #include #include #include -#include #include @@ -49,7 +49,7 @@ static void create_initialize(symbol_tablet &symbol_table) symbol_exprt rounding_mode= ns.lookup(CPROVER_PREFIX "rounding_mode").symbol_expr(); - code_assignt a(rounding_mode, gen_zero(rounding_mode.type())); + code_assignt a(rounding_mode, from_integer(0, rounding_mode.type())); init_code.add(a); initialize.value=init_code; diff --git a/src/linking/static_lifetime_init.cpp b/src/linking/static_lifetime_init.cpp index e008d64c612..8e7d475766c 100644 --- a/src/linking/static_lifetime_init.cpp +++ b/src/linking/static_lifetime_init.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -118,7 +117,7 @@ bool static_lifetime_init( assert(it!=symbol_table.symbols.end()); it->second.type=type; - it->second.type.set(ID_size, gen_one(size_type())); + it->second.type.set(ID_size, from_integer(1, size_type())); } if(type.id()==ID_incomplete_struct || diff --git a/src/linking/zero_initializer.cpp b/src/linking/zero_initializer.cpp index 24d483cb4c9..d652427059d 100644 --- a/src/linking/zero_initializer.cpp +++ b/src/linking/zero_initializer.cpp @@ -110,7 +110,7 @@ exprt zero_initializert::zero_initializer_rec( array_exprt value(array_type); value.type().id(ID_array); - value.type().set(ID_size, gen_zero(size_type())); + value.type().set(ID_size, from_integer(0, size_type())); value.add_source_location()=source_location; return value; } diff --git a/src/musketeer/fence_shared.cpp b/src/musketeer/fence_shared.cpp index c3557d712af..9e3a3c580f1 100644 --- a/src/musketeer/fence_shared.cpp +++ b/src/musketeer/fence_shared.cpp @@ -14,7 +14,6 @@ Author: Vincent Nimal #include #include -#include #include #include #include diff --git a/src/musketeer/fencer.cpp b/src/musketeer/fencer.cpp index bbcb1db1d2d..71587267e8f 100644 --- a/src/musketeer/fencer.cpp +++ b/src/musketeer/fencer.cpp @@ -7,7 +7,6 @@ Author: Vincent Nimal \*******************************************************************/ #include -#include #include #include diff --git a/src/musketeer/pensieve.cpp b/src/musketeer/pensieve.cpp index 42ae7b61a49..bea0fab3525 100644 --- a/src/musketeer/pensieve.cpp +++ b/src/musketeer/pensieve.cpp @@ -7,7 +7,6 @@ Author: Vincent Nimal \*******************************************************************/ #include -#include #include #include diff --git a/src/path-symex/path_symex.cpp b/src/path-symex/path_symex.cpp index a646e45409c..f3cffd498bb 100644 --- a/src/path-symex/path_symex.cpp +++ b/src/path-symex/path_symex.cpp @@ -280,7 +280,7 @@ void path_symext::symex_malloc( rhs.type()=pointer_typet(value_symbol.type.subtype()); index_exprt index_expr(value_symbol.type.subtype()); index_expr.array()=value_symbol.symbol_expr(); - index_expr.index()=gen_zero(index_type()); + index_expr.index()=from_integer(0, index_type()); rhs.op0()=index_expr; } else @@ -510,7 +510,7 @@ void path_symext::assign_rec( else if(compound_type.id()==ID_union) { // rewrite into byte_extract, and do again - exprt offset=gen_zero(index_type()); + exprt offset=from_integer(0, index_type()); byte_extract_exprt new_lhs(byte_update_id(), struct_op, offset, ssa_rhs.type()); diff --git a/src/path-symex/path_symex_state.cpp b/src/path-symex/path_symex_state.cpp index 3cd0cd0d269..4f422172374 100644 --- a/src/path-symex/path_symex_state.cpp +++ b/src/path-symex/path_symex_state.cpp @@ -8,7 +8,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include diff --git a/src/pointer-analysis/dereference.cpp b/src/pointer-analysis/dereference.cpp index ca648722b04..a256a5e39d9 100644 --- a/src/pointer-analysis/dereference.cpp +++ b/src/pointer-analysis/dereference.cpp @@ -52,7 +52,7 @@ exprt dereferencet::operator()(const exprt &pointer) return dereference_rec( pointer, - gen_zero(index_type()), // offset + from_integer(0, index_type()), // offset type); } @@ -225,7 +225,7 @@ exprt dereferencet::dereference_rec( if(to_constant_expr(address).get_value()==ID_NULL) // NULL { // we turn this into (type *)0 - exprt zero=gen_zero(index_type()); + exprt zero=from_integer(0, index_type()); return dereference_rec( typecast_exprt(zero, address.type()), offset, type); } diff --git a/src/pointer-analysis/value_set.cpp b/src/pointer-analysis/value_set.cpp index 500dbd23bcf..4a22fc40acb 100644 --- a/src/pointer-analysis/value_set.cpp +++ b/src/pointer-analysis/value_set.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -1136,7 +1135,7 @@ void value_sett::get_reference_set_rec( { index_exprt index_expr(expr.type()); index_expr.array()=object; - index_expr.index()=gen_zero(index_type()); + index_expr.index()=from_integer(0, index_type()); // adjust type? if(ns.follow(object.type())!=array_type) diff --git a/src/pointer-analysis/value_set_dereference.cpp b/src/pointer-analysis/value_set_dereference.cpp index d9e8af80fc2..c69e6feda73 100644 --- a/src/pointer-analysis/value_set_dereference.cpp +++ b/src/pointer-analysis/value_set_dereference.cpp @@ -723,7 +723,7 @@ void value_set_dereferencet::bounds_check( } else { - exprt zero=gen_zero(expr.index().type()); + exprt zero=from_integer(0, expr.index().type()); if(zero.is_nil()) throw "no zero constant of index type "+ @@ -878,7 +878,7 @@ bool value_set_dereferencet::memory_model_conversion( if(options.get_bool_option("pointer-check")) { - equal_exprt offset_not_zero(offset, gen_zero(offset.type())); + equal_exprt offset_not_zero(offset, from_integer(0, offset.type())); offset_not_zero.make_not(); guardt tmp_guard(guard); @@ -972,8 +972,8 @@ bool value_set_dereferencet::memory_model_bytes( if(!offset.is_zero()) { binary_relation_exprt - offset_lower_bound(offset, ID_lt, - gen_zero(offset.type())); + offset_lower_bound( + offset, ID_lt, from_integer(0, offset.type())); guardt tmp_guard(guard); tmp_guard.add(offset_lower_bound); diff --git a/src/pointer-analysis/value_set_fi.cpp b/src/pointer-analysis/value_set_fi.cpp index e1157b49324..ed1de7872ac 100644 --- a/src/pointer-analysis/value_set_fi.cpp +++ b/src/pointer-analysis/value_set_fi.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -1029,7 +1028,7 @@ void value_set_fit::get_reference_set_sharing_rec( exprt index_expr(ID_index, expr.type()); index_expr.operands().resize(2); index_expr.op0()=object; - index_expr.op1()=gen_zero(index_type()); + index_expr.op1()=from_integer(0, index_type()); // adjust type? if(object.type().id()!="#REF#" && diff --git a/src/pointer-analysis/value_set_fivr.cpp b/src/pointer-analysis/value_set_fivr.cpp index c6c5c8920d2..3f34d861d89 100644 --- a/src/pointer-analysis/value_set_fivr.cpp +++ b/src/pointer-analysis/value_set_fivr.cpp @@ -12,7 +12,6 @@ Author: Daniel Kroening, kroening@kroening.com, #include #include -#include #include #include #include @@ -1152,7 +1151,7 @@ void value_set_fivrt::get_reference_set_sharing_rec( exprt index_expr(ID_index, expr.type()); index_expr.operands().resize(2); index_expr.op0()=object; - index_expr.op1()=gen_zero(index_type()); + index_expr.op1()=from_integer(0, index_type()); // adjust type? if(object.type().id()!="#REF#" && diff --git a/src/pointer-analysis/value_set_fivrns.cpp b/src/pointer-analysis/value_set_fivrns.cpp index 10e7c94006a..574942a73d7 100644 --- a/src/pointer-analysis/value_set_fivrns.cpp +++ b/src/pointer-analysis/value_set_fivrns.cpp @@ -12,7 +12,6 @@ Author: Daniel Kroening, kroening@kroening.com, #include #include -#include #include #include #include @@ -817,7 +816,7 @@ void value_set_fivrnst::get_reference_set_rec( exprt index_expr(ID_index, expr.type()); index_expr.operands().resize(2); index_expr.op0()=object; - index_expr.op1()=gen_zero(index_type()); + index_expr.op1()=from_integer(0, index_type()); // adjust type? if(ns.follow(object.type())!=array_type) diff --git a/src/solvers/cvc/cvc_conv.cpp b/src/solvers/cvc/cvc_conv.cpp index 6e01448d5e2..55c1815b182 100644 --- a/src/solvers/cvc/cvc_conv.cpp +++ b/src/solvers/cvc/cvc_conv.cpp @@ -14,7 +14,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include #include @@ -349,7 +348,7 @@ void cvc_convt::convert_typecast_expr(const exprt &expr) { convert_expr(op); out << "/="; - convert_expr(gen_zero(op.type())); + convert_expr(from_integer(0, op.type())); } else { diff --git a/src/solvers/dplib/dplib_conv.cpp b/src/solvers/dplib/dplib_conv.cpp index 58b7702f927..ae69746fc2e 100644 --- a/src/solvers/dplib/dplib_conv.cpp +++ b/src/solvers/dplib/dplib_conv.cpp @@ -13,7 +13,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include #include @@ -393,7 +392,7 @@ void dplib_convt::convert_dplib_expr(const exprt &expr) { convert_dplib_expr(op); dplib_prop.out << "/="; - convert_dplib_expr(gen_zero(op.type())); + convert_dplib_expr(from_integer(0, op.type())); } else { diff --git a/src/solvers/flattening/boolbv_member.cpp b/src/solvers/flattening/boolbv_member.cpp index a5a09a4239a..c5c0a697e1e 100644 --- a/src/solvers/flattening/boolbv_member.cpp +++ b/src/solvers/flattening/boolbv_member.cpp @@ -7,7 +7,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ #include -#include #include #include @@ -37,7 +36,7 @@ bvt boolbvt::convert_member(const member_exprt &expr) return convert_bv( byte_extract_exprt(byte_extract_id(), struct_op, - gen_zero(integer_typet()), + from_integer(0, integer_typet()), expr.type())); } else if(struct_op_type.id()==ID_struct) diff --git a/src/solvers/flattening/boolbv_update.cpp b/src/solvers/flattening/boolbv_update.cpp index 0d75a0f3eb8..2b485781f6b 100644 --- a/src/solvers/flattening/boolbv_update.cpp +++ b/src/solvers/flattening/boolbv_update.cpp @@ -11,7 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include diff --git a/src/solvers/flattening/boolbv_with.cpp b/src/solvers/flattening/boolbv_with.cpp index 50ac35813f0..2c5a2f5e556 100644 --- a/src/solvers/flattening/boolbv_with.cpp +++ b/src/solvers/flattening/boolbv_with.cpp @@ -8,7 +8,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include diff --git a/src/solvers/flattening/bv_pointers.cpp b/src/solvers/flattening/bv_pointers.cpp index e23dccace5e..673a81f6e5a 100644 --- a/src/solvers/flattening/bv_pointers.cpp +++ b/src/solvers/flattening/bv_pointers.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include diff --git a/src/solvers/floatbv/float_bv.cpp b/src/solvers/floatbv/float_bv.cpp index 33f46b51c0f..99bfc7af317 100644 --- a/src/solvers/floatbv/float_bv.cpp +++ b/src/solvers/floatbv/float_bv.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include @@ -131,8 +130,7 @@ Function: float_bvt::abs exprt float_bvt::abs(const exprt &op, const ieee_float_spect &spec) { // we mask away the sign bit, which is the most significand bit - std::string mask_str; - mask_str.resize(spec.width(), '1'); + std::string mask_str(spec.width(), '1'); mask_str[0]='0'; constant_exprt mask(mask_str, op.type()); @@ -155,8 +153,7 @@ Function: float_bvt::negation exprt float_bvt::negation(const exprt &op, const ieee_float_spect &spec) { // we flip the sign bit with an xor - std::string mask_str; - mask_str.resize(spec.width(), '0'); + std::string mask_str(spec.width(), '0'); mask_str[0]='1'; constant_exprt mask(mask_str, op.type()); @@ -218,15 +215,15 @@ exprt float_bvt::is_zero( const floatbv_typet &type=to_floatbv_type(src.type()); std::size_t width=type.get_width(); - std::string mask_str; - mask_str.resize(width, '1'); + std::string mask_str(width, '1'); mask_str[0]='0'; constant_exprt mask(mask_str, src.type()); - return equal_exprt( - bitand_exprt(src, mask), - gen_zero(src.type())); + ieee_floatt z(type); + z.make_zero(); + + return equal_exprt(bitand_exprt(src, mask), z.to_expr()); } /*******************************************************************\ @@ -485,7 +482,7 @@ exprt float_bvt::to_integer( exprt exponent_sign=sign_exprt(unpacked.exponent); result= - if_exprt(exponent_sign, gen_zero(result.type()), result); + if_exprt(exponent_sign, from_integer(0, result.type()), result); // chop out the right number of bits from the result typet result_type= @@ -750,9 +747,12 @@ exprt float_bvt::add_sub( // 2. Subnormals mean that addition or subtraction can't round to 0, // thus we can perform this test now // 3. The rules for sign are different for zero - result.zero = and_exprt( + result.zero= + and_exprt( not_exprt(or_exprt(result.infinity, result.NaN)), - equal_exprt(result.fraction, gen_zero(result.fraction.type()))); + equal_exprt( + result.fraction, + from_integer(0, result.fraction.type()))); // sign exprt add_sub_sign= @@ -811,7 +811,8 @@ exprt float_bvt::limit_distance( exprt upper_bits= extractbits_exprt(dist, dist_width-1, nb_bits, unsignedbv_typet(dist_width-nb_bits)); - exprt upper_bits_zero=equal_exprt(upper_bits, gen_zero(upper_bits.type())); + exprt upper_bits_zero= + equal_exprt(upper_bits, from_integer(0, upper_bits.type())); exprt lower_bits= extractbits_exprt(dist, nb_bits-1, 0, @@ -864,7 +865,8 @@ exprt float_bvt::mul( // Adjust exponent; we are thowing in an extra fraction bit, // it has been extended above. - result.exponent=plus_exprt(added_exponent, gen_one(new_exponent_type)); + result.exponent= + plus_exprt(added_exponent, from_integer(1, new_exponent_type)); // new sign result.sign=notequal_exprt(unpacked1.sign, unpacked2.sign); @@ -935,7 +937,7 @@ exprt float_bvt::div( rem=mod_exprt(fraction1, fraction2); // is there a remainder? - exprt have_remainder=notequal_exprt(rem, gen_zero(rem.type())); + exprt have_remainder=notequal_exprt(rem, from_integer(0, rem.type())); // we throw this into the result, as least-significand bit, // to get the right rounding decision @@ -981,8 +983,11 @@ exprt float_bvt::div( exprt force_zero= and_exprt(not_exprt(unpacked1.NaN), unpacked2.infinity); - result.fraction=if_exprt(force_zero, - gen_zero(result.fraction.type()), result.fraction); + result.fraction= + if_exprt( + force_zero, + from_integer(0, result.fraction.type()), + result.fraction); return rounder(result, rm, spec); } @@ -1221,7 +1226,7 @@ void float_bvt::normalization_shift( if(exponent_bits=0; d--) { @@ -1232,7 +1237,7 @@ void float_bvt::normalization_shift( const exprt prefix= extractbits_exprt(fraction, fraction_bits-1, fraction_bits-distance, unsignedbv_typet(distance)); - exprt prefix_is_zero=equal_exprt(prefix, gen_zero(prefix.type())); + exprt prefix_is_zero=equal_exprt(prefix, from_integer(0, prefix.type())); // If so, shift the zeros out left by 'distance'. // Otherwise, leave as is. @@ -1296,9 +1301,10 @@ void float_bvt::denormalization_shift( from_integer(-bias+1, exponent.type()), exponent); // use sign bit - exprt denormal=and_exprt( - not_exprt(sign_exprt(distance)), - notequal_exprt(distance, gen_zero(distance.type()))); + exprt denormal= + and_exprt( + not_exprt(sign_exprt(distance)), + notequal_exprt(distance, from_integer(0, distance.type()))); #if 1 // Care must be taken to not loose information required for the @@ -1438,7 +1444,7 @@ exprt float_bvt::fraction_rounding_decision( exprt tail= extractbits_exprt(fraction, extra_bits-2, 0, unsignedbv_typet(extra_bits-2+1)); - sticky_bit=notequal_exprt(tail, gen_zero(tail.type())); + sticky_bit=notequal_exprt(tail, from_integer(0, tail.type())); } // the rounding bit is the last extra bit @@ -1578,10 +1584,12 @@ void float_bvt::round_fraction( // In case of an overflow or subnormal to normal conversion, // the exponent has to be incremented. result.exponent= - plus_exprt(result.exponent, - if_exprt(or_exprt(overflow, subnormal_to_normal), - gen_one(result.exponent.type()), - gen_zero(result.exponent.type()))); + plus_exprt( + result.exponent, + if_exprt( + or_exprt(overflow, subnormal_to_normal), + from_integer(1, result.exponent.type()), + from_integer(0, result.exponent.type()))); // post normalization of the fraction // In the case of overflow, set the MSB to 1 @@ -1590,7 +1598,7 @@ void float_bvt::round_fraction( result.fraction, if_exprt(overflow, from_integer(1<<(fraction_size-1), result.fraction.type()), - gen_zero(result.fraction.type()))); + from_integer(0, result.fraction.type()))); #endif } } @@ -1642,7 +1650,9 @@ void float_bvt::round_exponent( exprt exponent_too_large= and_exprt( binary_relation_exprt(old_exponent, ID_ge, max_exponent), - notequal_exprt(result.fraction, gen_zero(result.fraction.type()))); + notequal_exprt( + result.fraction, + from_integer(0, result.fraction.type()))); #if 1 // Directed rounding modes round overflow to the maximum normal @@ -1897,9 +1907,11 @@ exprt float_bvt::sticky_right_shift( exprt dist_bit= extractbit_exprt(dist, stage); - sticky=or_exprt( - and_exprt(dist_bit, - notequal_exprt(lost_bits, gen_zero(lost_bits.type()))), + sticky= + or_exprt( + and_exprt( + dist_bit, + notequal_exprt(lost_bits, from_integer(0, lost_bits.type()))), sticky); result=if_exprt(dist_bit, tmp, result); diff --git a/src/solvers/smt1/smt1_conv.cpp b/src/solvers/smt1/smt1_conv.cpp index b769d3b052e..e9127b15e77 100644 --- a/src/solvers/smt1/smt1_conv.cpp +++ b/src/solvers/smt1/smt1_conv.cpp @@ -9,7 +9,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include #include @@ -392,7 +391,7 @@ void smt1_convt::convert_address_of_rec( { // this is really pointer arithmetic exprt new_index_expr=expr; - new_index_expr.op1()=gen_zero(index.type()); + new_index_expr.op1()=from_integer(0, index.type()); exprt address_of_expr(ID_address_of, pointer_typet()); address_of_expr.type().subtype()=array.type().subtype(); diff --git a/src/solvers/smt2/smt2_conv.cpp b/src/solvers/smt2/smt2_conv.cpp index 870e3c5052f..b98cf9a9da5 100644 --- a/src/solvers/smt2/smt2_conv.cpp +++ b/src/solvers/smt2/smt2_conv.cpp @@ -648,7 +648,7 @@ void smt2_convt::convert_address_of_rec( { // this is really pointer arithmetic exprt new_index_expr=expr; - new_index_expr.op1()=gen_zero(index.type()); + new_index_expr.op1()=from_integer(0, index.type()); exprt address_of_expr(ID_address_of, pointer_typet()); address_of_expr.type().subtype()=array.type().subtype(); diff --git a/src/util/arith_tools.cpp b/src/util/arith_tools.cpp index 3334be4dcb4..7a99d385570 100644 --- a/src/util/arith_tools.cpp +++ b/src/util/arith_tools.cpp @@ -8,10 +8,13 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "arith_tools.h" +#include "fixedbv.h" +#include "ieee_float.h" #include "std_types.h" #include "std_expr.h" +#include "arith_tools.h" + /*******************************************************************\ Function: to_integer @@ -198,6 +201,20 @@ constant_exprt from_integer( result.set_value(integer2binary(int_value, width)); return result; } + else if(type_id==ID_fixedbv) + { + fixedbvt fixedbv; + fixedbv.spec=to_fixedbv_type(type); + fixedbv.from_integer(int_value); + return fixedbv.to_expr(); + } + else if(type_id==ID_floatbv) + { + ieee_floatt ieee_float; + ieee_float.spec=to_floatbv_type(type); + ieee_float.from_integer(int_value); + return ieee_float.to_expr(); + } { constant_exprt r; diff --git a/src/util/expr_util.cpp b/src/util/expr_util.cpp index b7034bda43c..577f59610d7 100644 --- a/src/util/expr_util.cpp +++ b/src/util/expr_util.cpp @@ -316,7 +316,10 @@ exprt is_not_zero( // Note that this returns a proper bool_typet(), not a C/C++ boolean. // To get a C/C++ boolean, add a further typecast. - const typet &src_type=ns.follow(src.type()); + const typet &src_type= + src.type().id()==ID_c_enum_tag? + ns.follow_tag(to_c_enum_tag_type(src.type())): + ns.follow(src.type()); if(src_type.id()==ID_bool) // already there return src; // do nothing @@ -324,7 +327,7 @@ exprt is_not_zero( irep_idt id= src_type.id()==ID_floatbv?ID_ieee_float_notequal:ID_notequal; - exprt zero=gen_zero(src_type); + exprt zero=from_integer(0, src_type); assert(zero.is_not_nil()); binary_exprt comparison(src, id, zero, bool_typet()); diff --git a/src/util/pointer_offset_size.cpp b/src/util/pointer_offset_size.cpp index a8dab9ab98e..370cc534ac7 100644 --- a/src/util/pointer_offset_size.cpp +++ b/src/util/pointer_offset_size.cpp @@ -268,7 +268,7 @@ exprt member_offset_expr( return member_offset_expr( to_struct_type(type), member_expr.get_component_name(), ns); else if(type.id()==ID_union) - return gen_zero(signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(0, signedbv_typet(config.ansi_c.pointer_width)); else return nil_exprt(); } @@ -292,7 +292,7 @@ exprt member_offset_expr( { const struct_typet::componentst &components=type.components(); - exprt result=gen_zero(signedbv_typet(config.ansi_c.pointer_width)); + exprt result=from_integer(0, signedbv_typet(config.ansi_c.pointer_width)); std::size_t bit_field_bits=0; for(struct_typet::componentst::const_iterator @@ -395,7 +395,7 @@ exprt size_of_expr( const struct_typet::componentst &components= struct_type.components(); - exprt result=gen_zero(signedbv_typet(config.ansi_c.pointer_width)); + exprt result=from_integer(0, signedbv_typet(config.ansi_c.pointer_width)); std::size_t bit_field_bits=0; for(struct_typet::componentst::const_iterator @@ -482,7 +482,7 @@ exprt size_of_expr( } else if(type.id()==ID_bool) { - return gen_one(signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(1, signedbv_typet(config.ansi_c.pointer_width)); } else if(type.id()==ID_pointer) { @@ -497,7 +497,7 @@ exprt size_of_expr( } else if(type.id()==ID_code) { - return gen_zero(signedbv_typet(config.ansi_c.pointer_width)); + return from_integer(0, signedbv_typet(config.ansi_c.pointer_width)); } else if(type.id()==ID_string) { diff --git a/src/util/pointer_predicates.cpp b/src/util/pointer_predicates.cpp index 732781878a2..1e1e285e01c 100644 --- a/src/util/pointer_predicates.cpp +++ b/src/util/pointer_predicates.cpp @@ -450,7 +450,7 @@ exprt object_lower_bound(const exprt &pointer) { exprt offset=pointer_offset(pointer); - exprt zero=gen_zero(offset.type()); + exprt zero=from_integer(0, offset.type()); assert(zero.is_not_nil()); return binary_relation_exprt(offset, ID_lt, zero); diff --git a/src/util/simplify_expr.cpp b/src/util/simplify_expr.cpp index 483c214855d..0bf81ed283d 100644 --- a/src/util/simplify_expr.cpp +++ b/src/util/simplify_expr.cpp @@ -236,7 +236,7 @@ bool simplify_exprt::simplify_typecast(exprt &expr) (expr_type.id()==ID_unsignedbv || expr_type.id()==ID_signedbv) && config.ansi_c.NULL_is_zero) { - exprt tmp=gen_zero(expr_type); + exprt tmp=from_integer(0, expr_type); expr.swap(tmp); return false; } @@ -516,13 +516,13 @@ bool simplify_exprt::simplify_typecast(exprt &expr) { if(operand.is_true()) { - expr=gen_one(expr_type); + expr=from_integer(1, expr_type); assert(expr.is_not_nil()); return false; } else if(operand.is_false()) { - expr=gen_zero(expr_type); + expr=from_integer(0, expr_type); assert(expr.is_not_nil()); return false; } @@ -1916,7 +1916,7 @@ bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr) el_size<=pointer_offset_bits(expr.op().op2().type(), ns)) { expr.op()=expr.op().op2(); - expr.offset()=gen_zero(expr.offset().type()); + expr.offset()=from_integer(0, expr.offset().type()); simplify_byte_extract(expr); diff --git a/src/util/simplify_expr_int.cpp b/src/util/simplify_expr_int.cpp index acc1c0453a7..ffb51d7a328 100644 --- a/src/util/simplify_expr_int.cpp +++ b/src/util/simplify_expr_int.cpp @@ -110,7 +110,7 @@ bool simplify_exprt::simplify_mult(exprt &expr) if(it->is_zero() && it->type().id()!=ID_floatbv) { - expr=gen_zero(expr.type()); + expr=from_integer(0, expr.type()); return false; } @@ -353,7 +353,7 @@ bool simplify_exprt::simplify_mod(exprt &expr) if((ok1 && int_value1==1) || (ok0 && int_value0==0)) { - expr=gen_zero(expr.type()); + expr=from_integer(0, expr.type()); return false; } @@ -469,7 +469,8 @@ bool simplify_exprt::simplify_plus(exprt &expr) { if(!const_sum->sum(*it)) { - *it=gen_zero(it->type()); + *it=from_integer(0, it->type()); + assert(it->is_not_nil()); result=false; } } @@ -498,8 +499,9 @@ bool simplify_exprt::simplify_plus(exprt &expr) if(itm!=expr_map.end()) { - *(itm->second)=gen_zero(expr.type()); - *it=gen_zero(expr.type()); + *(itm->second)=from_integer(0, expr.type()); + *it=from_integer(0, expr.type()); + assert(it->is_not_nil()); expr_map.erase(itm); result=false; } @@ -525,7 +527,8 @@ bool simplify_exprt::simplify_plus(exprt &expr) if(operands.empty()) { - expr=gen_zero(expr.type()); + expr=from_integer(0, expr.type()); + assert(expr.is_not_nil()); return false; } else if(operands.size()==1) @@ -599,12 +602,10 @@ bool simplify_exprt::simplify_minus(exprt &expr) if(operands[0]==operands[1]) { - exprt zero=gen_zero(expr.type()); - if(zero.is_not_nil()) - { - expr=zero; - return false; - } + exprt zero=from_integer(0, expr.type()); + assert(zero.is_not_nil()); + expr=zero; + return false; } } @@ -985,7 +986,7 @@ bool simplify_exprt::simplify_shifts(exprt &expr) // this is to guard against large values of distance if(distance>=width) { - expr=gen_zero(expr.type()); + expr=from_integer(0, expr.type()); return false; } else if(distance>=0) @@ -1010,7 +1011,7 @@ bool simplify_exprt::simplify_shifts(exprt &expr) // this is to guard against large values of distance if(distance>=width) { - expr=gen_zero(expr.type()); + expr=from_integer(0, expr.type()); return false; } else if(distance>=0) @@ -1589,8 +1590,8 @@ bool simplify_exprt::eliminate_common_addends( op0.type().id()!=ID_complex) { // elimination! - op0=gen_zero(op0.type()); - op1=gen_zero(op1.type()); + op0=from_integer(0, op0.type()); + op1=from_integer(0, op1.type()); return false; } } @@ -1823,7 +1824,7 @@ bool simplify_exprt::simplify_inequality_constant(exprt &expr) exprt op=expr.op0().op0(); expr.op0().swap(op); if(expr.op0().type().id()!=ID_pointer) - expr.op1()=gen_zero(expr.op0().type()); + expr.op1()=from_integer(0, expr.op0().type()); else expr.op1().type()=expr.op0().type(); simplify_inequality(expr); // do again! @@ -1854,7 +1855,8 @@ bool simplify_exprt::simplify_inequality_constant(exprt &expr) if(!to_integer(*it, i)) { constant+=i; - *it=gen_zero(it->type()); + *it=from_integer(0, it->type()); + assert(it->is_not_nil()); changed=true; } } diff --git a/src/util/simplify_expr_pointer.cpp b/src/util/simplify_expr_pointer.cpp index ae5a0f60fd7..5e0d7a502fb 100644 --- a/src/util/simplify_expr_pointer.cpp +++ b/src/util/simplify_expr_pointer.cpp @@ -217,7 +217,7 @@ bool simplify_exprt::simplify_address_of(exprt &expr) // we normalize &a[i] to (&a[0])+i exprt offset; offset.swap(index_expr.op1()); - index_expr.op1()=gen_zero(offset.type()); + index_expr.op1()=from_integer(0, offset.type()); exprt addition(ID_plus, expr.type()); addition.move_to_operands(expr, offset); @@ -412,7 +412,7 @@ bool simplify_exprt::simplify_pointer_offset(exprt &expr) else if(ptr.id()==ID_constant && ptr.get(ID_value)==ID_NULL) { - expr=gen_zero(expr.type()); + expr=from_integer(0, expr.type()); simplify_node(expr); From 230dc50c55d76a6fb0cc50b4941bc8b066e51773 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 16 Jan 2017 08:04:35 -0500 Subject: [PATCH 108/166] Use null_pointer_exprt instead of gen_zero --- src/analyses/goto_check.cpp | 17 ++++++++++++----- src/cpp/cpp_typecheck_virtual_table.cpp | 3 +-- .../java_bytecode_convert_method.cpp | 6 +++--- src/java_bytecode/java_types.cpp | 2 +- src/java_bytecode/java_types.h | 2 +- src/util/arith_tools.cpp | 6 +----- src/util/simplify_expr.cpp | 3 +-- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/analyses/goto_check.cpp b/src/analyses/goto_check.cpp index e5c1ec0290a..aa22aa72563 100644 --- a/src/analyses/goto_check.cpp +++ b/src/analyses/goto_check.cpp @@ -972,7 +972,8 @@ void goto_checkt::pointer_validity_check( return; const exprt &pointer=expr.op0(); - const typet &pointer_type=to_pointer_type(ns.follow(pointer.type())); + const pointer_typet &pointer_type= + to_pointer_type(ns.follow(pointer.type())); assert(base_type_eq(pointer_type.subtype(), expr.type(), ns)); @@ -986,7 +987,7 @@ void goto_checkt::pointer_validity_check( { if(flags.is_unknown() || flags.is_null()) { - notequal_exprt not_eq_null(pointer, gen_zero(pointer.type())); + notequal_exprt not_eq_null(pointer, null_pointer_exprt(pointer_type)); add_guarded_claim( not_eq_null, @@ -1612,7 +1613,9 @@ void goto_checkt::goto_check(goto_functiont &goto_function) if(flags.is_unknown() || flags.is_null()) { - notequal_exprt not_eq_null(pointer, gen_zero(pointer.type())); + notequal_exprt not_eq_null( + pointer, + null_pointer_exprt(to_pointer_type(pointer.type()))); add_guarded_claim( not_eq_null, @@ -1651,7 +1654,9 @@ void goto_checkt::goto_check(goto_functiont &goto_function) if(pointer.type().subtype().get(ID_identifier)!="java::java.lang.AssertionError") { - notequal_exprt not_eq_null(pointer, gen_zero(pointer.type())); + notequal_exprt not_eq_null( + pointer, + null_pointer_exprt(to_pointer_type(pointer.type()))); add_guarded_claim( not_eq_null, @@ -1718,7 +1723,9 @@ void goto_checkt::goto_check(goto_functiont &goto_function) source_locationt source_location; source_location.set_function(i.function); - equal_exprt eq(leak_expr, gen_zero(ns.follow(leak.type))); + equal_exprt eq( + leak_expr, + null_pointer_exprt(to_pointer_type(leak.type))); add_guarded_claim( eq, "dynamically allocated memory never freed", diff --git a/src/cpp/cpp_typecheck_virtual_table.cpp b/src/cpp/cpp_typecheck_virtual_table.cpp index 74efcad31c9..b2c18974613 100644 --- a/src/cpp/cpp_typecheck_virtual_table.cpp +++ b/src/cpp/cpp_typecheck_virtual_table.cpp @@ -47,8 +47,7 @@ void cpp_typecheckt::do_virtual_table(const symbolt &symbol) if(compo.get_bool("is_pure_virtual")) { pointer_typet pointer_type(code_type); - e = gen_zero(pointer_type); - assert(e.is_not_nil()); + e=null_pointer_exprt(pointer_type); value_map[compo.get("virtual_name")] = e; } else diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index a9a67ddd556..331a1012d9e 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -943,7 +943,7 @@ codet java_bytecode_convert_methodt::convert_instructions( if(statement=="aconst_null") { assert(results.size()==1); - results[0]=gen_zero(java_reference_type(void_typet())); + results[0]=null_pointer_exprt(java_reference_type(void_typet())); } else if(statement=="athrow") { @@ -1407,7 +1407,7 @@ codet java_bytecode_convert_methodt::convert_instructions( assert(op.size()==1 && results.empty()); code_ifthenelset code_branch; const typecast_exprt lhs(op[0], pointer_typet(empty_typet())); - const exprt rhs(gen_zero(lhs.type())); + const exprt rhs(null_pointer_exprt(to_pointer_type(lhs.type()))); code_branch.cond()=binary_relation_exprt(lhs, ID_notequal, rhs); code_branch.then_case()=code_gotot(label(number)); code_branch.then_case().add_source_location()=i_it->source_location; @@ -1421,7 +1421,7 @@ codet java_bytecode_convert_methodt::convert_instructions( irep_idt number=to_constant_expr(arg0).get_value(); code_ifthenelset code_branch; const typecast_exprt lhs(op[0], pointer_typet(empty_typet())); - const exprt rhs(gen_zero(lhs.type())); + const exprt rhs(null_pointer_exprt(to_pointer_type(lhs.type()))); code_branch.cond()=binary_relation_exprt(lhs, ID_equal, rhs); code_branch.then_case()=code_gotot(label(number)); code_branch.then_case().add_source_location()=i_it->source_location; diff --git a/src/java_bytecode/java_types.cpp b/src/java_bytecode/java_types.cpp index cd3d23b22bd..de89fc0e209 100644 --- a/src/java_bytecode/java_types.cpp +++ b/src/java_bytecode/java_types.cpp @@ -183,7 +183,7 @@ Function: java_reference_type \*******************************************************************/ -typet java_reference_type(const typet &subtype) +reference_typet java_reference_type(const typet &subtype) { return reference_typet(subtype); } diff --git a/src/java_bytecode/java_types.h b/src/java_bytecode/java_types.h index 41f68bdda01..e283a5acf23 100644 --- a/src/java_bytecode/java_types.h +++ b/src/java_bytecode/java_types.h @@ -20,7 +20,7 @@ typet java_char_type(); typet java_float_type(); typet java_double_type(); typet java_boolean_type(); -typet java_reference_type(const typet &subtype); +reference_typet java_reference_type(const typet &subtype); symbol_typet java_classname(const std::string &); pointer_typet java_array_type(const char subtype); diff --git a/src/util/arith_tools.cpp b/src/util/arith_tools.cpp index 7a99d385570..0957cf41ab5 100644 --- a/src/util/arith_tools.cpp +++ b/src/util/arith_tools.cpp @@ -188,11 +188,7 @@ constant_exprt from_integer( else if(type_id==ID_pointer) { if(int_value==0) - { - constant_exprt result(type); - result.set_value(ID_NULL); - return result; - } + return null_pointer_exprt(to_pointer_type(type)); } else if(type_id==ID_c_bit_field) { diff --git a/src/util/simplify_expr.cpp b/src/util/simplify_expr.cpp index 0bf81ed283d..b827edc3972 100644 --- a/src/util/simplify_expr.cpp +++ b/src/util/simplify_expr.cpp @@ -543,8 +543,7 @@ bool simplify_exprt::simplify_typecast(exprt &expr) operand.is_false() && config.ansi_c.NULL_is_zero) { - expr=gen_zero(expr_type); - assert(expr.is_not_nil()); + expr=null_pointer_exprt(to_pointer_type(expr_type)); return false; } } From c37c089de6d83294b46c2a7bd4780c9132985773 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 16 Jan 2017 08:06:32 -0500 Subject: [PATCH 109/166] zero_initializer without message_handlert Throws a string instead of 0. --- src/cegis/control/facade/control_runner.cpp | 2 -- src/cegis/control/verify/insert_solution.cpp | 4 +-- src/cegis/control/verify/zero_solutions.cpp | 6 ++-- src/cegis/jsa/learn/jsa_symex_learn.cpp | 3 +- .../preprocessing/add_synthesis_library.cpp | 3 +- src/cegis/learn/insert_counterexample.cpp | 6 ++-- .../instructionset/create_cegis_processor.cpp | 6 ++-- .../refactor/verify/refactor_symex_verify.cpp | 3 +- src/goto-symex/symex_start_thread.cpp | 7 +--- .../java_bytecode_convert_method.cpp | 1 + src/linking/zero_initializer.cpp | 35 ++++++++++++++++++- src/linking/zero_initializer.h | 12 +++++-- 12 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/cegis/control/facade/control_runner.cpp b/src/cegis/control/facade/control_runner.cpp index 8e6a2070dc6..140f1ef3908 100644 --- a/src/cegis/control/facade/control_runner.cpp +++ b/src/cegis/control/facade/control_runner.cpp @@ -7,8 +7,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include #include #include diff --git a/src/cegis/control/verify/insert_solution.cpp b/src/cegis/control/verify/insert_solution.cpp index 9c1fbe27642..ca5decd1ac7 100644 --- a/src/cegis/control/verify/insert_solution.cpp +++ b/src/cegis/control/verify/insert_solution.cpp @@ -10,7 +10,6 @@ Author: Daniel Kroening, kroening@kroening.com #include #include -#include #include #include @@ -56,8 +55,7 @@ struct_exprt to_struct_expr(const symbol_tablet &st, const symbol_typet &type=control_solution_type(st); const namespacet ns(st); const struct_typet &struct_type=to_struct_type(ns.follow(type)); - null_message_handlert msg; - const exprt zero(zero_initializer(type, loc, ns, msg)); + const exprt zero(zero_initializer(type, loc, ns)); struct_exprt result(to_struct_expr(zero)); struct_exprt::operandst &ops=result.operands(); set_array(ops, st, struct_type, solution.a, CEGIS_CONTROL_A_MEMBER_NAME); diff --git a/src/cegis/control/verify/zero_solutions.cpp b/src/cegis/control/verify/zero_solutions.cpp index 59468253271..22249c9b7e4 100644 --- a/src/cegis/control/verify/zero_solutions.cpp +++ b/src/cegis/control/verify/zero_solutions.cpp @@ -32,8 +32,7 @@ namespace struct_exprt make_zero(const namespacet &ns, const symbol_typet &type) { const source_locationt loc(default_cegis_source_location()); - null_message_handlert msg; - return to_struct_expr(zero_initializer(type, loc, ns, msg)); + return to_struct_expr(zero_initializer(type, loc, ns)); } } @@ -59,6 +58,5 @@ void zero_vector_solutiont::operator ()( const namespacet ns(st); const array_typet &type=control_vector_solution_type(st); const source_locationt loc(default_cegis_source_location()); - null_message_handlert msg; - solution.K=to_array_expr(zero_initializer(type, loc, ns, msg)); + solution.K=to_array_expr(zero_initializer(type, loc, ns)); } diff --git a/src/cegis/jsa/learn/jsa_symex_learn.cpp b/src/cegis/jsa/learn/jsa_symex_learn.cpp index d44640e5006..eb1fffecb3b 100644 --- a/src/cegis/jsa/learn/jsa_symex_learn.cpp +++ b/src/cegis/jsa/learn/jsa_symex_learn.cpp @@ -45,7 +45,6 @@ void jsa_symex_learnt::process(const counterexamplest &counterexamples, void jsa_symex_learnt::process(const size_t max_solution_size) { - null_message_handlert msg; const namespacet ns(original_program.st); counterexamplest counterexamples(1); counterexamplet &counterexample=counterexamples.front(); @@ -55,7 +54,7 @@ void jsa_symex_learnt::process(const size_t max_solution_size) const irep_idt &key=pos->labels.front(); const typet &type=get_affected_type(*pos); const source_locationt &loc=pos->source_location; - const exprt value(zero_initializer(type, loc, ns, msg)); + const exprt value(zero_initializer(type, loc, ns)); counterexample.insert(std::make_pair(key, value)); } process(counterexamples, max_solution_size); diff --git a/src/cegis/jsa/preprocessing/add_synthesis_library.cpp b/src/cegis/jsa/preprocessing/add_synthesis_library.cpp index f2e394c51ed..20d8edb420a 100644 --- a/src/cegis/jsa/preprocessing/add_synthesis_library.cpp +++ b/src/cegis/jsa/preprocessing/add_synthesis_library.cpp @@ -93,7 +93,6 @@ void zero_new_global_vars(const symbol_tablet &st, goto_functionst &gf) assert(init.body_available()); goto_programt &body=init.body; goto_programt::targett pos=std::prev(body.instructions.end(), 2); - null_message_handlert msg; const source_locationt loc(jsa_builtin_source_location()); const namespacet ns(st); for (const symbol_tablet::symbolst::value_type &symbol : st.symbols) @@ -103,7 +102,7 @@ void zero_new_global_vars(const symbol_tablet &st, goto_functionst &gf) pos->type=goto_program_instruction_typet::ASSIGN; pos->source_location=loc; const symbol_exprt lhs(ns.lookup(symbol.first).symbol_expr()); - const exprt rhs(zero_initializer(lhs.type(), loc, ns, msg)); + const exprt rhs(zero_initializer(lhs.type(), loc, ns)); pos->code=code_assignt(lhs, rhs); } } diff --git a/src/cegis/learn/insert_counterexample.cpp b/src/cegis/learn/insert_counterexample.cpp index 7c321db9128..9a54bd750ed 100644 --- a/src/cegis/learn/insert_counterexample.cpp +++ b/src/cegis/learn/insert_counterexample.cpp @@ -31,12 +31,11 @@ zero_valuest get_zero_values(const symbol_tablet &st, std::map zero_values; const source_locationt loc(default_cegis_source_location()); const namespacet ns(st); - null_message_handlert msg; for (const goto_programt::const_targett pos : ce_locs) { const irep_idt &marker=get_counterexample_marker(pos); const typet &type=get_affected_type(*pos); - const exprt value(zero_initializer(type, loc, ns, msg)); + const exprt value(zero_initializer(type, loc, ns)); zero_values.insert(std::make_pair(marker, value)); } return zero_values; @@ -172,8 +171,7 @@ void add_array_indexes(const std::set &ce_keys, symbol_tablet &st, pos=declare_cegis_meta_variable(st, gf, std::prev(pos), CE_ARRAY_INDEX, type); const source_locationt loc(default_cegis_source_location()); const namespacet ns(st); - null_message_handlert msg; - const exprt zero(zero_initializer(type, loc, ns, msg)); + const exprt zero(zero_initializer(type, loc, ns)); assign_cegis_meta_variable(st, gf, pos, CE_ARRAY_INDEX, zero); pos=cprover_init; for (const irep_idt &key : ce_keys) diff --git a/src/cegis/refactor/instructionset/create_cegis_processor.cpp b/src/cegis/refactor/instructionset/create_cegis_processor.cpp index 0a5871aef54..0d2d3cb54c1 100644 --- a/src/cegis/refactor/instructionset/create_cegis_processor.cpp +++ b/src/cegis/refactor/instructionset/create_cegis_processor.cpp @@ -7,8 +7,9 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include #include + +#include #include #include @@ -83,8 +84,7 @@ void create_variable_array(symbol_tablet &st, goto_functionst &gf, pos->source_location=new_symbol.location; const symbol_exprt lhs(st.lookup(name).symbol_expr()); const namespacet ns(st); - null_message_handlert msg; - const exprt rhs(zero_initializer(array_type, new_symbol.location, ns, msg)); + const exprt rhs(zero_initializer(array_type, new_symbol.location, ns)); pos->code=code_assignt(lhs, rhs); body.update(); } diff --git a/src/cegis/refactor/verify/refactor_symex_verify.cpp b/src/cegis/refactor/verify/refactor_symex_verify.cpp index a65fba9f684..4586b00acaf 100644 --- a/src/cegis/refactor/verify/refactor_symex_verify.cpp +++ b/src/cegis/refactor/verify/refactor_symex_verify.cpp @@ -28,14 +28,13 @@ void refactor_symex_verifyt::process(const candidatet &candidate) symbol_tablet &st=current_program.st; goto_functionst &gf=current_program.gf; const namespacet ns(st); - null_message_handlert msg; for (const irep_idt &program : current_program.programs) { symbolt &symbol=st.lookup(program); const candidatet::const_iterator it=candidate.find(program); if (candidate.end() == it) { - const exprt zero(zero_initializer(symbol.type, symbol.location, ns, msg)); + const exprt zero(zero_initializer(symbol.type, symbol.location, ns)); assign_in_cprover_init(gf, symbol, zero); } else assign_in_cprover_init(gf, symbol, it->second); } diff --git a/src/goto-symex/symex_start_thread.cpp b/src/goto-symex/symex_start_thread.cpp index 72b1acdb840..959034733d7 100644 --- a/src/goto-symex/symex_start_thread.cpp +++ b/src/goto-symex/symex_start_thread.cpp @@ -6,8 +6,6 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include #include "goto_symex.h" @@ -116,10 +114,7 @@ void goto_symext::symex_start_thread(statet &state) exprt rhs=symbol.value; if(rhs.is_nil()) - { - null_message_handlert null_message; - rhs=zero_initializer(symbol.type, symbol.location, ns, null_message); - } + rhs=zero_initializer(symbol.type, symbol.location, ns); guardt guard; symex_assign_symbol(state, lhs, nil_exprt(), rhs, guard, symex_targett::HIDDEN); diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 331a1012d9e..ba6764de0d7 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -10,6 +10,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #endif +#include #include #include #include diff --git a/src/linking/zero_initializer.cpp b/src/linking/zero_initializer.cpp index d652427059d..616920ca0bc 100644 --- a/src/linking/zero_initializer.cpp +++ b/src/linking/zero_initializer.cpp @@ -6,9 +6,11 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +#include + +#include #include #include -#include #include #include #include @@ -298,3 +300,34 @@ exprt zero_initializer( zero_initializert z_i(ns, message_handler); return z_i(type, source_location); } + +/*******************************************************************\ + +Function: zero_initializer + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +exprt zero_initializer( + const typet &type, + const source_locationt &source_location, + const namespacet &ns) +{ + std::ostringstream oss; + stream_message_handlert mh(oss); + + try + { + zero_initializert z_i(ns, mh); + return z_i(type, source_location); + } + catch(int) + { + throw oss.str(); + } +} diff --git a/src/linking/zero_initializer.h b/src/linking/zero_initializer.h index 0768a15056d..766fdf26784 100644 --- a/src/linking/zero_initializer.h +++ b/src/linking/zero_initializer.h @@ -10,8 +10,10 @@ Author: Daniel Kroening, kroening@kroening.com #define CPROVER_LINKING_ZERO_INITIALIZER_H #include -#include -#include + +class message_handlert; +class namespacet; +class source_locationt; exprt zero_initializer( const typet &, @@ -19,4 +21,10 @@ exprt zero_initializer( const namespacet &, message_handlert &); +// throws a char* in case of failure +exprt zero_initializer( + const typet &, + const source_locationt &, + const namespacet &); + #endif // CPROVER_LINKING_ZERO_INITIALIZER_H From e304badde8ad60b0ae91432652fca77a4ac8574c Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 16 Jan 2017 08:05:54 -0500 Subject: [PATCH 110/166] Use zero_initializer instead of gen_zero gen_zero/gen_one can now safely be removed. --- src/cegis/instrument/cegis_library.cpp | 10 +- src/cpp/cpp_typecheck_expr.cpp | 17 +- src/goto-programs/builtin_functions.cpp | 15 +- src/goto-symex/symex_builtin_functions.cpp | 4 +- .../java_bytecode_convert_class.cpp | 12 +- src/linking/zero_initializer.cpp | 66 +++++-- src/memory-models/Makefile | 2 + src/path-symex/path_symex.cpp | 9 +- src/solvers/smt1/smt1_conv.cpp | 10 +- src/solvers/smt2/smt2_conv.cpp | 8 +- src/util/expr_util.cpp | 180 ------------------ src/util/expr_util.h | 7 +- src/util/simplify_expr.cpp | 8 +- 13 files changed, 123 insertions(+), 225 deletions(-) diff --git a/src/cegis/instrument/cegis_library.cpp b/src/cegis/instrument/cegis_library.cpp index 251849164a3..920f620f74a 100644 --- a/src/cegis/instrument/cegis_library.cpp +++ b/src/cegis/instrument/cegis_library.cpp @@ -7,13 +7,13 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ -#include - #include #include #include +#include + #include #include #include @@ -78,7 +78,11 @@ goto_programt::targett init_array(const symbol_tablet &st, goto_programt &body, pos->source_location=default_cegis_source_location(); const symbol_exprt array(st.lookup(name).symbol_expr()); const array_typet &type=to_array_type(array.type()); - pos->code=code_assignt(array, array_of_exprt(gen_zero(type.subtype()), type)); + const namespacet ns(st); + pos->code= + code_assignt( + array, + zero_initializer(type, pos->source_location, ns)); return pos; } diff --git a/src/cpp/cpp_typecheck_expr.cpp b/src/cpp/cpp_typecheck_expr.cpp index a8e8fed5651..935d174a23e 100644 --- a/src/cpp/cpp_typecheck_expr.cpp +++ b/src/cpp/cpp_typecheck_expr.cpp @@ -19,6 +19,8 @@ Author: Daniel Kroening, kroening@cs.cmu.edu #include #include +#include + #include "cpp_type2name.h" #include "cpp_typecheck.h" #include "cpp_convert_type.h" @@ -1035,15 +1037,12 @@ void cpp_typecheckt::typecheck_expr_explicit_typecast(exprt &expr) { // Default value, e.g., int() typecheck_type(expr.type()); - exprt new_expr=gen_zero(expr.type()); - - if(new_expr.is_nil()) - { - error().source_location=expr.find_source_location(); - error() << "no default value for `" << to_string(expr.type()) - << "'" << eom; - throw 0; - } + exprt new_expr= + ::zero_initializer( + expr.type(), + expr.find_source_location(), + *this, + get_message_handler()); new_expr.add_source_location()=expr.source_location(); expr=new_expr; diff --git a/src/goto-programs/builtin_functions.cpp b/src/goto-programs/builtin_functions.cpp index d6a67946730..2ee615aa4b4 100644 --- a/src/goto-programs/builtin_functions.cpp +++ b/src/goto-programs/builtin_functions.cpp @@ -814,7 +814,12 @@ void goto_convertt::do_java_new_array( t_p->source_location=location; // zero-initialize the data - exprt zero_element=gen_zero(data.type().subtype()); + exprt zero_element= + zero_initializer( + data.type().subtype(), + location, + ns, + get_message_handler()); codet array_set(ID_array_set); array_set.copy_to_operands(data, zero_element); goto_programt::targett t_d=dest.add_instruction(OTHER); @@ -1646,7 +1651,13 @@ void goto_convertt::do_function_call_symbol( { goto_programt::targett t=dest.add_instruction(ASSIGN); t->source_location=function.source_location(); - t->code=code_assignt(dest_expr, gen_zero(dest_expr.type())); + exprt zero= + zero_initializer( + dest_expr.type(), + function.source_location(), + ns, + get_message_handler()); + t->code=code_assignt(dest_expr, zero); } } else if(identifier=="__sync_fetch_and_add" || diff --git a/src/goto-symex/symex_builtin_functions.cpp b/src/goto-symex/symex_builtin_functions.cpp index 1eaf30353d3..92b269f9405 100644 --- a/src/goto-symex/symex_builtin_functions.cpp +++ b/src/goto-symex/symex_builtin_functions.cpp @@ -21,6 +21,8 @@ Author: Daniel Kroening, kroening@kroening.com #include +#include + #include "goto_symex.h" #include "goto_symex_state.h" @@ -235,7 +237,7 @@ void goto_symext::symex_gcc_builtin_va_arg_next( do_simplify(tmp); irep_idt id=get_symbol(tmp); - exprt rhs=gen_zero(lhs.type()); + exprt rhs=zero_initializer(lhs.type(), code.source_location(), ns); if(id!=irep_idt()) { diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 113a8b9422d..6f292ee5985 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -15,8 +15,10 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_types.h" #include "java_bytecode_convert_method.h" +#include #include -#include + +#include class java_bytecode_convert_classt:public messaget { @@ -215,7 +217,13 @@ void java_bytecode_convert_classt::convert( "."+id2string(f.name); new_symbol.mode=ID_java; new_symbol.is_type=false; - new_symbol.value=gen_zero(field_type); + const namespacet ns(symbol_table); + new_symbol.value= + zero_initializer( + field_type, + class_symbol.location, + ns, + get_message_handler()); // Do we have the static field symbol already? const auto s_it=symbol_table.symbols.find(new_symbol.name); diff --git a/src/linking/zero_initializer.cpp b/src/linking/zero_initializer.cpp index 616920ca0bc..071cb34aa27 100644 --- a/src/linking/zero_initializer.cpp +++ b/src/linking/zero_initializer.cpp @@ -74,25 +74,42 @@ exprt zero_initializert::zero_initializer_rec( { const irep_idt &type_id=type.id(); - if(type_id==ID_bool) + if(type_id==ID_unsignedbv || + type_id==ID_signedbv || + type_id==ID_pointer || + type_id==ID_c_enum || + type_id==ID_incomplete_c_enum || + type_id==ID_c_bit_field || + type_id==ID_bool || + type_id==ID_c_bool || + type_id==ID_floatbv || + type_id==ID_fixedbv) { - exprt result=false_exprt(); + exprt result=from_integer(0, type); result.add_source_location()=source_location; return result; } - else if(type_id==ID_unsignedbv || - type_id==ID_signedbv || - type_id==ID_floatbv || - type_id==ID_fixedbv || - type_id==ID_pointer || - type_id==ID_complex || - type_id==ID_c_enum || - type_id==ID_incomplete_c_enum || - type_id==ID_c_enum_tag || - type_id==ID_c_bit_field || - type_id==ID_c_bool) + else if(type_id==ID_rational || + type_id==ID_real) { - exprt result=gen_zero(type); + constant_exprt result(ID_0, type); + result.add_source_location()=source_location; + return result; + } + else if(type_id==ID_verilog_signedbv || + type_id==ID_verilog_unsignedbv) + { + std::size_t width=to_bitvector_type(type).get_width(); + std::string value(width, '0'); + + constant_exprt result(value, type); + result.add_source_location()=source_location; + return result; + } + else if(type_id==ID_complex) + { + exprt sub_zero=zero_initializer_rec(type.subtype(), source_location); + complex_exprt result(sub_zero, sub_zero, to_complex_type(type)); result.add_source_location()=source_location; return result; } @@ -266,6 +283,27 @@ exprt zero_initializert::zero_initializer_rec( return result; } + else if(type_id==ID_c_enum_tag) + { + return + zero_initializer_rec( + ns.follow_tag(to_c_enum_tag_type(type)), + source_location); + } + else if(type_id==ID_struct_tag) + { + return + zero_initializer_rec( + ns.follow_tag(to_struct_tag_type(type)), + source_location); + } + else if(type_id==ID_union_tag) + { + return + zero_initializer_rec( + ns.follow_tag(to_union_tag_type(type)), + source_location); + } else if(type_id==ID_string) { return constant_exprt(irep_idt(), type); diff --git a/src/memory-models/Makefile b/src/memory-models/Makefile index c4c7b403b13..a1127d05821 100644 --- a/src/memory-models/Makefile +++ b/src/memory-models/Makefile @@ -2,6 +2,8 @@ SRC = mm_y.tab.cpp mm_lex.yy.cpp mmcc_main.cpp mm_parser.cpp \ mmcc_parse_options.cpp mm2cpp.cpp OBJ += ../big-int/big-int$(LIBEXT) \ + ../ansi-c/ansi-c$(LIBEXT) \ + ../linking/linking$(LIBEXT) \ ../util/util$(LIBEXT) INCLUDES= -I .. diff --git a/src/path-symex/path_symex.cpp b/src/path-symex/path_symex.cpp index f3cffd498bb..8455bec3392 100644 --- a/src/path-symex/path_symex.cpp +++ b/src/path-symex/path_symex.cpp @@ -11,11 +11,12 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include -#include #include #include #include +#include + #include #include "path_symex_class.h" @@ -352,7 +353,11 @@ void path_symext::symex_va_arg_next( // Get old symbol of va_arg and modify it to generate a new one. irep_idt id=get_old_va_symbol(state, tmp); - exprt rhs=gen_zero(lhs.type()); + exprt rhs= + zero_initializer( + lhs.type(), + code.source_location(), + state.var_map.ns); if(!id.empty()) { diff --git a/src/solvers/smt1/smt1_conv.cpp b/src/solvers/smt1/smt1_conv.cpp index e9127b15e77..0a403f6dd76 100644 --- a/src/solvers/smt1/smt1_conv.cpp +++ b/src/solvers/smt1/smt1_conv.cpp @@ -21,6 +21,8 @@ Author: Daniel Kroening, kroening@kroening.com #include +#include + #include #include #include @@ -1540,7 +1542,9 @@ void smt1_convt::convert_typecast( out << "(not (= "; convert_expr(src, true); out << " "; - convert_expr(gen_zero(src_type), true); + convert_expr( + zero_initializer(src_type, expr.source_location(), ns), + true); out << "))"; } else @@ -1566,7 +1570,9 @@ void smt1_convt::convert_typecast( out << "(not (= "; convert_expr(src, true); out << " "; - convert_expr(gen_zero(src_type), true); + convert_expr( + zero_initializer(src_type, expr.source_location(), ns), + true); out << ")) "; // not, = out << " bv1[" << to_width << "]"; out << " bv0[" << to_width << "]"; diff --git a/src/solvers/smt2/smt2_conv.cpp b/src/solvers/smt2/smt2_conv.cpp index b98cf9a9da5..32df575ff84 100644 --- a/src/solvers/smt2/smt2_conv.cpp +++ b/src/solvers/smt2/smt2_conv.cpp @@ -22,6 +22,8 @@ Author: Daniel Kroening, kroening@kroening.com #include +#include + #include #include #include @@ -2062,7 +2064,8 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr) out << "(not (= "; convert_expr(src); out << " "; - convert_expr(gen_zero(src_type)); + convert_expr( + zero_initializer(src_type, expr.source_location(), ns)); out << "))"; } else if(src_type.id()==ID_floatbv) @@ -2088,7 +2091,8 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr) out << "(not (= "; convert_expr(src); out << " "; - convert_expr(gen_zero(src_type)); + convert_expr( + zero_initializer(src_type, expr.source_location(), ns)); out << ")) "; // not, = out << " (_ bv1 " << to_width << ")"; out << " (_ bv0 " << to_width << ")"; diff --git a/src/util/expr_util.cpp b/src/util/expr_util.cpp index 577f59610d7..09f3ef2a7c6 100644 --- a/src/util/expr_util.cpp +++ b/src/util/expr_util.cpp @@ -17,186 +17,6 @@ Author: Daniel Kroening, kroening@kroening.com /*******************************************************************\ -Function: gen_zero - - Inputs: - - Outputs: - - Purpose: - -\*******************************************************************/ - -exprt gen_zero(const typet &type) -{ - const irep_idt type_id=type.id(); - - if(type_id==ID_rational || - type_id==ID_real || - type_id==ID_integer || - type_id==ID_natural) - { - return constant_exprt(ID_0, type); - } - else if(type_id==ID_c_enum) - { - exprt tmp=gen_zero(type.subtype()); - tmp.type()=type; - return tmp; - } - else if(type_id==ID_c_enum_tag) - { - // Ha! We generate a typecast. - exprt tmp=gen_zero(unsignedbv_typet(1)); - return typecast_exprt(tmp, type); - } - else if(type_id==ID_unsignedbv || - type_id==ID_signedbv || - type_id==ID_verilog_signedbv || - type_id==ID_verilog_unsignedbv || - type_id==ID_floatbv || - type_id==ID_fixedbv || - type_id==ID_c_bit_field || - type_id==ID_c_bool) - { - std::string value; - std::size_t width=to_bitvector_type(type).get_width(); - - for(std::size_t i=0; i=3 operands into nested binary expressions */ +/*! splits an expression with >=3 operands into nested binary expressions */ exprt make_binary(const exprt &); /*! converts an udpate expr into a (possibly nested) with expression */ diff --git a/src/util/simplify_expr.cpp b/src/util/simplify_expr.cpp index b827edc3972..1c8dfd226c2 100644 --- a/src/util/simplify_expr.cpp +++ b/src/util/simplify_expr.cpp @@ -32,6 +32,8 @@ Author: Daniel Kroening, kroening@kroening.com #include "endianness_map.h" #include "simplify_utils.h" +#include + //#define DEBUGX #ifdef DEBUGX @@ -273,7 +275,8 @@ bool simplify_exprt::simplify_typecast(exprt &expr) inequality.id(op_type.id()==ID_floatbv?ID_ieee_float_notequal:ID_notequal); inequality.add_source_location()=expr.source_location(); inequality.lhs()=expr.op0(); - inequality.rhs()=gen_zero(ns.follow(expr.op0().type())); + inequality.rhs()= + zero_initializer(expr.op0().type(), expr.source_location(), ns); assert(inequality.rhs().is_not_nil()); simplify_node(inequality); expr.swap(inequality); @@ -289,7 +292,8 @@ bool simplify_exprt::simplify_typecast(exprt &expr) inequality.id(op_type.id()==ID_floatbv?ID_ieee_float_notequal:ID_notequal); inequality.add_source_location()=expr.source_location(); inequality.lhs()=expr.op0(); - inequality.rhs()=gen_zero(ns.follow(expr.op0().type())); + inequality.rhs()= + zero_initializer(expr.op0().type(), expr.source_location(), ns); assert(inequality.rhs().is_not_nil()); simplify_node(inequality); expr.op0()=inequality; From 33b45d333588fe8f5d9eb154bb57fa44c537a18c Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sat, 21 Jan 2017 21:42:20 +0000 Subject: [PATCH 111/166] Added file copyright header as noted by linter --- src/cpp/cpp_typecheck_virtual_table.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/cpp/cpp_typecheck_virtual_table.cpp b/src/cpp/cpp_typecheck_virtual_table.cpp index b2c18974613..1d8cca10b84 100644 --- a/src/cpp/cpp_typecheck_virtual_table.cpp +++ b/src/cpp/cpp_typecheck_virtual_table.cpp @@ -1,5 +1,18 @@ /*******************************************************************\ +Module: C++ Language Type Checking + +Author: Daniel Kroening, kroening@cs.cmu.edu + +\*******************************************************************/ + +#include +#include + +#include "cpp_typecheck.h" + +/*******************************************************************\ + Function: cpp_typecheckt::do_virtual_table Inputs: @@ -10,11 +23,6 @@ Function: cpp_typecheckt::do_virtual_table \*******************************************************************/ -#include -#include - -#include "cpp_typecheck.h" - void cpp_typecheckt::do_virtual_table(const symbolt &symbol) { assert(symbol.type.id()==ID_struct); From a9752ccffcbfe2cc70cc3a8583aee935681410cb Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Fri, 27 Jan 2017 08:10:33 +0000 Subject: [PATCH 112/166] cbmc-java: Print details of errors in regression tests This is the same as various other directories already do. --- regression/cbmc-java/Makefile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/regression/cbmc-java/Makefile b/regression/cbmc-java/Makefile index 5ac5a21995e..cee83cba67a 100644 --- a/regression/cbmc-java/Makefile +++ b/regression/cbmc-java/Makefile @@ -1,10 +1,16 @@ default: tests.log test: - @../test.pl -c ../../../src/cbmc/cbmc + @if ! ../test.pl -c ../../../src/cbmc/cbmc ; then \ + ../failed-tests-printer.pl ; \ + exit 1 ; \ + fi tests.log: ../test.pl - @../test.pl -c ../../../src/cbmc/cbmc + @if ! ../test.pl -c ../../../src/cbmc/cbmc ; then \ + ../failed-tests-printer.pl ; \ + exit 1 ; \ + fi show: @for dir in *; do \ From b083cf542099d78a98620c5a375ac3034827bee7 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Fri, 27 Jan 2017 09:23:22 +0000 Subject: [PATCH 113/166] Make from_integer fail an assertion for unsupported types Prompts a fix in java bytecode conversion. --- .../java_bytecode_convert_method.cpp | 16 ++++++++++------ src/util/arith_tools.cpp | 1 + src/util/arith_tools.h | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index ba6764de0d7..fd2a5a0ed91 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -1277,9 +1277,11 @@ codet java_bytecode_convert_methodt::convert_instructions( irep_idt number=to_constant_expr(arg0).get_value(); code_gotot code_goto(label(number)); c=code_goto; - results[0]=from_integer( - std::next(i_it)->address, - pointer_typet(void_typet(), 64)); + results[0]= + from_integer( + std::next(i_it)->address, + unsignedbv_typet(64)); + results[0].type()=pointer_typet(void_typet(), 64); } else if(statement=="ret") { @@ -1300,9 +1302,11 @@ codet java_bytecode_convert_methodt::convert_instructions( else { code_ifthenelset branch; - auto address_ptr=from_integer( - jsr_ret_targets[idx], - pointer_typet(void_typet(), 64)); + auto address_ptr= + from_integer( + jsr_ret_targets[idx], + unsignedbv_typet(64)); + address_ptr.type()=pointer_typet(void_typet(), 64); branch.cond()=equal_exprt(retvar, address_ptr); branch.cond().add_source_location()=i_it->source_location; branch.then_case()=g; diff --git a/src/util/arith_tools.cpp b/src/util/arith_tools.cpp index 0957cf41ab5..6acac029673 100644 --- a/src/util/arith_tools.cpp +++ b/src/util/arith_tools.cpp @@ -213,6 +213,7 @@ constant_exprt from_integer( } { + assert(false); constant_exprt r; r.make_nil(); return r; diff --git a/src/util/arith_tools.h b/src/util/arith_tools.h index 227910b0674..2dbef68b7a3 100644 --- a/src/util/arith_tools.h +++ b/src/util/arith_tools.h @@ -22,7 +22,7 @@ bool to_integer(const exprt &expr, mp_integer &int_value); // returns 'true' on error bool to_integer(const constant_exprt &expr, mp_integer &int_value); -// returns 'nil' on error +// assert(false) in case of unsupported type constant_exprt from_integer(const mp_integer &int_value, const typet &type); // ceil(log2(size)) From d36aa5ab45c797b95a7066e2de0b2c5e22d4d1d7 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sat, 21 Jan 2017 06:13:21 +0000 Subject: [PATCH 114/166] Makefile tweaks to enable re-use of Makefiles in vpath builds --- src/solvers/Makefile | 2 +- src/util/Makefile | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/solvers/Makefile b/src/solvers/Makefile index b806aa47886..95ea7650274 100644 --- a/src/solvers/Makefile +++ b/src/solvers/Makefile @@ -120,7 +120,7 @@ SRC = $(CHAFF_SRC) $(BOOLEFORCE_SRC) $(MINISAT_SRC) $(MINISAT2_SRC) \ refinement/refine_arrays.cpp \ miniBDD/miniBDD.cpp -INCLUDES= -I .. \ +INCLUDES += -I .. \ $(CHAFF_INCLUDE) $(BOOLEFORCE_INCLUDE) $(MINISAT_INCLUDE) $(MINISAT2_INCLUDE) \ $(SMVSAT_INCLUDE) $(SQUOLEM2_INC) $(CUDD_INCLUDE) $(GLUCOSE_INCLUDE) \ $(PRECOSAT_INCLUDE) $(PICOSAT_INCLUDE) $(LINGELING_INCLUDE) diff --git a/src/util/Makefile b/src/util/Makefile index f98b6588df8..237236f5230 100644 --- a/src/util/Makefile +++ b/src/util/Makefile @@ -37,11 +37,11 @@ all: util$(LIBEXT) ############################################################################### -irep_ids.h: irep_ids_convert$(EXEEXT) irep_ids.txt - ./irep_ids_convert$(EXEEXT) header < irep_ids.txt > $@ +irep_ids.h: irep_ids.txt irep_ids_convert$(EXEEXT) + ./irep_ids_convert$(EXEEXT) header < $< > $@ -irep_ids.inc: irep_ids_convert$(EXEEXT) irep_ids.txt - ./irep_ids_convert$(EXEEXT) table < irep_ids.txt > $@ +irep_ids.inc: irep_ids.txt irep_ids_convert$(EXEEXT) + ./irep_ids_convert$(EXEEXT) table < $< > $@ irep_ids.cpp: irep_ids.inc irep_ids.h From 6a7a64c439c7033b0674bb0c2c23e7095a5bb08d Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sat, 21 Jan 2017 06:14:45 +0000 Subject: [PATCH 115/166] Script to prepare out-of-tree (aka vpath) builds Run ../scripts/vpath-setup.sh desired-build-dir from the src/ directory. --- scripts/vpath-setup.sh | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100755 scripts/vpath-setup.sh diff --git a/scripts/vpath-setup.sh b/scripts/vpath-setup.sh new file mode 100755 index 00000000000..611b0056652 --- /dev/null +++ b/scripts/vpath-setup.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +set -e + +if [ $# -ne 1 ] +then + echo "Target directory required" 1>&2 + exit 1 +fi + +if ! make -s generated_files +then + echo "Failed to run 'make generated_files'" 1>&2 + exit 1 +fi + +DEST=$1 + +gen_makefile() +{ + local d=$1 + local m=$2 + + mkdir -p $DEST/src/$d + cat > $DEST/src/$d/$m <> $DEST/src/$d/$m +} + +makefiles=$(find . -name Makefile | grep -v $DEST) + +for m in $makefiles +do + dir=$(dirname $m) + gen_makefile $dir Makefile +done + +gen_makefile big-int makefile + +cp common config.inc $DEST/src/ + +# tweak include paths in config.inc +perl -p -i -e 's/(= \.\.\/\.\.\/)/$1..\/..\//' $DEST/src/config.inc +echo "INCLUDES += -I$PWD" >> $DEST/src/config.inc + +# tweak targets that aren't compatible with vpaths +perl -p -i -e "s{(library/\\*.c)}{$PWD/ansi-c/\$1}" $DEST/src/ansi-c/Makefile +perl -p -i -e 's/^(cprover_library.inc:)/%$1/' $DEST/src/ansi-c/Makefile +perl -p -i -e 's/^(cprover_library.cpp:)/#$1/' $DEST/src/ansi-c/Makefile + +perl -p -i -e 's/^(irep_ids.cpp:)/#$1/' $DEST/src/util/Makefile + +# create sub-directories +mkdir -p $DEST/src/ansi-c/library $DEST/src/ansi-c/literals +mkdir -p $DEST/src/goto-instrument/{accelerate,wmm} +mkdir -p $DEST/src/solvers/{cvc,flattening,floatbv,miniBDD,prop,qbf,refinement,sat,smt1,smt2} + +# copy generated files for coverage reports +for f in \ + ansi-c/ansi_c_lex.yy.cpp ansi-c/scanner.l ansi-c/ansi_c_y.tab.cpp \ + assembler/scanner.l assembler/assembler_lex.yy.cpp \ + jsil/jsil_lex.yy.cpp jsil/scanner.l jsil/jsil_y.tab.cpp \ + json/parser.y json/json_lex.yy.cpp json/json_y.tab.cpp \ + xmllang/scanner.l xmllang/xml_lex.yy.cpp xmllang/xml_y.tab.cpp xmllang/parser.y +do + cp $f $DEST/src/$(dirname $f)/ +done + +cp -aL ../regression $DEST/ From 99d53d953588fa3db937b59a8b2397773db955eb Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sat, 21 Jan 2017 07:26:48 +0000 Subject: [PATCH 116/166] Use vpath builds for coverage measurement This avoids full clean & recompile on each run. --- regression/get_coverage.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/regression/get_coverage.sh b/regression/get_coverage.sh index 3f2a8e424f3..9ca3561714a 100755 --- a/regression/get_coverage.sh +++ b/regression/get_coverage.sh @@ -9,6 +9,7 @@ if [ $? -ne 0 ]; then printf "ERROR: Could not create output directoy" exit 1 fi +output_dir_abs=`cd $output_dir > /dev/null ; pwd` # Check that the previous command succeded, if not exit. command_status() @@ -49,18 +50,21 @@ lcov -version > $output_dir/cbmc_coverage.out 2>&1 command_status # Remove any previous build that may not have coverage in it. -printf "INFO: Cleaning CBMC build " -make clean -C ../src >> $output_dir/cbmc_coverage.out 2>&1 +printf "INFO: setting up vpath build " +cd ../src +../scripts/vpath-setup.sh coverage-build >> $output_dir_abs/cbmc_coverage.out 2>&1 command_status +cd ../regression printf "INFO: Building CBMC with Code Coverage enabled " # Run the usual make target with --coverage to add gcov instrumentation -make CXXFLAGS="--coverage" LINKFLAGS="--coverage" -C ../src >> $output_dir/cbmc_coverage.out 2>&1 +make CXXFLAGS="--coverage" LINKFLAGS="--coverage" -C ../src/coverage-build/src \ + >> $output_dir/cbmc_coverage.out 2>&1 command_status printf "INFO: Running Regression tests " # Run regression tests which will collect the coverage metrics and put them in the src files -make >> $output_dir/cbmc_coverage.out 2>&1 +make -C ../src/coverage-build/regression >> $output_dir/cbmc_coverage.out 2>&1 printf "[DONE]\n" printf "INFO: Gathering coverage metrics " From a7a4ebbf1c84dd8d0e15d3267e9699f3b2fdf4df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Thu, 15 Dec 2016 12:51:10 +0100 Subject: [PATCH 117/166] ignore recursion set if class is subtype --- src/java_bytecode/java_object_factory.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/java_bytecode/java_object_factory.cpp b/src/java_bytecode/java_object_factory.cpp index e7ab2f1a658..b23e419d216 100644 --- a/src/java_bytecode/java_object_factory.cpp +++ b/src/java_bytecode/java_object_factory.cpp @@ -189,8 +189,9 @@ void java_object_factoryt::gen_nondet_init( { const struct_typet &struct_type=to_struct_type(subtype); const irep_idt struct_tag=struct_type.get_tag(); - - if(recursion_set.find(struct_tag)!=recursion_set.end()) + // set to null if found in recursion set and not a sub-type + if(recursion_set.find(struct_tag)!=recursion_set.end() && + struct_tag==class_identifier) { // make null null_pointer_exprt null_pointer_expr(pointer_type); From 9f37ed471f623638701e7bf5bc4b6d9168c3462f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Sat, 21 Jan 2017 00:42:53 +0100 Subject: [PATCH 118/166] loop unwinding in static init of Java enum Static initialization of Java enums sometimes contains extra code that loops over the array of enum elements. This often prevents initialization of the enumeration and leads to zero coverage. This patch counts the number of enum elements, and explicitely unwinds all loops in to this number + 1. This acts as a heuristic to make static inits of enums finish. --- src/cbmc/cbmc_parse_options.cpp | 12 ++ src/cbmc/cbmc_parse_options.h | 11 +- src/goto-programs/Makefile | 3 +- .../remove_static_init_loops.cpp | 118 ++++++++++++++++++ src/goto-programs/remove_static_init_loops.h | 22 ++++ .../java_bytecode_convert_class.cpp | 4 + .../java_bytecode_parse_tree.cpp | 19 +-- src/java_bytecode/java_bytecode_parse_tree.h | 22 +++- src/java_bytecode/java_bytecode_parser.cpp | 11 +- src/util/irep_ids.txt | 1 + 10 files changed, 204 insertions(+), 19 deletions(-) create mode 100644 src/goto-programs/remove_static_init_loops.cpp create mode 100644 src/goto-programs/remove_static_init_loops.h diff --git a/src/cbmc/cbmc_parse_options.cpp b/src/cbmc/cbmc_parse_options.cpp index 51fd717edb2..4fa9edb7726 100644 --- a/src/cbmc/cbmc_parse_options.cpp +++ b/src/cbmc/cbmc_parse_options.cpp @@ -27,6 +27,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include #include @@ -221,6 +222,10 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options) // all checks supported by goto_check GOTO_CHECK_PARSE_OPTIONS(cmdline, options); + // unwind loops in java enum static initialization + if(cmdline.isset("java-unwind-enum-static")) + options.set_option("java-unwind-enum-static", true); + // check assertions if(cmdline.isset("no-assertions")) options.set_option("assertions", false); @@ -541,6 +546,9 @@ int cbmc_parse_optionst::doit() if(set_properties(goto_functions)) return 7; // should contemplate EX_USAGE from sysexits.h + if(options.get_bool_option("java-unwind-enum-static")) + remove_static_init_loops(symbol_table, goto_functions, options); + // do actual BMC return do_bmc(bmc, goto_functions); } @@ -1126,6 +1134,10 @@ void cbmc_parse_optionst::help() "Java Bytecode frontend options:\n" " --classpath dir/jar set the classpath\n" " --main-class class-name set the name of the main class\n" + // NOLINTNEXTLINE(whitespace/line_length) + " --java-max-vla-length limit the length of user-code-created arrays\n" + // NOLINTNEXTLINE(whitespace/line_length) + " --java-unwind-enum-static try to unwind loops in static initialization of enums\n" "\n" "Semantic transformations:\n" " --nondet-static add nondeterministic initialization of variables with static lifetime\n" // NOLINT(*) diff --git a/src/cbmc/cbmc_parse_options.h b/src/cbmc/cbmc_parse_options.h index 72387bcb4fc..3fcc98231f7 100644 --- a/src/cbmc/cbmc_parse_options.h +++ b/src/cbmc/cbmc_parse_options.h @@ -36,13 +36,13 @@ class optionst; "(smt1)(smt2)(fpa)(cvc3)(cvc4)(boolector)(yices)(z3)(opensmt)(mathsat)" \ "(no-sat-preprocessor)" \ "(no-pretty-names)(beautify)" \ - "(dimacs)(refine)(max-node-refinement):(refine-arrays)(refine-arithmetic)(aig)" \ - "(16)(32)(64)(LP64)(ILP64)(LLP64)(ILP32)(LP32)" \ + "(dimacs)(refine)(max-node-refinement):(refine-arrays)(refine-arithmetic)"\ + "(aig)(16)(32)(64)(LP64)(ILP64)(LLP64)(ILP32)(LP32)" \ "(little-endian)(big-endian)" \ "(show-goto-functions)(show-loops)" \ "(show-symbol-table)(show-parse-tree)(show-vcc)" \ - "(show-claims)(claim):(show-properties)(show-reachable-properties)(property):" \ - "(stop-on-fail)(trace)" \ + "(show-claims)(claim):(show-properties)(show-reachable-properties)" \ + "(property):(stop-on-fail)(trace)" \ "(error-label):(verbosity):(no-library)" \ "(nondet-static)" \ "(version)" \ @@ -54,8 +54,9 @@ class optionst; "(string-abstraction)(no-arch)(arch):" \ "(round-to-nearest)(round-to-plus-inf)(round-to-minus-inf)(round-to-zero)" \ "(graphml-witness):" \ + "(java-max-vla-length):(java-unwind-enum-static)" \ "(localize-faults)(localize-faults-method):" \ - "(fixedbv)(floatbv)(all-claims)(all-properties)" // legacy, and will eventually disappear + "(fixedbv)(floatbv)(all-claims)(all-properties)" // legacy, and will eventually disappear // NOLINT(whitespace/line_length) class cbmc_parse_optionst: public parse_options_baset, diff --git a/src/goto-programs/Makefile b/src/goto-programs/Makefile index 813be9a18b7..14516b8c38c 100644 --- a/src/goto-programs/Makefile +++ b/src/goto-programs/Makefile @@ -17,7 +17,8 @@ SRC = goto_convert.cpp goto_convert_function_call.cpp \ goto_trace.cpp xml_goto_trace.cpp vcd_goto_trace.cpp \ graphml_witness.cpp remove_virtual_functions.cpp \ class_hierarchy.cpp show_goto_functions.cpp get_goto_model.cpp \ - slice_global_inits.cpp goto_inline_class.cpp class_identifier.cpp + slice_global_inits.cpp goto_inline_class.cpp class_identifier.cpp \ + remove_static_init_loops.cpp INCLUDES= -I .. diff --git a/src/goto-programs/remove_static_init_loops.cpp b/src/goto-programs/remove_static_init_loops.cpp new file mode 100644 index 00000000000..25d48ccf654 --- /dev/null +++ b/src/goto-programs/remove_static_init_loops.cpp @@ -0,0 +1,118 @@ +/*******************************************************************\ + +Module: Unwind loops in static initializers + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + +#include +#include + +#include "remove_static_init_loops.h" + +class remove_static_init_loopst +{ +public: + explicit remove_static_init_loopst( + const symbol_tablet &_symbol_table): + symbol_table(_symbol_table) + {} + + void unwind_enum_static( + const goto_functionst &goto_functions, + optionst &options); +protected: + const symbol_tablet &symbol_table; +}; + +/*******************************************************************\ + +Function: unwind_enum_static + + Inputs: goto_functions and options + + Outputs: side effect is adding loops to unwindset + + Purpose: unwind static initialization loops of Java enums as far as + the enum has elements, thus flattening them completely + +\*******************************************************************/ + +void remove_static_init_loopst::unwind_enum_static( + const goto_functionst &goto_functions, + optionst &options) +{ + size_t unwind_max=0; + forall_goto_functions(f, goto_functions) + { + auto &p=f->second.body; + for(const auto &ins : p.instructions) + { + // is this a loop? + if(ins.is_backwards_goto()) + { + size_t loop_id=ins.loop_number; + const std::string java_clinit=":()V"; + const std::string &fname=id2string(ins.function); + size_t class_prefix_length=fname.find_last_of('.'); + assert( + class_prefix_length!=std::string::npos && + "could not identify class name"); + const std::string &classname=fname.substr(0, class_prefix_length); + const symbolt &class_symbol=symbol_table.lookup(classname); + const class_typet &class_type=to_class_type(class_symbol.type); + size_t unwinds=class_type.get_size_t(ID_java_enum_static_unwind); + + unwind_max=std::max(unwind_max, unwinds); + if(fname.length()>java_clinit.length()) + { + // extend unwindset with unwinds for of enum + if(fname.compare( + fname.length()-java_clinit.length(), + java_clinit.length(), + java_clinit)==0 && unwinds>0) + { + const std::string &set=options.get_option("unwindset"); + std::string newset; + if(set!="") + newset=","; + newset+= + id2string(ins.function)+"."+std::to_string(loop_id)+":"+ + std::to_string(unwinds); + options.set_option("unwindset", set+newset); + } + } + } + } + } + const std::string &vla_length=options.get_option("java-max-vla-length"); + if(!vla_length.empty()) + { + size_t max_vla_length=safe_string2unsigned(vla_length); + if(max_vla_length due to insufficient max vla length"; + } +} + +/*******************************************************************\ + +Function: remove_static_init_loops + + Inputs: symbol table, goto_functions and options + + Outputs: side effect is adding loops to unwindset + + Purpose: this is the entry point for the removal of loops in static + initialization code of Java enums + +\*******************************************************************/ + +void remove_static_init_loops( + const symbol_tablet &symbol_table, + const goto_functionst &goto_functions, + optionst &options) +{ + remove_static_init_loopst remove_loops(symbol_table); + remove_loops.unwind_enum_static(goto_functions, options); +} diff --git a/src/goto-programs/remove_static_init_loops.h b/src/goto-programs/remove_static_init_loops.h new file mode 100644 index 00000000000..dd07ec6a670 --- /dev/null +++ b/src/goto-programs/remove_static_init_loops.h @@ -0,0 +1,22 @@ +/*******************************************************************\ + +Module: Unwind loops in static initializers + +Author: Daniel Kroening, kroening@kroening.com + +\*******************************************************************/ + +#include + +#include +#include + +#ifndef CPROVER_GOTO_PROGRAMS_REMOVE_STATIC_INIT_LOOPS_H +#define CPROVER_GOTO_PROGRAMS_REMOVE_STATIC_INIT_LOOPS_H + +void remove_static_init_loops( + const symbol_tablet &, + const goto_functionst &, + optionst &); + +#endif // CPROVER_GOTO_PROGRAMS_REMOVE_STATIC_INIT_LOOPS_H diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 6f292ee5985..8d42611bfe0 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -79,6 +79,10 @@ void java_bytecode_convert_classt::convert(const classt &c) class_type.set_tag(c.name); class_type.set(ID_base_name, c.name); + if(c.is_enum) + class_type.set( + ID_java_enum_static_unwind, + std::to_string(c.enum_elements+1)); if(!c.extends.empty()) { diff --git a/src/java_bytecode/java_bytecode_parse_tree.cpp b/src/java_bytecode/java_bytecode_parse_tree.cpp index b7f3be50007..e48675d275f 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.cpp +++ b/src/java_bytecode/java_bytecode_parse_tree.cpp @@ -34,6 +34,8 @@ void java_bytecode_parse_treet::classt::swap( { other.name.swap(name); other.extends.swap(extends); + other.is_enum=is_enum; + other.enum_elements=enum_elements; std::swap(other.is_abstract, is_abstract); other.implements.swap(implements); other.fields.swap(fields); @@ -61,10 +63,7 @@ void java_bytecode_parse_treet::output(std::ostream &out) const for(class_refst::const_iterator it=class_refs.begin(); it!=class_refs.end(); it++) - { out << " " << *it << '\n'; - } - } /*******************************************************************\ @@ -88,7 +87,8 @@ void java_bytecode_parse_treet::classt::output(std::ostream &out) const } out << "class " << name; - if(!extends.empty()) out << " extends " << extends; + if(!extends.empty()) + out << " extends " << extends; out << " {" << '\n'; for(fieldst::const_iterator @@ -139,7 +139,10 @@ void java_bytecode_parse_treet::annotationt::output(std::ostream &out) const bool first=true; for(const auto &element_value_pair : element_value_pairs) { - if(first) first=false; else out << ", "; + if(first) + first=false; + else + out << ", "; element_value_pair.output(out); } @@ -159,7 +162,8 @@ Function: java_bytecode_parse_treet::annotationt::element_value_pairt::output \*******************************************************************/ -void java_bytecode_parse_treet::annotationt::element_value_pairt::output(std::ostream &out) const +void java_bytecode_parse_treet::annotationt::element_value_pairt::output( + std::ostream &out) const { symbol_tablet symbol_table; namespacet ns(symbol_table); @@ -233,7 +237,8 @@ void java_bytecode_parse_treet::methodt::output(std::ostream &out) const for(std::vector::const_iterator a_it=i.args.begin(); a_it!=i.args.end(); a_it++) { - if(a_it!=i.args.begin()) out << ','; + if(a_it!=i.args.begin()) + out << ','; #if 0 out << ' ' << from_expr(*a_it); #else diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index 398e3959d1a..bd62b0e1377 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -123,15 +123,20 @@ class java_bytecode_parse_treet class stack_map_table_entryt { public: - enum stack_frame_type { SAME, SAME_LOCALS_ONE_STACK, SAME_LOCALS_ONE_STACK_EXTENDED, - CHOP, SAME_EXTENDED, APPEND, FULL}; + enum stack_frame_type + { + SAME, SAME_LOCALS_ONE_STACK, SAME_LOCALS_ONE_STACK_EXTENDED, + CHOP, SAME_EXTENDED, APPEND, FULL + }; stack_frame_type type; size_t offset_delta; size_t chops; size_t appends; - typedef std::vector local_verification_type_infot; - typedef std::vector stack_verification_type_infot; + typedef std::vector + local_verification_type_infot; + typedef std::vector + stack_verification_type_infot; local_verification_type_infot locals; stack_verification_type_infot stack; @@ -142,7 +147,10 @@ class java_bytecode_parse_treet virtual void output(std::ostream &out) const; - inline methodt():is_native(false), is_abstract(false), is_synchronized(false) + inline methodt(): + is_native(false), + is_abstract(false), + is_synchronized(false) { } }; @@ -151,6 +159,7 @@ class java_bytecode_parse_treet { public: virtual void output(std::ostream &out) const; + bool is_enum; }; class classt @@ -158,6 +167,9 @@ class java_bytecode_parse_treet public: irep_idt name, extends; bool is_abstract; + bool is_enum; + size_t enum_elements=0; + typedef std::list implementst; implementst implements; diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 7138ab3951b..323ef603af8 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -264,6 +264,7 @@ Function: java_bytecode_parsert::rClassFile #define ACC_ABSTRACT 0x0400 #define ACC_STRICT 0x0800 #define ACC_SYNTHETIC 0x1000 +#define ACC_ENUM 0x4000 #ifdef _MSC_VER #define UNUSED @@ -295,10 +296,11 @@ void java_bytecode_parsert::rClassFile() classt &parsed_class=parse_tree.parsed_class; - u2 UNUSED access_flags=read_u2(); + u2 access_flags=read_u2(); u2 this_class=read_u2(); u2 super_class=read_u2(); + parsed_class.is_enum=(access_flags&ACC_ENUM)!=0; parsed_class.name= constant(this_class).type().get(ID_C_base_name); @@ -310,6 +312,12 @@ void java_bytecode_parsert::rClassFile() rfields(parsed_class); rmethods(parsed_class); + // count elements of enum + if(parsed_class.is_enum) + for(fieldt &field : parse_tree.parsed_class.fields) + if(field.is_enum) + parse_tree.parsed_class.enum_elements++; + u2 attributes_count=read_u2(); for(std::size_t j=0; j Date: Fri, 16 Sep 2016 15:15:38 +0100 Subject: [PATCH 119/166] Keep SSA L1 IDs as an attribute Previously these were derived from the full SSA ID by searching for the last character that can't feature in a C identifier. Unfortunately a period /can/ feature in a Java identifier (e.g. mypackage.myclass.myfunction). Alternatively we could just flip the #if test at ssa_expr.h:67, but there was apparently a performance motive to avoid this in the first place. --- src/util/irep_ids.txt | 1 + src/util/ssa_expr.cpp | 24 +++++++++++++++++------- src/util/ssa_expr.h | 18 +++++++----------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/util/irep_ids.txt b/src/util/irep_ids.txt index 37b96299311..bd6c082973f 100644 --- a/src/util/irep_ids.txt +++ b/src/util/irep_ids.txt @@ -693,6 +693,7 @@ C_full_identifier #full_identifier L0 L1 L2 +L1_object_identifier already_typechecked C_va_arg_type #va_arg_type smt2_symbol diff --git a/src/util/ssa_expr.cpp b/src/util/ssa_expr.cpp index 5b54e2d649c..c75d7d2ed92 100644 --- a/src/util/ssa_expr.cpp +++ b/src/util/ssa_expr.cpp @@ -30,13 +30,14 @@ static void build_ssa_identifier_rec( const irep_idt &l0, const irep_idt &l1, const irep_idt &l2, - std::ostream &os) + std::ostream &os, + std::ostream &l1_object_os) { if(expr.id()==ID_member) { const member_exprt &member=to_member_expr(expr); - build_ssa_identifier_rec(member.struct_op(), l0, l1, l2, os); + build_ssa_identifier_rec(member.struct_op(), l0, l1, l2, os, l1_object_os); os << '.' << member.get_component_name(); } @@ -44,7 +45,7 @@ static void build_ssa_identifier_rec( { const index_exprt &index=to_index_expr(expr); - build_ssa_identifier_rec(index.array(), l0, l1, l2, os); + build_ssa_identifier_rec(index.array(), l0, l1, l2, os, l1_object_os); mp_integer idx; if(to_integer(to_constant_expr(index.index()), idx)) @@ -54,13 +55,21 @@ static void build_ssa_identifier_rec( } else if(expr.id()==ID_symbol) { - os << to_symbol_expr(expr).get_identifier(); + auto symid=to_symbol_expr(expr).get_identifier(); + os << symid; + l1_object_os << symid; if(!l0.empty()) + { os << '!' << l0; + l1_object_os << '!' << l0; + } if(!l1.empty()) + { os << '@' << l1; + l1_object_os << '@' << l1; + } if(!l2.empty()) os << '#' << l2; @@ -81,15 +90,16 @@ Function: ssa_exprt::build_identifier \*******************************************************************/ -irep_idt ssa_exprt::build_identifier( +std::pair ssa_exprt::build_identifier( const exprt &expr, const irep_idt &l0, const irep_idt &l1, const irep_idt &l2) { std::ostringstream oss; + std::ostringstream l1_object_oss; - build_ssa_identifier_rec(expr, l0, l1, l2, oss); + build_ssa_identifier_rec(expr, l0, l1, l2, oss, l1_object_oss); - return oss.str(); + return std::make_pair(irep_idt(oss.str()), irep_idt(l1_object_oss.str())); } diff --git a/src/util/ssa_expr.h b/src/util/ssa_expr.h index 36ab025b821..31064c1ec60 100644 --- a/src/util/ssa_expr.h +++ b/src/util/ssa_expr.h @@ -67,15 +67,9 @@ class ssa_exprt:public symbol_exprt #if 0 return get_l1_object().get_identifier(); #else - // the above is the clean version, this is the fast one, making - // use of internal knowledge about identifier names - std::string l1_o_id=id2string(get_identifier()); - std::string::size_type fs_suffix=l1_o_id.find_first_of(".[#"); - - if(fs_suffix!=std::string::npos) - l1_o_id.resize(fs_suffix); - - return l1_o_id; + // the above is the clean version, this is the fast one, using + // an identifier cached during build_identifier + return get(ID_L1_object_identifier); #endif } @@ -130,10 +124,12 @@ class ssa_exprt:public symbol_exprt const irep_idt &l1=get_level_1(); const irep_idt &l2=get_level_2(); - set_identifier(build_identifier(get_original_expr(), l0, l1, l2)); + auto idpair=build_identifier(get_original_expr(), l0, l1, l2); + set_identifier(idpair.first); + set(ID_L1_object_identifier, idpair.second); } - static irep_idt build_identifier( + static std::pair build_identifier( const exprt &src, const irep_idt &l0, const irep_idt &l1, From ebe9f2e7fec9a8dd153279ae8cb76bb756265efa Mon Sep 17 00:00:00 2001 From: thk123 Date: Wed, 18 Jan 2017 14:14:56 +0000 Subject: [PATCH 120/166] Replaced all instances of show-goto-functions a define This way if the help or command flag wants to change it can be done in one place. Also ensures that all programs that support the --show-goto- functions have it in the help output. Also ensures they all call the correct function which means flags like --json-ui will work as expected. --- src/cbmc/cbmc_parse_options.cpp | 2 +- src/clobber/clobber_parse_options.cpp | 4 ++-- src/clobber/clobber_parse_options.h | 2 ++ src/goto-analyzer/goto_analyzer_parse_options.cpp | 6 ++---- src/goto-analyzer/goto_analyzer_parse_options.h | 4 +++- src/goto-diff/goto_diff_parse_options.cpp | 13 ++++--------- src/goto-diff/goto_diff_parse_options.h | 3 ++- .../goto_instrument_parse_options.cpp | 4 ++-- src/goto-instrument/goto_instrument_parse_options.h | 4 +++- src/goto-programs/show_goto_functions.h | 6 ++++++ src/symex/symex_parse_options.cpp | 5 ++--- src/symex/symex_parse_options.h | 4 +++- 12 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/cbmc/cbmc_parse_options.cpp b/src/cbmc/cbmc_parse_options.cpp index 4fa9edb7726..1d40a72c58e 100644 --- a/src/cbmc/cbmc_parse_options.cpp +++ b/src/cbmc/cbmc_parse_options.cpp @@ -1121,7 +1121,7 @@ void cbmc_parse_optionst::help() "Program representations:\n" " --show-parse-tree show parse tree\n" " --show-symbol-table show symbol table\n" - " --show-goto-functions show goto program\n" + HELP_SHOW_GOTO_FUNCTIONS "\n" "Program instrumentation options:\n" GOTO_CHECK_HELP diff --git a/src/clobber/clobber_parse_options.cpp b/src/clobber/clobber_parse_options.cpp index bff5e163c4f..99d12b703a1 100644 --- a/src/clobber/clobber_parse_options.cpp +++ b/src/clobber/clobber_parse_options.cpp @@ -425,7 +425,7 @@ bool clobber_parse_optionst::process_goto_program( // show it? if(cmdline.isset("show-goto-functions")) { - goto_functions.output(ns, std::cout); + show_goto_functions(ns, get_ui(), goto_functions); return true; } } @@ -655,7 +655,7 @@ void clobber_parse_optionst::help() " --unsigned-char make \"char\" unsigned by default\n" " --show-parse-tree show parse tree\n" " --show-symbol-table show symbol table\n" - " --show-goto-functions show goto program\n" + HELP_SHOW_GOTO_FUNCTIONS " --ppc-macos set MACOS/PPC architecture\n" " --mm model set memory model (default: sc)\n" " --arch set architecture (default: " diff --git a/src/clobber/clobber_parse_options.h b/src/clobber/clobber_parse_options.h index 8d1705cf0e0..8bbed79e1db 100644 --- a/src/clobber/clobber_parse_options.h +++ b/src/clobber/clobber_parse_options.h @@ -15,6 +15,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include class goto_functionst; class optionst; @@ -22,6 +23,7 @@ class optionst; #define CLOBBER_OPTIONS \ "(depth):(context-bound):(unwind):" \ GOTO_CHECK_OPTIONS \ + OPT_SHOW_GOTO_FUNCTIONS \ "(no-assertions)(no-assumptions)" \ "(error-label):(verbosity):(no-library)" \ "(version)" \ diff --git a/src/goto-analyzer/goto_analyzer_parse_options.cpp b/src/goto-analyzer/goto_analyzer_parse_options.cpp index 4b29d4b8548..8b36f6e71a4 100644 --- a/src/goto-analyzer/goto_analyzer_parse_options.cpp +++ b/src/goto-analyzer/goto_analyzer_parse_options.cpp @@ -406,9 +406,7 @@ bool goto_analyzer_parse_optionst::process_goto_program( // show it? if(cmdline.isset("show-goto-functions")) { - namespacet ns(goto_model.symbol_table); - - goto_model.goto_functions.output(ns, std::cout); + show_goto_functions(goto_model, get_ui()); return true; } @@ -521,7 +519,7 @@ void goto_analyzer_parse_optionst::help() "Program representations:\n" " --show-parse-tree show parse tree\n" " --show-symbol-table show symbol table\n" - " --show-goto-functions show goto program\n" + HELP_SHOW_GOTO_FUNCTIONS " --show-properties show the properties, but don't run analysis\n" "\n" "Other options:\n" diff --git a/src/goto-analyzer/goto_analyzer_parse_options.h b/src/goto-analyzer/goto_analyzer_parse_options.h index 19b44c21910..7b319c8b99b 100644 --- a/src/goto-analyzer/goto_analyzer_parse_options.h +++ b/src/goto-analyzer/goto_analyzer_parse_options.h @@ -15,6 +15,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include class bmct; class goto_functionst; @@ -26,7 +27,8 @@ class optionst; "(classpath):(cp):(main-class):" \ "(16)(32)(64)(LP64)(ILP64)(LLP64)(ILP32)(LP32)" \ "(little-endian)(big-endian)" \ - "(show-goto-functions)(show-loops)" \ + OPT_SHOW_GOTO_FUNCTIONS \ + "(show-loops)" \ "(show-symbol-table)(show-parse-tree)" \ "(show-properties)(show-reachable-properties)(property):" \ "(verbosity):(version)" \ diff --git a/src/goto-diff/goto_diff_parse_options.cpp b/src/goto-diff/goto_diff_parse_options.cpp index c22766492bb..b2a6ae5fd14 100644 --- a/src/goto-diff/goto_diff_parse_options.cpp +++ b/src/goto-diff/goto_diff_parse_options.cpp @@ -334,13 +334,8 @@ int goto_diff_parse_optionst::doit() if(cmdline.isset("show-goto-functions")) { - //ENHANCE: make UI specific - std::cout << "*******************************************************\n"; - namespacet ns1(goto_model1.symbol_table); - goto_model1.goto_functions.output(ns1, std::cout); - std::cout << "*******************************************************\n"; - namespacet ns2(goto_model2.symbol_table); - goto_model2.goto_functions.output(ns2, std::cout); + show_goto_functions(goto_model1, get_ui()); + show_goto_functions(goto_model2, get_ui()); return 0; } @@ -512,7 +507,7 @@ bool goto_diff_parse_optionst::process_goto_program( // show it? if(cmdline.isset("show-goto-functions")) { - goto_functions.output(ns, std::cout); + show_goto_functions(ns, get_ui(), goto_functions); return true; } } @@ -569,7 +564,7 @@ void goto_diff_parse_optionst::help() " goto_diff old new goto binaries to be compared\n" "\n" "Diff options:\n" - " --show-functions show functions (default)\n" + HELP_SHOW_GOTO_FUNCTIONS " --syntactic do syntactic diff (default)\n" " -u | --unified output unified diff\n" " --change-impact | \n" diff --git a/src/goto-diff/goto_diff_parse_options.h b/src/goto-diff/goto_diff_parse_options.h index 822fd59a678..e78bd1537e7 100644 --- a/src/goto-diff/goto_diff_parse_options.h +++ b/src/goto-diff/goto_diff_parse_options.h @@ -15,6 +15,7 @@ Author: Peter Schrammel #include #include +#include #include "goto_diff_languages.h" @@ -23,7 +24,7 @@ class optionst; #define GOTO_DIFF_OPTIONS \ "(json-ui)" \ - "(show-goto-functions)" \ + OPT_SHOW_GOTO_FUNCTIONS \ "(verbosity):(version)" \ "u(unified)(change-impact)(forward-impact)(backward-impact)" \ "(compact-output)" diff --git a/src/goto-instrument/goto_instrument_parse_options.cpp b/src/goto-instrument/goto_instrument_parse_options.cpp index 45a5a964812..d03c5026119 100644 --- a/src/goto-instrument/goto_instrument_parse_options.cpp +++ b/src/goto-instrument/goto_instrument_parse_options.cpp @@ -575,7 +575,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-goto-functions")) { namespacet ns(symbol_table); - goto_functions.output(ns, std::cout); + show_goto_functions(ns, get_ui(), goto_functions); return 0; } @@ -1456,7 +1456,7 @@ void goto_instrument_parse_optionst::help() " --show-properties show the properties\n" " --show-symbol-table show symbol table\n" " --list-symbols list symbols with type information\n" - " --show-goto-functions show goto program\n" + HELP_SHOW_GOTO_FUNCTIONS " --list-undefined-functions list functions without body\n" " --show-struct-alignment show struct members that might be concurrently accessed\n" // NOLINT(*) " --show-natural-loops show natural loop heads\n" diff --git a/src/goto-instrument/goto_instrument_parse_options.h b/src/goto-instrument/goto_instrument_parse_options.h index 70bc292b85a..c348dbebe9b 100644 --- a/src/goto-instrument/goto_instrument_parse_options.h +++ b/src/goto-instrument/goto_instrument_parse_options.h @@ -14,6 +14,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include @@ -43,7 +44,8 @@ Author: Daniel Kroening, kroening@kroening.com "(nondet-volatile)(isr):" \ "(stack-depth):(nondet-static)" \ "(function-enter):(function-exit):(branch):" \ - "(show-goto-functions)(show-value-sets)" \ + OPT_SHOW_GOTO_FUNCTIONS \ + "(show-value-sets)" \ "(show-global-may-alias)" \ "(show-local-bitvector-analysis)(show-custom-bitvector-analysis)" \ "(show-escape-analysis)(escape-analysis)" \ diff --git a/src/goto-programs/show_goto_functions.h b/src/goto-programs/show_goto_functions.h index 1ce37a4cee9..5bb7320963e 100644 --- a/src/goto-programs/show_goto_functions.h +++ b/src/goto-programs/show_goto_functions.h @@ -15,6 +15,12 @@ class goto_functionst; class namespacet; class goto_modelt; +#define OPT_SHOW_GOTO_FUNCTIONS \ + "(show-goto-functions)" + +#define HELP_SHOW_GOTO_FUNCTIONS \ + " --show-goto-functions show goto program\n" + void show_goto_functions( const namespacet &ns, ui_message_handlert::uit ui, diff --git a/src/symex/symex_parse_options.cpp b/src/symex/symex_parse_options.cpp index 7a9227e6f58..4da8133c173 100644 --- a/src/symex/symex_parse_options.cpp +++ b/src/symex/symex_parse_options.cpp @@ -409,8 +409,7 @@ bool symex_parse_optionst::process_goto_program(const optionst &options) // show it? if(cmdline.isset("show-goto-functions")) { - const namespacet ns(goto_model.symbol_table); - goto_model.goto_functions.output(ns, std::cout); + show_goto_functions(goto_model, get_ui()); return true; } } @@ -677,7 +676,7 @@ void symex_parse_optionst::help() " --unsigned-char make \"char\" unsigned by default\n" " --show-parse-tree show parse tree\n" " --show-symbol-table show symbol table\n" - " --show-goto-functions show goto program\n" + HELP_SHOW_GOTO_FUNCTIONS " --ppc-macos set MACOS/PPC architecture\n" " --mm model set memory model (default: sc)\n" " --arch set architecture (default: " diff --git a/src/symex/symex_parse_options.h b/src/symex/symex_parse_options.h index 0ae56a9c6b8..c6276b555bb 100644 --- a/src/symex/symex_parse_options.h +++ b/src/symex/symex_parse_options.h @@ -13,6 +13,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include #include @@ -39,7 +40,8 @@ class optionst; "(ppc-macos)(unsigned-char)" \ "(string-abstraction)(no-arch)(arch):(floatbv)(fixedbv)" \ "(round-to-nearest)(round-to-plus-inf)(round-to-minus-inf)(round-to-zero)" \ - "(show-locs)(show-vcc)(show-properties)(show-goto-functions)" \ + "(show-locs)(show-vcc)(show-properties)" \ + OPT_SHOW_GOTO_FUNCTIONS \ "(property):(trace)(show-trace)(stop-on-fail)(eager-infeasibility)" \ "(no-simplify)(no-unwinding-assertions)(no-propagation)" // the last line is for CBMC-regression testing only From ddc75af77af681d4082d95795629f63ac8ad83eb Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 19 Jan 2017 10:42:22 +0000 Subject: [PATCH 121/166] Renamed the GOTO_CHECK defintions according to the new naming convention --- src/analyses/goto_check.h | 6 +++--- src/cbmc/cbmc_parse_options.cpp | 4 ++-- src/cbmc/cbmc_parse_options.h | 2 +- src/clobber/clobber_parse_options.cpp | 4 ++-- src/clobber/clobber_parse_options.h | 2 +- src/goto-instrument/goto_instrument_parse_options.cpp | 4 ++-- src/goto-instrument/goto_instrument_parse_options.h | 2 +- src/symex/symex_parse_options.cpp | 4 ++-- src/symex/symex_parse_options.h | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/analyses/goto_check.h b/src/analyses/goto_check.h index ee589ca9e70..73f9b2caac4 100644 --- a/src/analyses/goto_check.h +++ b/src/analyses/goto_check.h @@ -29,13 +29,13 @@ void goto_check( const optionst &options, goto_modelt &goto_model); -#define GOTO_CHECK_OPTIONS \ +#define OPT_GOTO_CHECK \ "(bounds-check)(pointer-check)(memory-leak-check)" \ "(div-by-zero-check)(signed-overflow-check)(unsigned-overflow-check)" \ "(pointer-overflow-check)(conversion-check)(undefined-shift-check)" \ "(float-overflow-check)(nan-check)" -#define GOTO_CHECK_HELP \ +#define HELP_GOTO_CHECK \ " --bounds-check enable array bounds checks\n" \ " --pointer-check enable pointer checks\n" \ " --memory-leak-check enable memory leak checks\n" \ @@ -48,7 +48,7 @@ void goto_check( " --float-overflow-check check floating-point for +/-Inf\n" \ " --nan-check check floating-point for NaN\n" \ -#define GOTO_CHECK_PARSE_OPTIONS(cmdline, options) \ +#define PARSE_OPTIONS_GOTO_CHECK(cmdline, options) \ options.set_option("bounds-check", cmdline.isset("bounds-check")); \ options.set_option("pointer-check", cmdline.isset("pointer-check")); \ options.set_option("memory-leak-check", cmdline.isset("memory-leak-check")); \ diff --git a/src/cbmc/cbmc_parse_options.cpp b/src/cbmc/cbmc_parse_options.cpp index 1d40a72c58e..508ea055bef 100644 --- a/src/cbmc/cbmc_parse_options.cpp +++ b/src/cbmc/cbmc_parse_options.cpp @@ -220,7 +220,7 @@ void cbmc_parse_optionst::get_command_line_options(optionst &options) options.set_option("propagation", true); // all checks supported by goto_check - GOTO_CHECK_PARSE_OPTIONS(cmdline, options); + PARSE_OPTIONS_GOTO_CHECK(cmdline, options); // unwind loops in java enum static initialization if(cmdline.isset("java-unwind-enum-static")) @@ -1124,7 +1124,7 @@ void cbmc_parse_optionst::help() HELP_SHOW_GOTO_FUNCTIONS "\n" "Program instrumentation options:\n" - GOTO_CHECK_HELP + HELP_GOTO_CHECK " --no-assertions ignore user assertions\n" " --no-assumptions ignore user assumptions\n" " --error-label label check that label is unreachable\n" diff --git a/src/cbmc/cbmc_parse_options.h b/src/cbmc/cbmc_parse_options.h index 3fcc98231f7..aa5438ae92e 100644 --- a/src/cbmc/cbmc_parse_options.h +++ b/src/cbmc/cbmc_parse_options.h @@ -30,7 +30,7 @@ class optionst; "D:I:(c89)(c99)(c11)(cpp89)(cpp99)(cpp11)" \ "(classpath):(cp):(main-class):" \ "(depth):(partial-loops)(no-unwinding-assertions)(unwinding-assertions)" \ - GOTO_CHECK_OPTIONS \ + OPT_GOTO_CHECK \ "(no-assertions)(no-assumptions)" \ "(xml-ui)(xml-interface)(json-ui)" \ "(smt1)(smt2)(fpa)(cvc3)(cvc4)(boolector)(yices)(z3)(opensmt)(mathsat)" \ diff --git a/src/clobber/clobber_parse_options.cpp b/src/clobber/clobber_parse_options.cpp index 99d12b703a1..e8d325db38b 100644 --- a/src/clobber/clobber_parse_options.cpp +++ b/src/clobber/clobber_parse_options.cpp @@ -112,7 +112,7 @@ void clobber_parse_optionst::get_command_line_options(optionst &options) options.set_option("unwindset", cmdline.get_value("unwindset")); // all checks supported by goto_check - GOTO_CHECK_PARSE_OPTIONS(cmdline, options); + PARSE_OPTIONS_GOTO_CHECK(cmdline, options); // check assertions if(cmdline.isset("no-assertions")) @@ -673,7 +673,7 @@ void clobber_parse_optionst::help() " --round-to-zero IEEE floating point rounding mode\n" "\n" "Program instrumentation options:\n" - GOTO_CHECK_HELP + HELP_GOTO_CHECK " --show-properties show the properties\n" " --no-assertions ignore user assertions\n" " --no-assumptions ignore user assumptions\n" diff --git a/src/clobber/clobber_parse_options.h b/src/clobber/clobber_parse_options.h index 8bbed79e1db..ffd897c9155 100644 --- a/src/clobber/clobber_parse_options.h +++ b/src/clobber/clobber_parse_options.h @@ -22,7 +22,7 @@ class optionst; #define CLOBBER_OPTIONS \ "(depth):(context-bound):(unwind):" \ - GOTO_CHECK_OPTIONS \ + OPT_GOTO_CHECK \ OPT_SHOW_GOTO_FUNCTIONS \ "(no-assertions)(no-assumptions)" \ "(error-label):(verbosity):(no-library)" \ diff --git a/src/goto-instrument/goto_instrument_parse_options.cpp b/src/goto-instrument/goto_instrument_parse_options.cpp index d03c5026119..52c65c3ce37 100644 --- a/src/goto-instrument/goto_instrument_parse_options.cpp +++ b/src/goto-instrument/goto_instrument_parse_options.cpp @@ -884,7 +884,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() options.set_option("assert-to-assume", false); // all checks supported by goto_check - GOTO_CHECK_PARSE_OPTIONS(cmdline, options); + PARSE_OPTIONS_GOTO_CHECK(cmdline, options); // check assertions if(cmdline.isset("no-assertions")) @@ -1463,7 +1463,7 @@ void goto_instrument_parse_optionst::help() "\n" "Safety checks:\n" " --no-assertions ignore user assertions\n" - GOTO_CHECK_HELP + HELP_GOTO_CHECK " --uninitialized-check add checks for uninitialized locals (experimental)\n" // NOLINT(*) " --error-label label check that label is unreachable\n" " --stack-depth n add check that call stack size of non-inlined functions never exceeds n\n" // NOLINT(*) diff --git a/src/goto-instrument/goto_instrument_parse_options.h b/src/goto-instrument/goto_instrument_parse_options.h index c348dbebe9b..c8c992f23e7 100644 --- a/src/goto-instrument/goto_instrument_parse_options.h +++ b/src/goto-instrument/goto_instrument_parse_options.h @@ -23,7 +23,7 @@ Author: Daniel Kroening, kroening@kroening.com "(document-claims-latex)(document-claims-html)" \ "(document-properties-latex)(document-properties-html)" \ "(dump-c)(dump-cpp)(use-system-headers)(dot)(xml)" \ - GOTO_CHECK_OPTIONS \ + OPT_GOTO_CHECK \ /* no-X-check are deprecated and ignored */ \ "(no-bounds-check)(no-pointer-check)(no-div-by-zero-check)" \ "(no-nan-check)" \ diff --git a/src/symex/symex_parse_options.cpp b/src/symex/symex_parse_options.cpp index 4da8133c173..ae6859624dc 100644 --- a/src/symex/symex_parse_options.cpp +++ b/src/symex/symex_parse_options.cpp @@ -119,7 +119,7 @@ void symex_parse_optionst::get_command_line_options(optionst &options) options.set_option("unwindset", cmdline.get_value("unwindset")); // all checks supported by goto_check - GOTO_CHECK_PARSE_OPTIONS(cmdline, options); + PARSE_OPTIONS_GOTO_CHECK(cmdline, options); // check assertions if(cmdline.isset("no-assertions")) @@ -695,7 +695,7 @@ void symex_parse_optionst::help() " --function name set main function name\n" "\n" "Program instrumentation options:\n" - GOTO_CHECK_HELP + HELP_GOTO_CHECK " --no-assertions ignore user assertions\n" " --no-assumptions ignore user assumptions\n" " --error-label label check that label is unreachable\n" diff --git a/src/symex/symex_parse_options.h b/src/symex/symex_parse_options.h index c6276b555bb..a67469d71e5 100644 --- a/src/symex/symex_parse_options.h +++ b/src/symex/symex_parse_options.h @@ -28,7 +28,7 @@ class optionst; "(function):" \ "D:I:" \ "(depth):(context-bound):(branch-bound):(unwind):" \ - GOTO_CHECK_OPTIONS \ + OPT_GOTO_CHECK \ "(no-assertions)(no-assumptions)" \ "(16)(32)(64)(LP64)(ILP64)(LLP64)(ILP32)(LP32)" \ "(little-endian)(big-endian)" \ From 712fed150bb08cd002e00a6dc371b08ee761af48 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 31 Jan 2017 14:25:59 +0000 Subject: [PATCH 122/166] Do not add named vars to used_local_names Commit 67f40196a0f206b0eabbef7081f33afa7f2fca1b accidentally reverted java_bytecode_convert_methodt::variable to an earlier version. This restores the version as of branch smowton/find_scopes_for_anonymous_variables Fixes failure of test cbmc-java/inferlexicalscope1 --- src/java_bytecode/java_bytecode_convert_method.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index fd2a5a0ed91..f9cb121091b 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -171,8 +171,6 @@ const exprt java_bytecode_convert_methodt::variable( else { exprt result=var.symbol_expr; - if(!var.is_parameter) - used_local_names.insert(to_symbol_expr(result)); if(do_cast==CAST_AS_NEEDED && t!=result.type()) result=typecast_exprt(result, t); return result; From edf0edd71423a1b2058f5d81358925cea8043d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Forejt?= Date: Tue, 31 Jan 2017 21:40:01 +0000 Subject: [PATCH 123/166] CPPlint on travis change: it will run, but not produce errors. (#473) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d454d25f806..aa6257791c7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,7 @@ matrix: compiler: clang env: COMPILER=clang++ - env: NAME="CPP-LINT" - script: scripts/run_lint.sh master HEAD + script: scripts/run_lint.sh master HEAD || true script: - make -C src minisat2-download From b6a5436433ec3f60b0f653624c677d27a12d33d9 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sun, 26 Jun 2016 13:22:00 +0000 Subject: [PATCH 124/166] Mark internal functions static --- src/goto-programs/remove_complex.cpp | 18 +++++++++--------- src/goto-programs/remove_vector.cpp | 14 +++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/goto-programs/remove_complex.cpp b/src/goto-programs/remove_complex.cpp index 4bb030299a2..38cd1b6000d 100644 --- a/src/goto-programs/remove_complex.cpp +++ b/src/goto-programs/remove_complex.cpp @@ -12,9 +12,6 @@ Date: September 2014 #include "remove_complex.h" -void remove_complex(typet &); -void remove_complex(exprt &); - /*******************************************************************\ Function: complex_member @@ -27,7 +24,7 @@ Function: complex_member \*******************************************************************/ -exprt complex_member(const exprt &expr, irep_idt id) +static exprt complex_member(const exprt &expr, irep_idt id) { if(expr.id()==ID_struct && expr.operands().size()==2) { @@ -60,7 +57,9 @@ Purpose: removes complex data type \*******************************************************************/ -void remove_complex(exprt &expr) +static void remove_complex(typet &); + +static void remove_complex(exprt &expr) { if(expr.id()==ID_typecast) { @@ -200,7 +199,7 @@ Purpose: removes complex data type \*******************************************************************/ -void remove_complex(typet &type) +static void remove_complex(typet &type) { if(type.id()==ID_struct || type.id()==ID_union) { @@ -250,7 +249,7 @@ Purpose: removes complex data type \*******************************************************************/ -void remove_complex(symbolt &symbol) +static void remove_complex(symbolt &symbol) { remove_complex(symbol.value); remove_complex(symbol.type); @@ -286,7 +285,8 @@ Purpose: removes complex data type \*******************************************************************/ -void remove_complex(goto_functionst::goto_functiont &goto_function) +static void remove_complex( + goto_functionst::goto_functiont &goto_function) { remove_complex(goto_function.type); @@ -309,7 +309,7 @@ Purpose: removes complex data type \*******************************************************************/ -void remove_complex(goto_functionst &goto_functions) +static void remove_complex(goto_functionst &goto_functions) { Forall_goto_functions(it, goto_functions) remove_complex(it->second); diff --git a/src/goto-programs/remove_vector.cpp b/src/goto-programs/remove_vector.cpp index 90df83ca43b..02d9d2e8fab 100644 --- a/src/goto-programs/remove_vector.cpp +++ b/src/goto-programs/remove_vector.cpp @@ -12,8 +12,6 @@ Date: September 2014 #include "remove_vector.h" -void remove_vector(typet &); -void remove_vector(exprt &); /*******************************************************************\ @@ -27,7 +25,9 @@ Purpose: removes vector data type \*******************************************************************/ -void remove_vector(exprt &expr) +static void remove_vector(typet &); + +static void remove_vector(exprt &expr) { Forall_operands(it, expr) remove_vector(*it); @@ -109,7 +109,7 @@ Purpose: removes vector data type \*******************************************************************/ -void remove_vector(typet &type) +static void remove_vector(typet &type) { if(type.id()==ID_struct || type.id()==ID_union) { @@ -155,7 +155,7 @@ Purpose: removes vector data type \*******************************************************************/ -void remove_vector(symbolt &symbol) +static void remove_vector(symbolt &symbol) { remove_vector(symbol.value); remove_vector(symbol.type); @@ -173,7 +173,7 @@ Purpose: removes vector data type \*******************************************************************/ -void remove_vector(symbol_tablet &symbol_table) +static void remove_vector(symbol_tablet &symbol_table) { Forall_symbols(it, symbol_table.symbols) remove_vector(it->second); @@ -214,7 +214,7 @@ Purpose: removes vector data type \*******************************************************************/ -void remove_vector(goto_functionst &goto_functions) +static void remove_vector(goto_functionst &goto_functions) { Forall_goto_functions(it, goto_functions) remove_vector(it->second); From 4adb505f71d48eb0868bfd82a696650cd194ea97 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sun, 26 Jun 2016 13:23:39 +0000 Subject: [PATCH 125/166] remove_complex: modify expressions only when necessary --- src/goto-programs/remove_complex.cpp | 90 ++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/goto-programs/remove_complex.cpp b/src/goto-programs/remove_complex.cpp index 38cd1b6000d..44539fb5f1e 100644 --- a/src/goto-programs/remove_complex.cpp +++ b/src/goto-programs/remove_complex.cpp @@ -47,6 +47,90 @@ static exprt complex_member(const exprt &expr, irep_idt id) /*******************************************************************\ +Function: have_to_remove_complex + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +static bool have_to_remove_complex(const typet &type); + +static bool have_to_remove_complex(const exprt &expr) +{ + if(expr.id()==ID_typecast && + to_typecast_expr(expr).op().type().id()==ID_complex && + expr.type().id()!=ID_complex) + return true; + + if(expr.type().id()==ID_complex) + { + if(expr.id()==ID_plus || expr.id()==ID_minus || + expr.id()==ID_mult || expr.id()==ID_div) + return true; + else if(expr.id()==ID_unary_minus) + return true; + else if(expr.id()==ID_complex) + return true; + else if(expr.id()==ID_typecast) + return true; + } + + if(expr.id()==ID_complex_real) + return true; + else if(expr.id()==ID_complex_imag) + return true; + + if(have_to_remove_complex(expr.type())) + return true; + + forall_operands(it, expr) + if(have_to_remove_complex(*it)) + return true; + + return false; +} + +/*******************************************************************\ + +Function: have_to_remove_complex + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +static bool have_to_remove_complex(const typet &type) +{ + if(type.id()==ID_struct || type.id()==ID_union) + { + const struct_union_typet &struct_union_type= + to_struct_union_type(type); + for(struct_union_typet::componentst::const_iterator + it=struct_union_type.components().begin(); + it!=struct_union_type.components().end(); + it++) + if(have_to_remove_complex(it->type())) + return true; + } + else if(type.id()==ID_pointer || + type.id()==ID_vector || + type.id()==ID_array) + return have_to_remove_complex(type.subtype()); + else if(type.id()==ID_complex) + return true; + + return false; +} + +/*******************************************************************\ + Function: remove_complex Inputs: @@ -61,6 +145,9 @@ static void remove_complex(typet &); static void remove_complex(exprt &expr) { + if(!have_to_remove_complex(expr)) + return; + if(expr.id()==ID_typecast) { assert(expr.operands().size()==1); @@ -201,6 +288,9 @@ Purpose: removes complex data type static void remove_complex(typet &type) { + if(!have_to_remove_complex(type)) + return; + if(type.id()==ID_struct || type.id()==ID_union) { struct_union_typet &struct_union_type= From a7c6880c55b57f1ed6b1c289f79f0f680c6f4ab5 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sun, 26 Jun 2016 13:24:45 +0000 Subject: [PATCH 126/166] remove_vector: modify expressions only when necessary --- src/goto-programs/remove_vector.cpp | 80 +++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/goto-programs/remove_vector.cpp b/src/goto-programs/remove_vector.cpp index 02d9d2e8fab..f7b63e42d4f 100644 --- a/src/goto-programs/remove_vector.cpp +++ b/src/goto-programs/remove_vector.cpp @@ -12,6 +12,80 @@ Date: September 2014 #include "remove_vector.h" +/*******************************************************************\ + +Function: have_to_remove_vector + +Inputs: + +Outputs: + +Purpose: + +\*******************************************************************/ + +static bool have_to_remove_vector(const typet &type); + +static bool have_to_remove_vector(const exprt &expr) +{ + if(expr.type().id()==ID_vector) + { + if(expr.id()==ID_plus || expr.id()==ID_minus || + expr.id()==ID_mult || expr.id()==ID_div || + expr.id()==ID_mod || expr.id()==ID_bitxor || + expr.id()==ID_bitand || expr.id()==ID_bitor) + return true; + else if(expr.id()==ID_unary_minus || expr.id()==ID_bitnot) + return true; + else if(expr.id()==ID_vector) + return true; + } + + if(have_to_remove_vector(expr.type())) + return true; + + forall_operands(it, expr) + if(have_to_remove_vector(*it)) + return true; + + return false; +} + +/*******************************************************************\ + +Function: have_to_remove_vector + +Inputs: + +Outputs: + +Purpose: + +\*******************************************************************/ + +static bool have_to_remove_vector(const typet &type) +{ + if(type.id()==ID_struct || type.id()==ID_union) + { + const struct_union_typet &struct_union_type= + to_struct_union_type(type); + + for(struct_union_typet::componentst::const_iterator + it=struct_union_type.components().begin(); + it!=struct_union_type.components().end(); + it++) + if(have_to_remove_vector(it->type())) + return true; + } + else if(type.id()==ID_pointer || + type.id()==ID_complex || + type.id()==ID_array) + return have_to_remove_vector(type.subtype()); + else if(type.id()==ID_vector) + return true; + + return false; +} /*******************************************************************\ @@ -29,6 +103,9 @@ static void remove_vector(typet &); static void remove_vector(exprt &expr) { + if(!have_to_remove_vector(expr)) + return; + Forall_operands(it, expr) remove_vector(*it); @@ -111,6 +188,9 @@ Purpose: removes vector data type static void remove_vector(typet &type) { + if(!have_to_remove_vector(type)) + return; + if(type.id()==ID_struct || type.id()==ID_union) { struct_union_typet &struct_union_type= From d38ccff8db1991b1bd7d2d9d9a8e1e852e2d9e19 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sat, 25 Jun 2016 21:01:32 +0200 Subject: [PATCH 127/166] Apply adjust_float_expressions, rewrite_union just once per expression These should be applied once across all goto functions instead of possibly applying them multiple times to the same source expression during symbolic execution. Signed-off-by: Michael Tautschnig --- src/cbmc/cbmc_parse_options.cpp | 6 ++ src/goto-symex/adjust_float_expressions.cpp | 72 +++++++++++++++++++++ src/goto-symex/adjust_float_expressions.h | 11 +++- src/goto-symex/rewrite_union.cpp | 63 ++++++++++++++++++ src/goto-symex/rewrite_union.h | 13 +++- src/goto-symex/symex_clean_expr.cpp | 4 -- src/path-symex/path_symex_state_read.cpp | 21 ++---- src/symex/symex_parse_options.cpp | 5 ++ 8 files changed, 171 insertions(+), 24 deletions(-) diff --git a/src/cbmc/cbmc_parse_options.cpp b/src/cbmc/cbmc_parse_options.cpp index 508ea055bef..87a9c969981 100644 --- a/src/cbmc/cbmc_parse_options.cpp +++ b/src/cbmc/cbmc_parse_options.cpp @@ -39,6 +39,9 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include +#include + #include #include #include @@ -898,10 +901,13 @@ bool cbmc_parse_optionst::process_goto_program( remove_returns(symbol_table, goto_functions); remove_vector(symbol_table, goto_functions); remove_complex(symbol_table, goto_functions); + rewrite_union(goto_functions, ns); // add generic checks status() << "Generic Property Instrumentation" << eom; goto_check(ns, options, goto_functions); + // checks don't know about adjusted float expressions + adjust_float_expressions(goto_functions, ns); // ignore default/user-specified initialization // of variables with static lifetime diff --git a/src/goto-symex/adjust_float_expressions.cpp b/src/goto-symex/adjust_float_expressions.cpp index 94048db8e5f..97ef7f56fe2 100644 --- a/src/goto-symex/adjust_float_expressions.cpp +++ b/src/goto-symex/adjust_float_expressions.cpp @@ -13,6 +13,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include + #include "adjust_float_expressions.h" /*******************************************************************\ @@ -32,6 +34,15 @@ void adjust_float_expressions( exprt &expr, const namespacet &ns) { + if(expr.id()==ID_floatbv_plus || + expr.id()==ID_floatbv_minus || + expr.id()==ID_floatbv_mult || + expr.id()==ID_floatbv_div || + expr.id()==ID_floatbv_div || + expr.id()==ID_floatbv_rem || + expr.id()==ID_floatbv_typecast) + return; + Forall_operands(it, expr) adjust_float_expressions(*it, ns); @@ -126,3 +137,64 @@ void adjust_float_expressions( } } } + +/*******************************************************************\ + +Function: adjust_float_expressions + +Inputs: + +Outputs: + +Purpose: + +\*******************************************************************/ + +static void adjust_float_expressions( + goto_functionst::goto_functiont &goto_function, + const namespacet &ns) +{ + Forall_goto_program_instructions(it, goto_function.body) + { + adjust_float_expressions(it->code, ns); + adjust_float_expressions(it->guard, ns); + } +} + +/*******************************************************************\ + +Function: adjust_float_expressions + +Inputs: + +Outputs: + +Purpose: + +\*******************************************************************/ + +void adjust_float_expressions( + goto_functionst &goto_functions, + const namespacet &ns) +{ + Forall_goto_functions(it, goto_functions) + adjust_float_expressions(it->second, ns); +} + +/*******************************************************************\ + +Function: adjust_float_expressions + +Inputs: + +Outputs: + +Purpose: + +\*******************************************************************/ + +void adjust_float_expressions(goto_modelt &goto_model) +{ + namespacet ns(goto_model.symbol_table); + adjust_float_expressions(goto_model.goto_functions, ns); +} diff --git a/src/goto-symex/adjust_float_expressions.h b/src/goto-symex/adjust_float_expressions.h index c8c87260996..f8547c59fa8 100644 --- a/src/goto-symex/adjust_float_expressions.h +++ b/src/goto-symex/adjust_float_expressions.h @@ -9,11 +9,18 @@ Author: Daniel Kroening, kroening@kroening.com #ifndef CPROVER_GOTO_SYMEX_ADJUST_FLOAT_EXPRESSIONS_H #define CPROVER_GOTO_SYMEX_ADJUST_FLOAT_EXPRESSIONS_H -#include -#include +class exprt; +class namespacet; +class goto_functionst; +class goto_modelt; void adjust_float_expressions( exprt &expr, const namespacet &ns); +void adjust_float_expressions( + goto_functionst &goto_functions, + const namespacet &ns); +void adjust_float_expressions(goto_modelt &goto_model); + #endif // CPROVER_GOTO_SYMEX_ADJUST_FLOAT_EXPRESSIONS_H diff --git a/src/goto-symex/rewrite_union.cpp b/src/goto-symex/rewrite_union.cpp index 903ec267466..dcab678d5d7 100644 --- a/src/goto-symex/rewrite_union.cpp +++ b/src/goto-symex/rewrite_union.cpp @@ -11,6 +11,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include + #include #include "rewrite_union.h" @@ -57,3 +59,64 @@ void rewrite_union( expr=tmp; } } + +/*******************************************************************\ + +Function: rewrite_union + +Inputs: + +Outputs: + +Purpose: + +\*******************************************************************/ + +static void rewrite_union( + goto_functionst::goto_functiont &goto_function, + const namespacet &ns) +{ + Forall_goto_program_instructions(it, goto_function.body) + { + rewrite_union(it->code, ns); + rewrite_union(it->guard, ns); + } +} + +/*******************************************************************\ + +Function: rewrite_union + +Inputs: + +Outputs: + +Purpose: + +\*******************************************************************/ + +void rewrite_union( + goto_functionst &goto_functions, + const namespacet &ns) +{ + Forall_goto_functions(it, goto_functions) + rewrite_union(it->second, ns); +} + +/*******************************************************************\ + +Function: rewrite_union + +Inputs: + +Outputs: + +Purpose: + +\*******************************************************************/ + +void rewrite_union(goto_modelt &goto_model) +{ + namespacet ns(goto_model.symbol_table); + rewrite_union(goto_model.goto_functions, ns); +} diff --git a/src/goto-symex/rewrite_union.h b/src/goto-symex/rewrite_union.h index 8f406960bc2..7215e0bf0a4 100644 --- a/src/goto-symex/rewrite_union.h +++ b/src/goto-symex/rewrite_union.h @@ -9,11 +9,20 @@ Author: Daniel Kroening, kroening@kroening.com #ifndef CPROVER_GOTO_SYMEX_REWRITE_UNION_H #define CPROVER_GOTO_SYMEX_REWRITE_UNION_H -#include -#include +#include + +class exprt; +class namespacet; +class goto_functionst; +class goto_modelt; void rewrite_union( exprt &expr, const namespacet &ns); +void rewrite_union( + goto_functionst &goto_functions, + const namespacet &ns); +void rewrite_union(goto_modelt &goto_model); + #endif // CPROVER_GOTO_SYMEX_REWRITE_UNION_H diff --git a/src/goto-symex/symex_clean_expr.cpp b/src/goto-symex/symex_clean_expr.cpp index a88075d4a62..e3e650d7b99 100644 --- a/src/goto-symex/symex_clean_expr.cpp +++ b/src/goto-symex/symex_clean_expr.cpp @@ -13,8 +13,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include "adjust_float_expressions.h" -#include "rewrite_union.h" #include "goto_symex.h" /*******************************************************************\ @@ -199,9 +197,7 @@ void goto_symext::clean_expr( statet &state, const bool write) { - rewrite_union(expr, ns); replace_nondet(expr); dereference(expr, state, write); replace_array_equal(expr); - adjust_float_expressions(expr, ns); } diff --git a/src/path-symex/path_symex_state_read.cpp b/src/path-symex/path_symex_state_read.cpp index 33aab3c5fc5..72fbc683f1c 100644 --- a/src/path-symex/path_symex_state_read.cpp +++ b/src/path-symex/path_symex_state_read.cpp @@ -11,9 +11,6 @@ Author: Daniel Kroening, kroening@kroening.com #include -#include -#include - #include "path_symex_state.h" //#define DEBUG @@ -41,21 +38,13 @@ exprt path_symex_statet::read(const exprt &src, bool propagate) //std::cout << "path_symex_statet::read " << src.pretty() << std::endl; #endif - // This has five phases! - // 1. Floating-point expression adjustment (rounding mode) - // 2. Rewrite unions into byte operators - // 3. Dereferencing, including propagation of pointers. - // 4. Rewriting to SSA symbols - // 5. Simplifier - - exprt tmp1=src; - adjust_float_expressions(tmp1, var_map.ns); - - exprt tmp2=tmp1; - rewrite_union(tmp2, var_map.ns); + // This has three phases! + // 1. Dereferencing, including propagation of pointers. + // 2. Rewriting to SSA symbols + // 3. Simplifier // we force propagation for dereferencing - exprt tmp3=dereference_rec(tmp2, true); + exprt tmp3=dereference_rec(src, true); exprt tmp4=instantiate_rec(tmp3, propagate); diff --git a/src/symex/symex_parse_options.cpp b/src/symex/symex_parse_options.cpp index ae6859624dc..9930d9cf43a 100644 --- a/src/symex/symex_parse_options.cpp +++ b/src/symex/symex_parse_options.cpp @@ -33,6 +33,9 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include +#include + #include #include @@ -359,6 +362,8 @@ bool symex_parse_optionst::process_goto_program(const optionst &options) remove_complex(goto_model); remove_vector(goto_model); remove_virtual_functions(goto_model); + rewrite_union(goto_model); + adjust_float_expressions(goto_model); // recalculate numbers, etc. goto_model.goto_functions.update(); From db2f6a4b82d151ba290126beef956de19c1ad6f5 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sun, 26 Jun 2016 13:29:15 +0000 Subject: [PATCH 128/166] rewrite_union, adjust_float_expressions: modify expressions only when necessary --- src/goto-symex/adjust_float_expressions.cpp | 71 +++++++++++++++++++-- src/goto-symex/rewrite_union.cpp | 37 +++++++++++ 2 files changed, 103 insertions(+), 5 deletions(-) diff --git a/src/goto-symex/adjust_float_expressions.cpp b/src/goto-symex/adjust_float_expressions.cpp index 97ef7f56fe2..46dee137447 100644 --- a/src/goto-symex/adjust_float_expressions.cpp +++ b/src/goto-symex/adjust_float_expressions.cpp @@ -19,19 +19,18 @@ Author: Daniel Kroening, kroening@kroening.com /*******************************************************************\ -Function: adjust_float_expressions +Function: have_to_adjust_float_expressions Inputs: Outputs: - Purpose: This adds the rounding mode to floating-point operations, - including those in vectors and complex numbers. + Purpose: \*******************************************************************/ -void adjust_float_expressions( - exprt &expr, +static bool have_to_adjust_float_expressions( + const exprt &expr, const namespacet &ns) { if(expr.id()==ID_floatbv_plus || @@ -41,6 +40,68 @@ void adjust_float_expressions( expr.id()==ID_floatbv_div || expr.id()==ID_floatbv_rem || expr.id()==ID_floatbv_typecast) + return false; + + const typet &type=ns.follow(expr.type()); + + if(type.id()==ID_floatbv || + (type.id()==ID_complex && + ns.follow(type.subtype()).id()==ID_floatbv)) + { + if(expr.id()==ID_plus || expr.id()==ID_minus || + expr.id()==ID_mult || expr.id()==ID_div || + expr.id()==ID_rem) + return true; + } + + if(expr.id()==ID_typecast) + { + const typecast_exprt &typecast_expr=to_typecast_expr(expr); + + const typet &src_type=typecast_expr.op().type(); + const typet &dest_type=typecast_expr.type(); + + if(dest_type.id()==ID_floatbv && + src_type.id()==ID_floatbv) + return true; + else if(dest_type.id()==ID_floatbv && + (src_type.id()==ID_c_bool || + src_type.id()==ID_signedbv || + src_type.id()==ID_unsignedbv || + src_type.id()==ID_c_enum_tag)) + return true; + else if((dest_type.id()==ID_signedbv || + dest_type.id()==ID_unsignedbv || + dest_type.id()==ID_c_enum_tag) && + src_type.id()==ID_floatbv) + return true; + } + + forall_operands(it, expr) + if(have_to_adjust_float_expressions(*it, ns)) + return true; + + return false; +} + +/*******************************************************************\ + +Function: adjust_float_expressions + + Inputs: + + Outputs: + + Purpose: This adds the rounding mode to floating-point operations, + including those in vectors and complex numbers. + +\*******************************************************************/ + +void adjust_float_expressions( + exprt &expr, + const namespacet &ns) +{ + if(!have_to_adjust_float_expressions(expr, ns)) return; Forall_operands(it, expr) diff --git a/src/goto-symex/rewrite_union.cpp b/src/goto-symex/rewrite_union.cpp index dcab678d5d7..f0a329af5ae 100644 --- a/src/goto-symex/rewrite_union.cpp +++ b/src/goto-symex/rewrite_union.cpp @@ -19,6 +19,40 @@ Author: Daniel Kroening, kroening@kroening.com /*******************************************************************\ +Function: have_to_rewrite_union + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +static bool have_to_rewrite_union( + const exprt &expr, + const namespacet &ns) +{ + if(expr.id()==ID_member) + { + const exprt &op=to_member_expr(expr).struct_op(); + const typet &op_type=ns.follow(op.type()); + + if(op_type.id()==ID_union) + return true; + } + else if(expr.id()==ID_union) + return true; + + forall_operands(it, expr) + if(have_to_rewrite_union(*it, ns)) + return true; + + return false; +} + +/*******************************************************************\ + Function: rewrite_union Inputs: @@ -34,6 +68,9 @@ void rewrite_union( exprt &expr, const namespacet &ns) { + if(!have_to_rewrite_union(expr, ns)) + return; + Forall_operands(it, expr) rewrite_union(*it, ns); From 36c87d9dbeac77922df4d41674031e4f2edf49c7 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 14 Dec 2016 11:09:57 +0000 Subject: [PATCH 129/166] Add remove_instanceof pass This lowers instanceof binary operators into classid checks, similar to how remove-virtual-functions uses the class ID to build a virtual dispatch table. --- src/goto-programs/Makefile | 2 +- src/goto-programs/remove_instanceof.cpp | 278 ++++++++++++++++++++++++ src/goto-programs/remove_instanceof.h | 20 ++ 3 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 src/goto-programs/remove_instanceof.cpp create mode 100644 src/goto-programs/remove_instanceof.h diff --git a/src/goto-programs/Makefile b/src/goto-programs/Makefile index 14516b8c38c..326e6e8bce3 100644 --- a/src/goto-programs/Makefile +++ b/src/goto-programs/Makefile @@ -18,7 +18,7 @@ SRC = goto_convert.cpp goto_convert_function_call.cpp \ graphml_witness.cpp remove_virtual_functions.cpp \ class_hierarchy.cpp show_goto_functions.cpp get_goto_model.cpp \ slice_global_inits.cpp goto_inline_class.cpp class_identifier.cpp \ - remove_static_init_loops.cpp + remove_static_init_loops.cpp remove_instanceof.cpp INCLUDES= -I .. diff --git a/src/goto-programs/remove_instanceof.cpp b/src/goto-programs/remove_instanceof.cpp new file mode 100644 index 00000000000..7930a67f4c2 --- /dev/null +++ b/src/goto-programs/remove_instanceof.cpp @@ -0,0 +1,278 @@ +/*******************************************************************\ + +Module: Remove Instance-of Operators + +Author: Chris Smowton, chris.smowton@diffblue.com + +\*******************************************************************/ + +#include "class_hierarchy.h" +#include "class_identifier.h" +#include "remove_instanceof.h" + +#include + +class remove_instanceoft +{ +public: + remove_instanceoft( + symbol_tablet &_symbol_table, + goto_functionst &_goto_functions): + symbol_table(_symbol_table), + ns(_symbol_table), + goto_functions(_goto_functions), + lowered_count(0) + { + class_hierarchy(_symbol_table); + } + + // Lower instanceof for all functions: + void lower_instanceof(); + +protected: + symbol_tablet &symbol_table; + namespacet ns; + class_hierarchyt class_hierarchy; + goto_functionst &goto_functions; + int lowered_count; + + bool lower_instanceof(goto_programt &); + + typedef std::vector< + std::pair> instanceof_instt; + + void lower_instanceof( + goto_programt &, + goto_programt::targett, + instanceof_instt &); + + void lower_instanceof( + exprt &, + goto_programt &, + goto_programt::targett, + instanceof_instt &); + + bool contains_instanceof(const exprt &); +}; + +/*******************************************************************\ + +Function: remove_instanceoft::contains_instanceof + + Inputs: Expression `expr` + + Outputs: Returns true if `expr` contains any instanceof ops + + Purpose: Avoid breaking sharing by checking for instanceof + before calling lower_instanceof. + +\*******************************************************************/ + +bool remove_instanceoft::contains_instanceof( + const exprt &expr) +{ + if(expr.id()==ID_java_instanceof) + return true; + forall_operands(it, expr) + if(contains_instanceof(*it)) + return true; + return false; +} + +/*******************************************************************\ + +Function: remove_instanceoft::lower_instanceof + + Inputs: Expression to lower `expr` and the `goto_program` and + instruction `this_inst` it belongs to. + + Outputs: Side-effect on `expr` replacing it with an explicit clsid test + + Purpose: Replaces an expression like + e instanceof A + with + e.@class_identifier == "A" + Or a big-or of similar expressions if we know of subtypes + that also satisfy the given test. + +\*******************************************************************/ + +void remove_instanceoft::lower_instanceof( + exprt &expr, + goto_programt &goto_program, + goto_programt::targett this_inst, + instanceof_instt &inst_switch) +{ + if(expr.id()==ID_java_instanceof) + { + const exprt &check_ptr=expr.op0(); + assert(check_ptr.type().id()==ID_pointer); + const exprt &target_arg=expr.op1(); + assert(target_arg.id()==ID_type); + const typet &target_type=target_arg.type(); + + // Find all types we know about that satisfy the given requirement: + assert(target_type.id()==ID_symbol); + const irep_idt &target_name= + to_symbol_type(target_type).get_identifier(); + std::vector children= + class_hierarchy.get_children_trans(target_name); + children.push_back(target_name); + + assert(!children.empty() && "Unable to execute instanceof"); + + // Insert an instruction before this one that assigns the clsid we're + // checking against to a temporary, as GOTO program if-expressions should + // not contain derefs. + + symbol_typet jlo("java::java.lang.Object"); + exprt object_clsid=get_class_identifier_field(check_ptr, jlo, ns); + + std::ostringstream symname; + symname << "instanceof_tmp::instanceof_tmp" << (++lowered_count); + auxiliary_symbolt newsym; + newsym.name=symname.str(); + newsym.type=object_clsid.type(); + newsym.base_name=newsym.name; + newsym.mode=ID_java; + newsym.is_type=false; + assert(!symbol_table.add(newsym)); + + auto newinst=goto_program.insert_after(this_inst); + newinst->make_assignment(); + newinst->code=code_assignt(newsym.symbol_expr(), object_clsid); + newinst->source_location=this_inst->source_location; + + // Insert the check instruction after the existing one. + // This will briefly be ill-formed (use before def of + // instanceof_tmp) but the two will subsequently switch + // places in lower_instanceof(goto_programt &) below. + inst_switch.push_back(make_pair(this_inst, newinst)); + // Replace the instanceof construct with a big-or. + exprt::operandst or_ops; + for(const auto &clsname : children) + { + constant_exprt clsexpr(clsname, string_typet()); + equal_exprt test(newsym.symbol_expr(), clsexpr); + or_ops.push_back(test); + } + expr=disjunction(or_ops); + } + else + { + Forall_operands(it, expr) + lower_instanceof(*it, goto_program, this_inst, inst_switch); + } +} + +/*******************************************************************\ + +Function: remove_instanceoft::lower_instanceof + + Inputs: GOTO program instruction `target` whose instanceof expressions, + if any, should be replaced with explicit tests, and the + `goto_program` it is part of. + + Outputs: Side-effect on `target` as above. + + Purpose: See function above + +\*******************************************************************/ + +void remove_instanceoft::lower_instanceof( + goto_programt &goto_program, + goto_programt::targett target, + instanceof_instt &inst_switch) +{ + bool code_iof=contains_instanceof(target->code); + bool guard_iof=contains_instanceof(target->guard); + // The instruction-switching step below will malfunction if a check + // has been added for the code *and* for the guard. This should + // be impossible, because guarded instructions currently have simple + // code (e.g. a guarded-goto), but this assertion checks that this + // assumption is correct and remains true on future evolution of the + // allowable goto instruction types. + assert(!(code_iof && guard_iof)); + if(code_iof) + lower_instanceof(target->code, goto_program, target, inst_switch); + if(guard_iof) + lower_instanceof(target->guard, goto_program, target, inst_switch); +} + +/*******************************************************************\ + +Function: remove_instanceoft::lower_instanceof + + Inputs: `goto_program`, all of whose instanceof expressions will + be replaced by explicit class-identifier tests. + + Outputs: Side-effect on `goto_program` as above. + + Purpose: See function above + +\*******************************************************************/ +bool remove_instanceoft::lower_instanceof(goto_programt &goto_program) +{ + instanceof_instt inst_switch; + Forall_goto_program_instructions(target, goto_program) + lower_instanceof(goto_program, target, inst_switch); + if(!inst_switch.empty()) + { + for(auto &p : inst_switch) + { + const goto_programt::targett &this_inst=p.first; + const goto_programt::targett &newinst=p.second; + this_inst->swap(*newinst); + } + goto_program.update(); + return true; + } + else + return false; +} + +/*******************************************************************\ + +Function: remove_instanceoft::lower_instanceof + + Inputs: None + + Outputs: Side-effects on this->goto_functions, replacing every + instanceof in every function with an explicit test. + + Purpose: See function above + +\*******************************************************************/ + +void remove_instanceoft::lower_instanceof() +{ + bool changed=false; + for(auto &f : goto_functions.function_map) + changed=(lower_instanceof(f.second.body) || changed); + if(changed) + goto_functions.compute_location_numbers(); +} + +/*******************************************************************\ + +Function: remove_instanceof + + Inputs: `goto_functions`, a function map, and the corresponding + `symbol_table`. + + Outputs: Side-effects on goto_functions, replacing every + instanceof in every function with an explicit test. + Extra auxiliary variables may be introduced into + `symbol_table`. + + Purpose: See function above + +\*******************************************************************/ + +void remove_instanceof( + symbol_tablet &symbol_table, + goto_functionst &goto_functions) +{ + remove_instanceoft rem(symbol_table, goto_functions); + rem.lower_instanceof(); +} diff --git a/src/goto-programs/remove_instanceof.h b/src/goto-programs/remove_instanceof.h new file mode 100644 index 00000000000..6adf67b3dd8 --- /dev/null +++ b/src/goto-programs/remove_instanceof.h @@ -0,0 +1,20 @@ +/*******************************************************************\ + +Module: Remove Instance-of Operators + +Author: Chris Smowton, chris.smowton@diffblue.com + +\*******************************************************************/ + +#ifndef CPROVER_GOTO_PROGRAMS_REMOVE_INSTANCEOF_H +#define CPROVER_GOTO_PROGRAMS_REMOVE_INSTANCEOF_H + +#include +#include "goto_functions.h" + +void remove_instanceof( + symbol_tablet &symbol_table, + goto_functionst &goto_functions); + + +#endif From 2e566724028bb4d04588a851cf7e52ee38f79f91 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Thu, 2 Feb 2017 20:34:33 +0000 Subject: [PATCH 130/166] Use container-based Travis builds (#488) This should increase the build performance. Furthermore builds will stop upon the first error instead of trying further make ... commands. --- .travis.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index aa6257791c7..232a4b708ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: cpp -sudo: required +sudo: false matrix: include: @@ -14,7 +14,7 @@ matrix: - libwww-perl - g++-5 before_install: - - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 90 + - mkdir bin ; ln -s /usr/bin/gcc-5 bin/gcc env: COMPILER=g++-5 - os: linux compiler: clang @@ -27,7 +27,7 @@ matrix: - libwww-perl - clang-3.7 before_install: - - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/clang-3.7 90 + - mkdir bin ; ln -s /usr/bin/clang-3.7 bin/gcc env: COMPILER=clang++-3.7 - os: osx compiler: gcc @@ -39,6 +39,8 @@ matrix: script: scripts/run_lint.sh master HEAD || true script: - - make -C src minisat2-download - - make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 && make -C regression test - - make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 aa-symex.dir cegis.dir clobber.dir memory-models.dir musketeer.dir + - if [ -L bin/gcc ] ; then export PATH=$PWD/bin:$PATH ; fi ; + make -C src minisat2-download && + make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 && + make -C regression test && + make -C src CXX=$COMPILER CXXFLAGS="-Wall -O2 -g -Werror -Wno-deprecated-register -pedantic -Wno-sign-compare" -j2 aa-symex.dir cegis.dir clobber.dir memory-models.dir musketeer.dir From cef4870435a2a6b4bfc0e36ff3e1eaec09c9d0fe Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Thu, 2 Feb 2017 20:39:09 +0000 Subject: [PATCH 131/166] Make the pre-commit hook report non-temporary path names (#477) This also fixes the problem of failing to deduce the correct include guards. --- .githooks/pre-commit | 1 + scripts/cpplint.py | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 2649d9bb8cf..25bad813e6b 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -24,6 +24,7 @@ cleanup() trap cleanup EXIT tmpStaging=$(mktemp -d) +touch $tmpStaging/.git # Copy contents of staged version of files to temporary staging area # because we only want the staged version that will be commited and not diff --git a/scripts/cpplint.py b/scripts/cpplint.py index 1b18e338e47..24662915ae5 100755 --- a/scripts/cpplint.py +++ b/scripts/cpplint.py @@ -1220,8 +1220,10 @@ def Error(filename, linenum, category, confidence, message): sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % ( filename, linenum, message, category, confidence)) else: + fileinfo = FileInfo(filename) + path_from_root = fileinfo.RepositoryName() sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( - filename, linenum, message, category, confidence)) + path_from_root, linenum, message, category, confidence)) # Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard. @@ -6469,13 +6471,18 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]): return # Note, if no dot is found, this will give the entire filename as the ext. - file_extension = filename[filename.rfind('.') + 1:] + fileinfo = FileInfo(filename) + path_from_root = fileinfo.RepositoryName() + file_extension = fileinfo.Extension() + if not file_extension: + file_extension = filename[filename.rfind('.')] + file_extension = file_extension[1:] # When reading from stdin, the extension is unknown, so no cpplint tests # should rely on the extension. if filename != '-' and file_extension not in _valid_extensions: sys.stderr.write('Ignoring %s; not a valid file name ' - '(%s)\n' % (filename, ', '.join(_valid_extensions))) + '(%s)\n' % (path_from_root, ', '.join(_valid_extensions))) else: ProcessFileData(filename, file_extension, lines, Error, extra_check_functions) @@ -6498,7 +6505,7 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]): Error(filename, linenum, 'whitespace/newline', 1, 'Unexpected \\r (^M) found; better to use only \\n') - sys.stdout.write('Done processing %s\n' % filename) + sys.stdout.write('Done processing %s\n' % path_from_root) _RestoreFilters() From ae3bb31da0d35d804d4a25e22f91f1feafd4b796 Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 26 Jan 2017 12:41:47 +0000 Subject: [PATCH 132/166] Keep track of types for structs and unions When dealing withs structs (and unions) we replace the type with a symbol for that type (that may or may not be new). However, if a struct is declared, we still need to track any qualifiers (e.g. a variable that is introduced as a const struct). --- src/ansi-c/c_typecheck_type.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ansi-c/c_typecheck_type.cpp b/src/ansi-c/c_typecheck_type.cpp index f6af7da7a1a..78a41a662b5 100644 --- a/src/ansi-c/c_typecheck_type.cpp +++ b/src/ansi-c/c_typecheck_type.cpp @@ -819,7 +819,9 @@ void c_typecheck_baset::typecheck_compound_type(struct_union_typet &type) symbol_type.add_source_location()=type.source_location(); symbol_type.set_identifier(identifier); + c_qualifierst original_qualifiers(type); type.swap(symbol_type); + original_qualifiers.write(type); } /*******************************************************************\ From ecf73db43188176eed9da9a85a211ceb3c6e75b6 Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 26 Jan 2017 12:45:55 +0000 Subject: [PATCH 133/166] Correcting test and adding to the suite The known bug related to this issue was checking the output was wrong, so made it check the correct output. Since it is now fixed, swapped it from KNOWNBUG to CORE. --- regression/goto-instrument/const-struct1/test.desc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/regression/goto-instrument/const-struct1/test.desc b/regression/goto-instrument/const-struct1/test.desc index 40306e23153..8575824dbcb 100644 --- a/regression/goto-instrument/const-struct1/test.desc +++ b/regression/goto-instrument/const-struct1/test.desc @@ -1,7 +1,7 @@ -KNOWNBUG +CORE main.c --show-symbol-table -^Type\.*: struct struct_tag_name$ +^Type\.*: const struct struct_tag_name$ ^Type\.*: const double$ ^EXIT=0$ ^SIGNAL=0$ From af84034ad5ab9c27ff2ee92454cb1bde6b78d50e Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 26 Jan 2017 14:05:32 +0000 Subject: [PATCH 134/166] Added tests for different cases Added cases for union types, for anonymous structs and for volatile variables (as opposed to const variables). Also added test for verifying the dump C output --- regression/goto-instrument/const-struct2/main.c | 10 ++++++++++ regression/goto-instrument/const-struct2/test.desc | 9 +++++++++ regression/goto-instrument/const-struct3/main.c | 13 +++++++++++++ regression/goto-instrument/const-struct3/test.desc | 9 +++++++++ regression/goto-instrument/const-union1/main.c | 13 +++++++++++++ regression/goto-instrument/const-union1/test.desc | 9 +++++++++ regression/goto-instrument/volatile-struct1/main.c | 13 +++++++++++++ .../goto-instrument/volatile-struct1/test.desc | 9 +++++++++ 8 files changed, 85 insertions(+) create mode 100644 regression/goto-instrument/const-struct2/main.c create mode 100644 regression/goto-instrument/const-struct2/test.desc create mode 100644 regression/goto-instrument/const-struct3/main.c create mode 100644 regression/goto-instrument/const-struct3/test.desc create mode 100644 regression/goto-instrument/const-union1/main.c create mode 100644 regression/goto-instrument/const-union1/test.desc create mode 100644 regression/goto-instrument/volatile-struct1/main.c create mode 100644 regression/goto-instrument/volatile-struct1/test.desc diff --git a/regression/goto-instrument/const-struct2/main.c b/regression/goto-instrument/const-struct2/main.c new file mode 100644 index 00000000000..adf97faf658 --- /dev/null +++ b/regression/goto-instrument/const-struct2/main.c @@ -0,0 +1,10 @@ + +int main() +{ + const struct struct_tag_name { + int x; + float y; + } my_struct_var = {.x = 1, .y = 3.15}; + const double z = 4; + return 0; +} diff --git a/regression/goto-instrument/const-struct2/test.desc b/regression/goto-instrument/const-struct2/test.desc new file mode 100644 index 00000000000..8575824dbcb --- /dev/null +++ b/regression/goto-instrument/const-struct2/test.desc @@ -0,0 +1,9 @@ +CORE +main.c +--show-symbol-table +^Type\.*: const struct struct_tag_name$ +^Type\.*: const double$ +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring diff --git a/regression/goto-instrument/const-struct3/main.c b/regression/goto-instrument/const-struct3/main.c new file mode 100644 index 00000000000..fda2dc345f6 --- /dev/null +++ b/regression/goto-instrument/const-struct3/main.c @@ -0,0 +1,13 @@ + +struct struct_tag_name +{ + int x; + float y; +}; + +int main() +{ + const struct struct_tag_name my_struct_var = {.x = 1, .y = 3.15}; + const double z = 4; + return 0; +} diff --git a/regression/goto-instrument/const-struct3/test.desc b/regression/goto-instrument/const-struct3/test.desc new file mode 100644 index 00000000000..430dcf89321 --- /dev/null +++ b/regression/goto-instrument/const-struct3/test.desc @@ -0,0 +1,9 @@ +CORE +main.c +--dump-c +^\s*const struct struct_tag_name my_struct_var +^\s*const double z +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring diff --git a/regression/goto-instrument/const-union1/main.c b/regression/goto-instrument/const-union1/main.c new file mode 100644 index 00000000000..1ba8ba29675 --- /dev/null +++ b/regression/goto-instrument/const-union1/main.c @@ -0,0 +1,13 @@ + +union union_tag_name +{ + int x; + float y; +}; + +int main() +{ + const union union_tag_name my_union_var = {.y = 3.15}; + const double z = 4; + return 0; +} diff --git a/regression/goto-instrument/const-union1/test.desc b/regression/goto-instrument/const-union1/test.desc new file mode 100644 index 00000000000..01de23cf56d --- /dev/null +++ b/regression/goto-instrument/const-union1/test.desc @@ -0,0 +1,9 @@ +CORE +main.c +--show-symbol-table +^Type\.*: const union union_tag_name$ +^Type\.*: const double$ +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring diff --git a/regression/goto-instrument/volatile-struct1/main.c b/regression/goto-instrument/volatile-struct1/main.c new file mode 100644 index 00000000000..7f788eacc21 --- /dev/null +++ b/regression/goto-instrument/volatile-struct1/main.c @@ -0,0 +1,13 @@ + +struct struct_tag_name +{ + int x; + float y; +}; + +int main() +{ + volatile struct struct_tag_name my_struct_var = {.x = 1, .y = 3.15}; + const double z = 4; + return 0; +} diff --git a/regression/goto-instrument/volatile-struct1/test.desc b/regression/goto-instrument/volatile-struct1/test.desc new file mode 100644 index 00000000000..ced4d5c8ddd --- /dev/null +++ b/regression/goto-instrument/volatile-struct1/test.desc @@ -0,0 +1,9 @@ +CORE +main.c +--show-symbol-table +^Type\.*: volatile struct struct_tag_name$ +^Type\.*: const double$ +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring From 332af100a09824cc1a46cac9f7116b866615cebe Mon Sep 17 00:00:00 2001 From: Pascal Kesseli Date: Fri, 3 Feb 2017 13:16:21 +0000 Subject: [PATCH 135/166] Removed zip package Removed temporary zip file. --- .../cegis_control_benchmark_05.zip | Bin 109010 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 regression/cegis/cegis_control_benchmark_05/cegis_control_benchmark_05.zip diff --git a/regression/cegis/cegis_control_benchmark_05/cegis_control_benchmark_05.zip b/regression/cegis/cegis_control_benchmark_05/cegis_control_benchmark_05.zip deleted file mode 100644 index 548a448ce7240ae6347cc5fd91143c73698a531b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109010 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�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 From 7e8a2b349cd80b45c26edc52b3d4e8014e54f334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 3 Feb 2017 14:12:27 +0100 Subject: [PATCH 136/166] specify initial values for Boolean in struct optiont Gave read of uninitilized Boolean value. Just a cleanup, no effect apart from observation via UB check. --- src/util/cmdline.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/util/cmdline.h b/src/util/cmdline.h index 1fb10dd298a..c689c8e3447 100644 --- a/src/util/cmdline.h +++ b/src/util/cmdline.h @@ -39,10 +39,19 @@ class cmdlinet protected: struct optiont { - bool isset, hasval, islong; + bool isset; + bool hasval; + bool islong; char optchar; std::string optstring; std::list values; + public: + optiont(): + isset(false), + hasval(false), + islong(false), + optchar(0) + {} }; std::vector options; From 294c7dbdadb41196ddfa7bc0a124b64090355e2b Mon Sep 17 00:00:00 2001 From: thk123 Date: Fri, 3 Feb 2017 10:42:59 +0000 Subject: [PATCH 137/166] Additions to the gitignore Ignore some more generated files from the regressions folder (.gb files and all the log files. Also removed some redundant lines that are now covered by the **/*.log rule. Added the clobber binary and moved the test-bigint binary to the binaries section. --- .gitignore | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 7987741c045..dd06a376eff 100644 --- a/.gitignore +++ b/.gitignore @@ -25,12 +25,9 @@ src/util/irep_ids.inc # regression/test files *.out -regression/ansi-c/tests.log -regression/symex/tests.log -regression/cbmc-java/tests.log -regression/cbmc/tests.log -src/big-int/test-bigint -src/big-int/test-bigint.exe +regression/**/tests.log +regression/**/*.gb +regression/**/*.smt2 # regression/coverage file /regression/coverage_** @@ -81,6 +78,10 @@ src/symex/symex src/symex/symex.exe src/goto-diff/goto-diff src/goto-diff/goto-diff.exe +src/clobber/clobber +src/clobber/clobber.exe +src/big-int/test-bigint +src/big-int/test-bigint.exe # build tools src/ansi-c/file_converter From 59996f7fca9f1fe236c45baee8fa32f59e28945c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 3 Feb 2017 01:14:07 +0100 Subject: [PATCH 138/166] initialize Boolean values in c_typecheck_baset c_typecheck_baset contains the method `start_typecheck_code()` which is not called for `ansi_c`, only for `cpp`. This method initializes three Boolean values: ``` bool break_is_allowed; bool continue_is_allowed; bool case_is_allowed; ``` This patch adds a call to `start_typecheck_code()` to `ansi_c`, too. The error was observed in `ansi_c/for_scope1`. --- src/ansi-c/ansi_c_typecheck.cpp | 1 + src/ansi-c/c_typecheck_code.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ansi-c/ansi_c_typecheck.cpp b/src/ansi-c/ansi_c_typecheck.cpp index 53daf912dc2..08da6bbae01 100644 --- a/src/ansi-c/ansi_c_typecheck.cpp +++ b/src/ansi-c/ansi_c_typecheck.cpp @@ -22,6 +22,7 @@ Function: ansi_c_typecheckt::typecheck void ansi_c_typecheckt::typecheck() { + start_typecheck_code(); for(ansi_c_parse_treet::itemst::iterator it=parse_tree.items.begin(); it!=parse_tree.items.end(); diff --git a/src/ansi-c/c_typecheck_code.cpp b/src/ansi-c/c_typecheck_code.cpp index 77f3bf3ba50..db02693b26d 100644 --- a/src/ansi-c/c_typecheck_code.cpp +++ b/src/ansi-c/c_typecheck_code.cpp @@ -14,7 +14,7 @@ Author: Daniel Kroening, kroening@kroening.com /*******************************************************************\ -Function: c_typecheck_baset::init +Function: c_typecheck_baset::start_typecheck_code Inputs: From e24d99271e51c349e3a215dd7ad0fa2028607473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 3 Feb 2017 19:58:18 +0100 Subject: [PATCH 139/166] add explicit undef value to format string enums This lead to uninitialized read of length_modifier and representation. While probably not critical, as the respective switches contain a default branch and the compiler seems to allow integral values outside the enum range. --- src/goto-programs/format_strings.h | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/goto-programs/format_strings.h b/src/goto-programs/format_strings.h index 157a8bf96f4..552e3c91b5e 100644 --- a/src/goto-programs/format_strings.h +++ b/src/goto-programs/format_strings.h @@ -30,12 +30,29 @@ class format_tokent typedef enum { ALTERNATE, ZERO_PAD, LEFT_ADJUST, SIGNED_SPACE, SIGN, ASTERISK } flag_typet; - typedef enum { LEN_h, LEN_hh, LEN_l, LEN_ll, LEN_L, LEN_j, LEN_t } length_modifierst; + typedef enum + { + LEN_undef, LEN_h, LEN_hh, LEN_l, LEN_ll, + LEN_L, LEN_j, LEN_t + } length_modifierst; + + typedef enum + { + SIGNED_undef, SIGNED_DEC, UNSIGNED_DEC, + UNSIGNED_OCT, UNSIGNED_HEX + } representationt; + + explicit format_tokent(token_typet _type) + : type(_type), + length_modifier(LEN_undef), + representation(SIGNED_undef) + { } + format_tokent(): + type(UNKNOWN), + length_modifier(LEN_undef), + representation(SIGNED_undef) + { } - typedef enum { SIGNED_DEC, UNSIGNED_DEC, UNSIGNED_OCT, UNSIGNED_HEX } representationt; - - explicit format_tokent(token_typet _type) : type(_type) { } - format_tokent(): type(UNKNOWN) { } token_typet type; std::list flags; From bf09a0bce3f632fcb3b6fad884ce7e9a2f37ae47 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 14 Dec 2016 11:22:40 +0000 Subject: [PATCH 140/166] Use remove_instanceof in driver programs This adds a remove_instanceof call wherever there was an existing remove_virtual_functions call. --- src/cbmc/cbmc_parse_options.cpp | 4 ++++ src/goto-analyzer/goto_analyzer_parse_options.cpp | 4 ++++ src/goto-programs/remove_instanceof.cpp | 6 ++++++ src/goto-programs/remove_instanceof.h | 2 ++ src/symex/symex_parse_options.cpp | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/src/cbmc/cbmc_parse_options.cpp b/src/cbmc/cbmc_parse_options.cpp index 87a9c969981..d09b544c678 100644 --- a/src/cbmc/cbmc_parse_options.cpp +++ b/src/cbmc/cbmc_parse_options.cpp @@ -22,6 +22,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include #include @@ -884,7 +885,10 @@ bool cbmc_parse_optionst::process_goto_program( symbol_table, goto_functions, cmdline.isset("pointer-check")); + // Java virtual functions -> explicit dispatch tables: remove_virtual_functions(symbol_table, goto_functions); + // Java instanceof -> clsid comparison: + remove_instanceof(symbol_table, goto_functions); // full slice? if(cmdline.isset("full-slice")) diff --git a/src/goto-analyzer/goto_analyzer_parse_options.cpp b/src/goto-analyzer/goto_analyzer_parse_options.cpp index 8b36f6e71a4..9e9c4a180bb 100644 --- a/src/goto-analyzer/goto_analyzer_parse_options.cpp +++ b/src/goto-analyzer/goto_analyzer_parse_options.cpp @@ -19,6 +19,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include #include @@ -380,7 +381,10 @@ bool goto_analyzer_parse_optionst::process_goto_program( // remove function pointers status() << "Removing function pointers and virtual functions" << eom; remove_function_pointers(goto_model, cmdline.isset("pointer-check")); + // Java virtual functions -> explicit dispatch tables: remove_virtual_functions(goto_model); + // Java instanceof -> clsid comparison: + remove_instanceof(goto_model); // do partial inlining status() << "Partial Inlining" << eom; diff --git a/src/goto-programs/remove_instanceof.cpp b/src/goto-programs/remove_instanceof.cpp index 7930a67f4c2..ee7f5979332 100644 --- a/src/goto-programs/remove_instanceof.cpp +++ b/src/goto-programs/remove_instanceof.cpp @@ -276,3 +276,9 @@ void remove_instanceof( remove_instanceoft rem(symbol_table, goto_functions); rem.lower_instanceof(); } + +void remove_instanceof(goto_modelt &goto_model) +{ + remove_instanceof( + goto_model.symbol_table, goto_model.goto_functions); +} diff --git a/src/goto-programs/remove_instanceof.h b/src/goto-programs/remove_instanceof.h index 6adf67b3dd8..7b4682ba9bf 100644 --- a/src/goto-programs/remove_instanceof.h +++ b/src/goto-programs/remove_instanceof.h @@ -11,10 +11,12 @@ Author: Chris Smowton, chris.smowton@diffblue.com #include #include "goto_functions.h" +#include "goto_model.h" void remove_instanceof( symbol_tablet &symbol_table, goto_functionst &goto_functions); +void remove_instanceof(goto_modelt &model); #endif diff --git a/src/symex/symex_parse_options.cpp b/src/symex/symex_parse_options.cpp index 9930d9cf43a..148f5b646d1 100644 --- a/src/symex/symex_parse_options.cpp +++ b/src/symex/symex_parse_options.cpp @@ -32,6 +32,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include @@ -361,7 +362,10 @@ bool symex_parse_optionst::process_goto_program(const optionst &options) // remove stuff remove_complex(goto_model); remove_vector(goto_model); + // Java virtual functions -> explicit dispatch tables: remove_virtual_functions(goto_model); + // Java instanceof -> clsid comparison: + remove_instanceof(goto_model); rewrite_union(goto_model); adjust_float_expressions(goto_model); From f25980c3c995195b7c3bcc5f2d2db4514c8000da Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 2 Feb 2017 10:28:18 +0000 Subject: [PATCH 141/166] Add instanceof test cases The first five of these are split up pieces of the existing instanceof1, and the final two are new. The first three (testing array and primitive classids) don't work at present; those dealing with ordinary reference types (3-7) do. --- .../cbmc-java/instanceof1/instanceof1.class | Bin 775 -> 535 bytes .../cbmc-java/instanceof1/instanceof1.java | 12 ------------ .../cbmc-java/instanceof2/instanceof2.class | Bin 0 -> 597 bytes .../cbmc-java/instanceof2/instanceof2.java | 7 +++++++ regression/cbmc-java/instanceof2/test.desc | 8 ++++++++ .../cbmc-java/instanceof3/instanceof3.class | Bin 0 -> 560 bytes .../cbmc-java/instanceof3/instanceof3.java | 7 +++++++ regression/cbmc-java/instanceof3/test.desc | 8 ++++++++ .../cbmc-java/instanceof4/instanceof4.class | Bin 0 -> 564 bytes .../cbmc-java/instanceof4/instanceof4.java | 7 +++++++ regression/cbmc-java/instanceof4/test.desc | 8 ++++++++ .../cbmc-java/instanceof5/instanceof5.class | Bin 0 -> 577 bytes .../cbmc-java/instanceof5/instanceof5.java | 8 ++++++++ regression/cbmc-java/instanceof5/test.desc | 8 ++++++++ regression/cbmc-java/instanceof6/A.class | Bin 0 -> 186 bytes regression/cbmc-java/instanceof6/B.class | Bin 0 -> 171 bytes .../cbmc-java/instanceof6/instanceof6.class | Bin 0 -> 633 bytes .../cbmc-java/instanceof6/instanceof6.java | 15 +++++++++++++++ regression/cbmc-java/instanceof6/test.desc | 8 ++++++++ regression/cbmc-java/instanceof7/A.class | Bin 0 -> 186 bytes regression/cbmc-java/instanceof7/B.class | Bin 0 -> 171 bytes .../cbmc-java/instanceof7/instanceof7.class | Bin 0 -> 633 bytes .../cbmc-java/instanceof7/instanceof7.java | 15 +++++++++++++++ regression/cbmc-java/instanceof7/test.desc | 8 ++++++++ 24 files changed, 107 insertions(+), 12 deletions(-) create mode 100644 regression/cbmc-java/instanceof2/instanceof2.class create mode 100644 regression/cbmc-java/instanceof2/instanceof2.java create mode 100644 regression/cbmc-java/instanceof2/test.desc create mode 100644 regression/cbmc-java/instanceof3/instanceof3.class create mode 100644 regression/cbmc-java/instanceof3/instanceof3.java create mode 100644 regression/cbmc-java/instanceof3/test.desc create mode 100644 regression/cbmc-java/instanceof4/instanceof4.class create mode 100644 regression/cbmc-java/instanceof4/instanceof4.java create mode 100644 regression/cbmc-java/instanceof4/test.desc create mode 100644 regression/cbmc-java/instanceof5/instanceof5.class create mode 100644 regression/cbmc-java/instanceof5/instanceof5.java create mode 100644 regression/cbmc-java/instanceof5/test.desc create mode 100644 regression/cbmc-java/instanceof6/A.class create mode 100644 regression/cbmc-java/instanceof6/B.class create mode 100644 regression/cbmc-java/instanceof6/instanceof6.class create mode 100644 regression/cbmc-java/instanceof6/instanceof6.java create mode 100644 regression/cbmc-java/instanceof6/test.desc create mode 100644 regression/cbmc-java/instanceof7/A.class create mode 100644 regression/cbmc-java/instanceof7/B.class create mode 100644 regression/cbmc-java/instanceof7/instanceof7.class create mode 100644 regression/cbmc-java/instanceof7/instanceof7.java create mode 100644 regression/cbmc-java/instanceof7/test.desc diff --git a/regression/cbmc-java/instanceof1/instanceof1.class b/regression/cbmc-java/instanceof1/instanceof1.class index 8d68b98063b413b0689fd44f3879f4ed1888a913..31bd4c733f4127c7e1ba7e2a941c1bf5b5594f63 100644 GIT binary patch delta 300 zcmYL@y-EW?6otQ;oy;V&t8Uip8h>IN2q*|^W#cp0S&AswL{NJ>trrVnUqG-^!GMBd z>r411;++AtnRDiH&v)*%y*1;{@0T~AX5Eu8=wT@xm1D_c7&wNWWmcN)v*v!I>q#@Z z^qQ~DN|ByS&o2(9hexN!TaML?HAXjAs=l;>0+kQLuDI}%D2hznNK}b-CNtE77{#2t zHV%~p=2;LQR(H^GT0Np$ipd8_OZtl0pV4^_Ssk-pRDhI1$=M5ys+98nUuhjV&@b#W auEm)Ohx{IpN0iQX!k(lrXF%rbYq<$nN8t{Qkw_`I{cFpdV|3d$O z&thT|Ni@9rn~d?!RM<+$Br|vJJ#+3kcYgi({sX`oR$SP)k%x<$9Je@TT{!wahk1_M zIV^D8;aGHW7fTG~B@xFmN>muc&r~crec5GTdkonP6{zG1gWXtu%iwH1qrp@-6e?h-HQu)l#F1F-i=emKP9hcb*7d`wb|U~3(2}3j-oK)xaZ+M9+1CD zRpWQ-4ET?3ES8}#(VnB>VHr(^nY77^Adx*8k>{P=H``R2aJ<#0K@xQ_g_{&jrYmC= z$?k%*cS?@E$vy8WXPk0GQ}D? zf<+4$oWL5Q)I5VdMBx<9?g*KmCRsT__KLK|^2^wADR+kaMD`RmF|pQ|euaw1DZQ3v z8ENz2MqriBhvaUPT)iWK`&3OxZiT8IGSyn8`Wv$xRpd~+@VjP=0W&4{8wx{k=QAAp WE3CA^xpz&Jf#p5b6S{8t*Z%@NzMmfe diff --git a/regression/cbmc-java/instanceof1/instanceof1.java b/regression/cbmc-java/instanceof1/instanceof1.java index c21806a7389..600b8da230e 100644 --- a/regression/cbmc-java/instanceof1/instanceof1.java +++ b/regression/cbmc-java/instanceof1/instanceof1.java @@ -2,18 +2,6 @@ class instanceof1 { public static void main(String[] args) { - // absolutely everything is an Object assert args instanceof Object; - assert int.class instanceof Object; - - // args is an array - assert args instanceof Object[]; - - // string literals are strings - assert "" instanceof String; - - // need a negative example, too - Object o=new Object(); - assert ! (o instanceof String); } }; diff --git a/regression/cbmc-java/instanceof2/instanceof2.class b/regression/cbmc-java/instanceof2/instanceof2.class new file mode 100644 index 0000000000000000000000000000000000000000..c56c25e1934f3ec4f2172c2a2b55f74130c6baf7 GIT binary patch literal 597 zcmYjOO;6iE5Pf4iapD+AfIwQlKMs@wNGP|YRS{6B5?@jfQsA_4mS|~MBirG}6GB?gk4D(+gDm14z4;fIx%2=xDrYe zrq<5)FU5`6>y@nxmti@61QU(d3mX)?&t?Wfn7!gYEBwZ}|SjGyWk`cb^MD`>j zos;(Q9zVUau+!(wG}v(lPfKjID`OSO?pr%{m<-}{Q)gJ@g**HKRIZuXIkWk&74R-N zo8w3vbL&r_J5C6reCN|5F=Y&8&JFZ4th8FYhc(3HJ?uYlhA90+uKk4kZ^O1yw#Shr x`J3~oaAt$1QNZ|H*Lo@hRL0#$6ozn}TR8RutW4u|0>jV2^1qrnC(;&^{{e%ObUOe5 literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/instanceof2/instanceof2.java b/regression/cbmc-java/instanceof2/instanceof2.java new file mode 100644 index 00000000000..dfda558a120 --- /dev/null +++ b/regression/cbmc-java/instanceof2/instanceof2.java @@ -0,0 +1,7 @@ +class instanceof2 +{ + public static void main(String[] args) + { + assert int.class instanceof Object; + } +}; diff --git a/regression/cbmc-java/instanceof2/test.desc b/regression/cbmc-java/instanceof2/test.desc new file mode 100644 index 00000000000..5e10735840b --- /dev/null +++ b/regression/cbmc-java/instanceof2/test.desc @@ -0,0 +1,8 @@ +KNOWNBUG +instanceof2.class + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/instanceof3/instanceof3.class b/regression/cbmc-java/instanceof3/instanceof3.class new file mode 100644 index 0000000000000000000000000000000000000000..b89a0754f2801bf0b8d3131d192c44a8761f09d9 GIT binary patch literal 560 zcmYk2%TB^T6o&t43x!gZiy+=vxIh-NkR8ToP*)M*wi)#5`YD6a@?F6&)0Un%8Vz_yWw zMPvSlA9s7giJA=MNyFXWE%t-J4;V84XeO3ztYDRTObkB|T4<7L_30M0i7P@G2=@<3 z3q(VDphKLaLf1^uby>EoMkA%uN0Wk9CACbEQB2gH!R|>gOw&IZCmC60kR`23o6zEH z=>ggZ`Pv8c5i+kZ&YqEYS6(glS`-P0B2jXrbg&}LkpJu1h%rDepL~Kjf@$2r&>x{q S7{C3MKLO3&QBxM;7PH^3uWSAQ literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/instanceof3/instanceof3.java b/regression/cbmc-java/instanceof3/instanceof3.java new file mode 100644 index 00000000000..2f2f4e64a58 --- /dev/null +++ b/regression/cbmc-java/instanceof3/instanceof3.java @@ -0,0 +1,7 @@ +class instanceof3 +{ + public static void main(String[] args) + { + assert args instanceof Object[]; + } +}; diff --git a/regression/cbmc-java/instanceof3/test.desc b/regression/cbmc-java/instanceof3/test.desc new file mode 100644 index 00000000000..f04f943dc4d --- /dev/null +++ b/regression/cbmc-java/instanceof3/test.desc @@ -0,0 +1,8 @@ +KNOWNBUG +instanceof3.class + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc-java/instanceof4/instanceof4.class b/regression/cbmc-java/instanceof4/instanceof4.class new file mode 100644 index 0000000000000000000000000000000000000000..98ea9b305454aceaee94aa9bc7e8932e7fa2401d GIT binary patch literal 564 zcmZ9I%TB^j5QhKL0tZS}1g&_##09#L4Lga^cv*Q_U`*82p&ZFUY)xBy7+%1&nnE z8AQtW!aWs=dRsOa*abtXsyr2KF_@*bGls;j-;fMrhsu-3otwH0PIWUCZiMm}oYLiC zOWcWaTX@ZKEee#^+|N!rGHh~&?Fl+ zMr>HfGJxv;=?ukTYNx-&eh~NpL-rSqW6{PEmj5tL>MiL;w9t^T+ooI4CJh;?KsE+Q zS|I9Bfevv&98Py7L%E{1Mv+M$IVFpu6wT91evw@7fjv+_Bj}%slZ>P}j8m*zt1#m1 z)FX^83VHJbi7v9QNS^nQde>qj7F+ZZ5e{MU6q#TS(kKjuR$>k?p6AahXmBpNN*Bv74@URJ(}R|w|R^gbcA9yBGPx2k-((>`m+a8DO=;!G%?FfeskJrNgT zz9szQ`C1$*|9D9^cGqIzoo!A@NxW!}N;zb^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBDjkeOFpl9-pAnxAH-mz7wS$iu+Gz{<$L=m?Yp z@%3{O^V0SGld@8iOBfUwn1D8d03#3s6#{8CAWIfVgG5-hwlgqp1WU66Nj9(`H<082 I@|YMn0nG6r!2kdN literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/instanceof6/B.class b/regression/cbmc-java/instanceof6/B.class new file mode 100644 index 0000000000000000000000000000000000000000..aabe922764087c6ec2ba3f888a811e7ff0d84cdf GIT binary patch literal 171 zcmX^0Z`VEs1_l!bUM>b^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBDjkeOFpl9-pAnxAH-mz7wS$iu+Gz{<$L=mf-$ v3_!~+4ZNb^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBDjkeOFpl9-pAnxAH_mz7wS$iu+Gz{<$L=m?Yp z@%3{O^V0SGld@8iOBfUwn1D8d03#3s6#{8CAWIfVgG5-hwlgqp1WU66Nj9(`H<082 I@|YMn0nJn(!Tb^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBDjkeOFpl9-pAnxAH_mz7wS$iu+Gz{<$L=mf-$ v3o1c)K=0b;E9^-%F)jS28{ySPNMfVLSAUZ+p1T3ohkIvoX6DS9ncsiE{Q$6myB_LjOI-C(vi6z>7wsBqxGpj0 zL0a&Jhntv}xFs;NsM1s?nTezHiAhy&p!))1PoT18B9lE7aF&+e2)NsEUkgljO{8~* zCq13Kw#f{fC=&@Zm-f3y>YZ8}sOWGl$PyDBZrZ|$AXDM-OZ7I-m$)rZ-3kY1CInhVm(IELr%4hg0`>puB^G=v;tpAh zf>*sG9cI+L-|cL2m?E-0;2tnujHU$aRW2-ZR&fJc_83L`8!Ix&Y0gRoM6`-!=+aax}Q-QVRps2 z{|oL1)W?v-t3S_R*TSO$w%tm3w+0VR323wLI`91)Rm>8pq4Wpq5|^6 Date: Fri, 3 Feb 2017 10:47:29 +0000 Subject: [PATCH 142/166] goto-instrument: remove virt calls and RTTI This adds remove_virtual_functions and remove_instanceof calls to goto-instrument mirroring the situation in all other driver programs that use remove_function_pointers already. --- .../goto_instrument_parse_options.cpp | 59 ++++++++++--------- .../goto_instrument_parse_options.h | 2 +- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/goto-instrument/goto_instrument_parse_options.cpp b/src/goto-instrument/goto_instrument_parse_options.cpp index 52c65c3ce37..b69d286a467 100644 --- a/src/goto-instrument/goto_instrument_parse_options.cpp +++ b/src/goto-instrument/goto_instrument_parse_options.cpp @@ -17,6 +17,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include +#include #include #include #include @@ -246,7 +248,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-value-sets")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); // recalculate numbers, etc. @@ -263,7 +265,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-global-may-alias")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); do_remove_returns(); parameter_assignments(symbol_table, goto_functions); @@ -281,7 +283,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-local-bitvector-analysis")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); parameter_assignments(symbol_table, goto_functions); @@ -305,7 +307,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-custom-bitvector-analysis")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); do_remove_returns(); parameter_assignments(symbol_table, goto_functions); @@ -331,7 +333,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-escape-analysis")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); do_remove_returns(); parameter_assignments(symbol_table, goto_functions); @@ -351,7 +353,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("custom-bitvector-analysis")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); do_remove_returns(); parameter_assignments(symbol_table, goto_functions); @@ -382,7 +384,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-points-to")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); // recalculate numbers, etc. @@ -399,7 +401,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-intervals")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); // recalculate numbers, etc. @@ -433,7 +435,7 @@ int goto_instrument_parse_optionst::doit() if(!cmdline.isset("inline")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); // recalculate numbers, etc. @@ -460,7 +462,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-reaching-definitions")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); const namespacet ns(symbol_table); reaching_definitions_analysist rd_analysis(ns); @@ -483,7 +485,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("show-dependence-graph")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); const namespacet ns(symbol_table); dependence_grapht dependence_graph(ns); @@ -674,7 +676,7 @@ int goto_instrument_parse_optionst::doit() if(cmdline.isset("accelerate")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); namespacet ns(symbol_table); @@ -757,7 +759,7 @@ int goto_instrument_parse_optionst::doit() /*******************************************************************\ -Function: goto_instrument_parse_optionst::do_function_pointer_removal +Function: goto_instrument_parse_optionst::do_indirect_call_and_rtti_removal Inputs: @@ -767,9 +769,10 @@ Function: goto_instrument_parse_optionst::do_function_pointer_removal \*******************************************************************/ -void goto_instrument_parse_optionst::do_function_pointer_removal() +void goto_instrument_parse_optionst::do_indirect_call_and_rtti_removal( + bool force) { - if(function_pointer_removal_done) + if(function_pointer_removal_done && !force) return; function_pointer_removal_done=true; @@ -779,6 +782,10 @@ void goto_instrument_parse_optionst::do_function_pointer_removal() symbol_table, goto_functions, cmdline.isset("pointer-check")); + status() << "Virtual function removal" << eom; + remove_virtual_functions(symbol_table, goto_functions); + status() << "Java instanceof removal" << eom; + remove_instanceof(symbol_table, goto_functions); } /*******************************************************************\ @@ -954,7 +961,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() // now do full inlining, if requested if(cmdline.isset("inline")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); if(cmdline.isset("show-custom-bitvector-analysis") || cmdline.isset("custom-bitvector-analysis")) @@ -980,7 +987,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() if(cmdline.isset("escape-analysis")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); do_remove_returns(); parameter_assignments(symbol_table, goto_functions); @@ -1009,14 +1016,14 @@ void goto_instrument_parse_optionst::instrument_goto_program() // replace function pointers, if explicitly requested if(cmdline.isset("remove-function-pointers")) - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); if(cmdline.isset("function-inline")) { std::string function=cmdline.get_value("function-inline"); assert(!function.empty()); - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); status() << "Inlining calls of function `" << function << "'" << eom; @@ -1067,7 +1074,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() if(cmdline.isset("partial-inline")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); status() << "Partial inlining" << eom; goto_partial_inline(goto_functions, ns, ui_message_handler, true); @@ -1079,11 +1086,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() // now do full inlining, if requested if(cmdline.isset("inline")) { - status() << "Function Pointer Removal" << eom; - remove_function_pointers( - symbol_table, - goto_functions, - cmdline.isset("pointer-check")); + do_indirect_call_and_rtti_removal(/*force=*/true); if(cmdline.isset("show-custom-bitvector-analysis") || cmdline.isset("custom-bitvector-analysis")) @@ -1099,7 +1102,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() if(cmdline.isset("constant-propagator")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); status() << "Propagating Constants" << eom; @@ -1161,7 +1164,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() cmdline.isset("isr") || cmdline.isset("concurrency")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); do_partial_inlining(); status() << "Pointer Analysis" << eom; @@ -1400,7 +1403,7 @@ void goto_instrument_parse_optionst::instrument_goto_program() // full slice? if(cmdline.isset("full-slice")) { - do_function_pointer_removal(); + do_indirect_call_and_rtti_removal(); status() << "Performing a full slice" << eom; if(cmdline.isset("property")) diff --git a/src/goto-instrument/goto_instrument_parse_options.h b/src/goto-instrument/goto_instrument_parse_options.h index c8c992f23e7..1d74bd94dbf 100644 --- a/src/goto-instrument/goto_instrument_parse_options.h +++ b/src/goto-instrument/goto_instrument_parse_options.h @@ -96,7 +96,7 @@ class goto_instrument_parse_optionst: void eval_verbosity(); - void do_function_pointer_removal(); + void do_indirect_call_and_rtti_removal(bool force=false); void do_partial_inlining(); void do_remove_returns(); From e9712bb804bdf444a41f8c445bf87fba6c81f9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Thu, 2 Feb 2017 17:35:13 +0100 Subject: [PATCH 143/166] read ACC_ABSTRACT attribute in Java class files This adds the initialization of the `is_abstract` and `is_enum` Boolean values to the Java class file parser. It also adds setting the value of `is_abstract` which wasn't done before and could lead to undefined behaviour as an unitialized bool was read in `std::swap(other.is_abstract, is_abstract)`. --- src/java_bytecode/java_bytecode_parse_tree.cpp | 4 ++-- src/java_bytecode/java_bytecode_parse_tree.h | 4 ++-- src/java_bytecode/java_bytecode_parser.cpp | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/java_bytecode/java_bytecode_parse_tree.cpp b/src/java_bytecode/java_bytecode_parse_tree.cpp index e48675d275f..63fb5674f85 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.cpp +++ b/src/java_bytecode/java_bytecode_parse_tree.cpp @@ -34,8 +34,8 @@ void java_bytecode_parse_treet::classt::swap( { other.name.swap(name); other.extends.swap(extends); - other.is_enum=is_enum; - other.enum_elements=enum_elements; + std::swap(other.is_enum, is_enum); + std::swap(other.enum_elements, enum_elements); std::swap(other.is_abstract, is_abstract); other.implements.swap(implements); other.fields.swap(fields); diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index bd62b0e1377..69e4aee7f1f 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -166,8 +166,8 @@ class java_bytecode_parse_treet { public: irep_idt name, extends; - bool is_abstract; - bool is_enum; + bool is_abstract=false; + bool is_enum=false; size_t enum_elements=0; typedef std::list implementst; diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 323ef603af8..012a1c21dea 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -300,6 +300,7 @@ void java_bytecode_parsert::rClassFile() u2 this_class=read_u2(); u2 super_class=read_u2(); + parsed_class.is_abstract=(access_flags&ACC_ABSTRACT)!=0; parsed_class.is_enum=(access_flags&ACC_ENUM)!=0; parsed_class.name= constant(this_class).type().get(ID_C_base_name); From 8e54769fee7196867ccdd2b7a4f61d79891ac5b8 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 28 Oct 2016 16:15:54 +0100 Subject: [PATCH 144/166] Check static array bounds of dynamic objects Previously checking against malloc bounds and against statically-bounded arrays (e.g. int[2]) were mutually exclusive. This enables the static array bounds check even for dynamic objects. Fixes #239. --- regression/cbmc/Pointer_byte_extract5/test.desc | 4 ++-- src/analyses/goto_check.cpp | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/regression/cbmc/Pointer_byte_extract5/test.desc b/regression/cbmc/Pointer_byte_extract5/test.desc index 5c5241acf14..ffd4b6e5750 100644 --- a/regression/cbmc/Pointer_byte_extract5/test.desc +++ b/regression/cbmc/Pointer_byte_extract5/test.desc @@ -3,7 +3,7 @@ main.c --bounds-check --32 ^EXIT=10$ ^SIGNAL=0$ -^\[main\.array_bounds\.5\] array.List upper bound in .*: FAILURE$ -^\*\* 1 of 9 failed (2 iterations)$ +array\.List dynamic object upper bound in p->List\[2\]: FAILURE +\*\* 1 of 11 failed (2 iterations) -- ^warning: ignoring diff --git a/src/analyses/goto_check.cpp b/src/analyses/goto_check.cpp index aa22aa72563..a3f83a80422 100644 --- a/src/analyses/goto_check.cpp +++ b/src/analyses/goto_check.cpp @@ -1193,6 +1193,8 @@ void goto_checkt::bounds_check( } } + exprt type_matches_size=true_exprt(); + if(ode.root_object().id()==ID_dereference) { const exprt &pointer= @@ -1218,13 +1220,18 @@ void goto_checkt::bounds_check( add_guarded_claim( precond, - name+" upper bound", + name+" dynamic object upper bound", "array bounds", expr.find_source_location(), expr, guard); - return; + exprt type_size=size_of_expr(ode.root_object().type(), ns); + if(type_size.is_not_nil()) + type_matches_size= + equal_exprt( + size, + typecast_exprt(type_size, size.type())); } const exprt &size=array_type.id()==ID_array ? @@ -1257,7 +1264,7 @@ void goto_checkt::bounds_check( inequality.op1().make_typecast(inequality.op0().type()); add_guarded_claim( - inequality, + implies_exprt(type_matches_size, inequality), name+" upper bound", "array bounds", expr.find_source_location(), From d8ba38f2dffd4b97bebaad883edd0074081fc118 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sun, 1 Jan 2017 22:40:04 +0000 Subject: [PATCH 145/166] mode!=ID_java is trivially true in this branch This is part of the else { ... } in if(mode==ID_java) { ... } else { ... } --- src/analyses/goto_check.cpp | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/analyses/goto_check.cpp b/src/analyses/goto_check.cpp index a3f83a80422..2f7e4160d71 100644 --- a/src/analyses/goto_check.cpp +++ b/src/analyses/goto_check.cpp @@ -1029,26 +1029,23 @@ void goto_checkt::pointer_validity_check( expr, guard); - if(mode != ID_java) - { - if(flags.is_unknown() || flags.is_dynamic_heap()) - add_guarded_claim( - not_exprt(deallocated(pointer, ns)), - "dereference failure: deallocated dynamic object", - "pointer dereference", - expr.find_source_location(), - expr, - guard); + if(flags.is_unknown() || flags.is_dynamic_heap()) + add_guarded_claim( + not_exprt(deallocated(pointer, ns)), + "dereference failure: deallocated dynamic object", + "pointer dereference", + expr.find_source_location(), + expr, + guard); - if(flags.is_unknown() || flags.is_dynamic_local()) - add_guarded_claim( - not_exprt(dead_object(pointer, ns)), - "dereference failure: dead object", - "pointer dereference", - expr.find_source_location(), - expr, - guard); - } + if(flags.is_unknown() || flags.is_dynamic_local()) + add_guarded_claim( + not_exprt(dead_object(pointer, ns)), + "dereference failure: dead object", + "pointer dereference", + expr.find_source_location(), + expr, + guard); if(enable_bounds_check) { From 735900a4f44c86708fea9744c3f390f35a35a822 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 2 Jan 2017 09:56:32 +0000 Subject: [PATCH 146/166] Limit dereferencing checks to actual access size For member accesses, access to other components need not be valid as shown in the included regression test Malloc23. Also do not require --bounds-check for full dereferencing checks. Fixes #219. --- regression/cbmc/Function5/test.desc | 2 +- regression/cbmc/Malloc23/main.c | 25 +++++ regression/cbmc/Malloc23/test.desc | 12 +++ src/analyses/goto_check.cpp | 102 ++++++++++++------ .../value_set_dereference.cpp | 13 ++- src/util/pointer_predicates.cpp | 83 ++++++++++---- src/util/pointer_predicates.h | 22 +++- 7 files changed, 196 insertions(+), 63 deletions(-) create mode 100644 regression/cbmc/Malloc23/main.c create mode 100644 regression/cbmc/Malloc23/test.desc diff --git a/regression/cbmc/Function5/test.desc b/regression/cbmc/Function5/test.desc index 239e8494e54..3dada8790af 100644 --- a/regression/cbmc/Function5/test.desc +++ b/regression/cbmc/Function5/test.desc @@ -3,6 +3,6 @@ main.c --pointer-check --bounds-check ^SIGNAL=0$ ^EXIT=10$ -^\[.*\] dereference failure: object bounds in \*p: FAILURE$ +^\[.*\] dereference failure: pointer outside object bounds in \*p: FAILURE$ -- ^warning: ignoring diff --git a/regression/cbmc/Malloc23/main.c b/regression/cbmc/Malloc23/main.c new file mode 100644 index 00000000000..e6e192b51ba --- /dev/null +++ b/regression/cbmc/Malloc23/main.c @@ -0,0 +1,25 @@ +#include + +struct A +{ + int x; + int y; +}; + +int main() +{ + struct A *p=malloc(sizeof(int)); + p->x=0; // OK + p->y=0; // out of bounds + + struct A o=*p; // out of bounds + + int *p2=malloc(sizeof(int)); + p2[0]=0; // OK + p2[1]=0; // out of bounds + + ++p2; + p2[0]=0; // out of bounds + + return 0; +} diff --git a/regression/cbmc/Malloc23/test.desc b/regression/cbmc/Malloc23/test.desc new file mode 100644 index 00000000000..6271e2d1865 --- /dev/null +++ b/regression/cbmc/Malloc23/test.desc @@ -0,0 +1,12 @@ +CORE +main.c +--pointer-check +^EXIT=10$ +^SIGNAL=0$ +pointer outside dynamic object bounds in \*p: FAILURE +pointer outside dynamic object bounds in \*p: FAILURE +pointer outside dynamic object bounds in p2\[(signed long int)1\]: FAILURE +pointer outside dynamic object bounds in p2\[(signed long int)0\]: FAILURE +\*\* 4 of 36 failed (3 iterations) +-- +^warning: ignoring diff --git a/src/analyses/goto_check.cpp b/src/analyses/goto_check.cpp index 2f7e4160d71..038e7152230 100644 --- a/src/analyses/goto_check.cpp +++ b/src/analyses/goto_check.cpp @@ -18,6 +18,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include #include #include #include @@ -73,7 +74,11 @@ class goto_checkt void undefined_shift_check(const shift_exprt &expr, const guardt &guard); void pointer_rel_check(const exprt &expr, const guardt &guard); void pointer_overflow_check(const exprt &expr, const guardt &guard); - void pointer_validity_check(const dereference_exprt &expr, const guardt &guard); + void pointer_validity_check( + const dereference_exprt &expr, + const guardt &guard, + const exprt &access_lb, + const exprt &access_ub); void integer_overflow_check(const exprt &expr, const guardt &guard); void conversion_check(const exprt &expr, const guardt &guard); void float_overflow_check(const exprt &expr, const guardt &guard); @@ -966,7 +971,9 @@ Function: goto_checkt::pointer_validity_check void goto_checkt::pointer_validity_check( const dereference_exprt &expr, - const guardt &guard) + const guardt &guard, + const exprt &access_lb, + const exprt &access_ub) { if(!enable_pointer_check) return; @@ -1047,42 +1054,44 @@ void goto_checkt::pointer_validity_check( expr, guard); - if(enable_bounds_check) + if(flags.is_unknown() || flags.is_dynamic_heap()) { - if(flags.is_unknown() || flags.is_dynamic_heap()) - { - exprt dynamic_bounds= - or_exprt(dynamic_object_lower_bound(pointer), - dynamic_object_upper_bound(pointer, dereference_type, ns)); + exprt dynamic_bounds= + or_exprt(dynamic_object_lower_bound(pointer, ns, access_lb), + dynamic_object_upper_bound( + pointer, + dereference_type, + ns, + access_ub)); - add_guarded_claim( - implies_exprt(malloc_object(pointer, ns), not_exprt(dynamic_bounds)), - "dereference failure: dynamic object bounds", - "pointer dereference", - expr.find_source_location(), - expr, - guard); - } + add_guarded_claim( + implies_exprt(malloc_object(pointer, ns), not_exprt(dynamic_bounds)), + "dereference failure: pointer outside dynamic object bounds", + "pointer dereference", + expr.find_source_location(), + expr, + guard); } - if(enable_bounds_check) + if(flags.is_unknown() || + flags.is_dynamic_local() || + flags.is_static_lifetime()) { - if(flags.is_unknown() || - flags.is_dynamic_local() || - flags.is_static_lifetime()) - { - exprt object_bounds= - or_exprt(object_lower_bound(pointer), - object_upper_bound(pointer, dereference_type, ns)); + exprt object_bounds= + or_exprt(object_lower_bound(pointer, ns, access_lb), + object_upper_bound( + pointer, + dereference_type, + ns, + access_ub)); - add_guarded_claim( - or_exprt(dynamic_object(pointer), not_exprt(object_bounds)), - "dereference failure: object bounds", - "pointer dereference", - expr.find_source_location(), - expr, - guard); - } + add_guarded_claim( + or_exprt(dynamic_object(pointer), not_exprt(object_bounds)), + "dereference failure: pointer outside object bounds", + "pointer dereference", + expr.find_source_location(), + expr, + guard); } } } @@ -1130,7 +1139,7 @@ void goto_checkt::bounds_check( typet array_type=ns.follow(expr.array().type()); if(array_type.id()==ID_pointer) - return; // done by the pointer code + throw "index got pointer as array type"; else if(array_type.id()==ID_incomplete_array) throw "index got incomplete array"; else if(array_type.id()!=ID_array && array_type.id()!=ID_vector) @@ -1434,6 +1443,27 @@ void goto_checkt::check_rec( return; } + else if(expr.id()==ID_member && + to_member_expr(expr).struct_op().id()==ID_dereference) + { + const member_exprt &member=to_member_expr(expr); + const dereference_exprt &deref= + to_dereference_expr(member.struct_op()); + + check_rec(deref.op0(), guard, false); + + exprt access_ub=nil_exprt(); + + exprt member_offset=member_offset_expr(member, ns); + exprt size=size_of_expr(expr.type(), ns); + + if(member_offset.is_not_nil() && size.is_not_nil()) + access_ub=plus_exprt(member_offset, size); + + pointer_validity_check(deref, guard, member_offset, access_ub); + + return; + } forall_operands(it, expr) check_rec(*it, guard, false); @@ -1491,7 +1521,11 @@ void goto_checkt::check_rec( expr.id()==ID_ge || expr.id()==ID_gt) pointer_rel_check(expr, guard); else if(expr.id()==ID_dereference) - pointer_validity_check(to_dereference_expr(expr), guard); + pointer_validity_check( + to_dereference_expr(expr), + guard, + nil_exprt(), + size_of_expr(expr.type(), ns)); } /*******************************************************************\ diff --git a/src/pointer-analysis/value_set_dereference.cpp b/src/pointer-analysis/value_set_dereference.cpp index c69e6feda73..c1913567448 100644 --- a/src/pointer-analysis/value_set_dereference.cpp +++ b/src/pointer-analysis/value_set_dereference.cpp @@ -425,7 +425,11 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( // check lower bound guardt tmp_guard(guard); tmp_guard.add(is_malloc_object); - tmp_guard.add(dynamic_object_lower_bound(pointer_expr)); + tmp_guard.add( + dynamic_object_lower_bound( + pointer_expr, + ns, + nil_exprt())); dereference_callback.dereference_failure( "pointer dereference", "dynamic object lower bound", tmp_guard); @@ -439,7 +443,12 @@ value_set_dereferencet::valuet value_set_dereferencet::build_reference_to( guardt tmp_guard(guard); tmp_guard.add(is_malloc_object); - tmp_guard.add(dynamic_object_upper_bound(pointer_expr, dereference_type, ns)); + tmp_guard.add( + dynamic_object_upper_bound( + pointer_expr, + dereference_type, + ns, + size_of_expr(dereference_type, ns))); dereference_callback.dereference_failure( "pointer dereference", "dynamic object upper bound", tmp_guard); diff --git a/src/util/pointer_predicates.cpp b/src/util/pointer_predicates.cpp index 1e1e285e01c..dcbf813ae48 100644 --- a/src/util/pointer_predicates.cpp +++ b/src/util/pointer_predicates.cpp @@ -241,8 +241,15 @@ exprt good_pointer_def( exprt good_dynamic_tmp1= or_exprt( not_exprt(malloc_object(pointer, ns)), - and_exprt(not_exprt(dynamic_object_lower_bound(pointer)), - not_exprt(dynamic_object_upper_bound(pointer, dereference_type, ns)))); + and_exprt(not_exprt(dynamic_object_lower_bound( + pointer, + ns, + nil_exprt())), + not_exprt(dynamic_object_upper_bound( + pointer, + dereference_type, + ns, + size_of_expr(dereference_type, ns))))); exprt good_dynamic_tmp2= and_exprt(not_exprt(deallocated(pointer, ns)), @@ -259,8 +266,12 @@ exprt good_pointer_def( not_exprt(invalid_pointer(pointer)); exprt bad_other= - or_exprt(object_lower_bound(pointer), - object_upper_bound(pointer, dereference_type, ns)); + or_exprt(object_lower_bound(pointer, ns, nil_exprt()), + object_upper_bound( + pointer, + dereference_type, + ns, + size_of_expr(dereference_type, ns))); exprt good_other= or_exprt(dynamic_object(pointer), @@ -357,9 +368,12 @@ Function: dynamic_object_lower_bound \*******************************************************************/ -exprt dynamic_object_lower_bound(const exprt &pointer) +exprt dynamic_object_lower_bound( + const exprt &pointer, + const namespacet &ns, + const exprt &offset) { - return object_lower_bound(pointer); + return object_lower_bound(pointer, ns, offset); } /*******************************************************************\ @@ -377,25 +391,31 @@ Function: dynamic_object_upper_bound exprt dynamic_object_upper_bound( const exprt &pointer, const typet &dereference_type, - const namespacet &ns) + const namespacet &ns, + const exprt &access_size) { // this is - // POINTER_OFFSET(p)+size>__CPROVER_malloc_size + // POINTER_OFFSET(p)+access_size>__CPROVER_malloc_size exprt malloc_size=dynamic_size(ns); exprt object_offset=pointer_offset(pointer); - exprt size=size_of_expr(dereference_type, ns); - // need to add size - exprt sum=plus_exprt(object_offset, size); + irep_idt op=ID_ge; + exprt sum=object_offset; + + if(access_size.is_not_nil()) + { + op=ID_gt; + sum=plus_exprt(object_offset, access_size); + } if(ns.follow(sum.type())!= ns.follow(malloc_size.type())) sum.make_typecast(malloc_size.type()); - return binary_relation_exprt(sum, ID_gt, malloc_size); + return binary_relation_exprt(sum, op, malloc_size); } /*******************************************************************\ @@ -413,25 +433,32 @@ Function: object_upper_bound exprt object_upper_bound( const exprt &pointer, const typet &dereference_type, - const namespacet &ns) + const namespacet &ns, + const exprt &access_size) { // this is - // POINTER_OFFSET(p)+size>OBJECT_SIZE(pointer) + // POINTER_OFFSET(p)+access_size>OBJECT_SIZE(pointer) exprt object_size_expr=object_size(pointer); exprt object_offset=pointer_offset(pointer); - exprt size=size_of_expr(dereference_type, ns); - // need to add size - exprt sum=plus_exprt(object_offset, size); + irep_idt op=ID_ge; + exprt sum=object_offset; + + if(access_size.is_not_nil()) + { + op=ID_gt; + sum=plus_exprt(object_offset, access_size); + } + if(ns.follow(sum.type())!= ns.follow(object_size_expr.type())) sum.make_typecast(object_size_expr.type()); - return binary_relation_exprt(sum, ID_gt, object_size_expr); + return binary_relation_exprt(sum, op, object_size_expr); } /*******************************************************************\ @@ -446,12 +473,24 @@ Function: object_lower_bound \*******************************************************************/ -exprt object_lower_bound(const exprt &pointer) +exprt object_lower_bound( + const exprt &pointer, + const namespacet &ns, + const exprt &offset) { - exprt offset=pointer_offset(pointer); + exprt p_offset=pointer_offset(pointer); - exprt zero=from_integer(0, offset.type()); + exprt zero=from_integer(0, p_offset.type()); assert(zero.is_not_nil()); - return binary_relation_exprt(offset, ID_lt, zero); + if(offset.is_not_nil()) + { + if(ns.follow(p_offset.type())!=ns.follow(offset.type())) + p_offset= + plus_exprt(p_offset, typecast_exprt(offset, p_offset.type())); + else + p_offset=plus_exprt(p_offset, offset); + } + + return binary_relation_exprt(p_offset, ID_lt, zero); } diff --git a/src/util/pointer_predicates.h b/src/util/pointer_predicates.h index a3b88e80cc6..354c110f3e2 100644 --- a/src/util/pointer_predicates.h +++ b/src/util/pointer_predicates.h @@ -28,9 +28,23 @@ exprt null_object(const exprt &pointer); exprt null_pointer(const exprt &pointer); exprt integer_address(const exprt &pointer); exprt invalid_pointer(const exprt &pointer); -exprt dynamic_object_lower_bound(const exprt &pointer); -exprt dynamic_object_upper_bound(const exprt &pointer, const typet &dereference_type, const namespacet &ns); -exprt object_lower_bound(const exprt &pointer); -exprt object_upper_bound(const exprt &pointer, const typet &dereference_type, const namespacet &ns); +exprt dynamic_object_lower_bound( + const exprt &pointer, + const namespacet &ns, + const exprt &offset); +exprt dynamic_object_upper_bound( + const exprt &pointer, + const typet &dereference_type, + const namespacet &ns, + const exprt &access_size); +exprt object_lower_bound( + const exprt &pointer, + const namespacet &ns, + const exprt &offset); +exprt object_upper_bound( + const exprt &pointer, + const typet &dereference_type, + const namespacet &ns, + const exprt &access_size); #endif // CPROVER_UTIL_POINTER_PREDICATES_H From af193034f2b4850d5e9b72a01639dbc1aef11c4c Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 23 Dec 2016 12:20:10 +0000 Subject: [PATCH 147/166] Making check methods of refinement virtual MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We make `check_SAT` and `check_UNSAT` methods of the bitvector refinement virtual so that it can be overloaded by string refinement. --- src/solvers/refinement/bv_refinement.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solvers/refinement/bv_refinement.h b/src/solvers/refinement/bv_refinement.h index de18da27361..00379373265 100644 --- a/src/solvers/refinement/bv_refinement.h +++ b/src/solvers/refinement/bv_refinement.h @@ -83,8 +83,8 @@ class bv_refinementt:public bv_pointerst void get_values(approximationt &approximation); bool is_in_conflict(approximationt &approximation); - void check_SAT(); - void check_UNSAT(); + virtual void check_SAT(); + virtual void check_UNSAT(); bool progress; // we refine the theory of arrays From 3d1fa7aeaf79add940fd602f1a9e3819ceb4f997 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 23 Dec 2016 12:34:16 +0000 Subject: [PATCH 148/166] Adding identifiers for string expressions and functions --- src/util/irep_ids.txt | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/util/irep_ids.txt b/src/util/irep_ids.txt index bd6c082973f..9bcb7807671 100644 --- a/src/util/irep_ids.txt +++ b/src/util/irep_ids.txt @@ -738,3 +738,66 @@ java_bytecode_index java_instanceof java_super_method_call java_enum_static_unwind +string_constraint +string_not_contains_constraint +cprover_char_literal_func +cprover_string_literal_func +cprover_string_char_at_func +cprover_string_char_set_func +cprover_string_code_point_at_func +cprover_string_code_point_before_func +cprover_string_code_point_count_func +cprover_string_offset_by_code_point_func +cprover_string_compare_to_func +cprover_string_concat_func +cprover_string_concat_int_func +cprover_string_concat_long_func +cprover_string_concat_char_func +cprover_string_concat_bool_func +cprover_string_concat_double_func +cprover_string_concat_float_func +cprover_string_concat_code_point_func +cprover_string_contains_func +cprover_string_copy_func +cprover_string_delete_func +cprover_string_delete_char_at_func +cprover_string_equal_func +cprover_string_equals_ignore_case_func +cprover_string_empty_string_func +cprover_string_endswith_func +cprover_string_format_func +cprover_string_hash_code_func +cprover_string_index_of_func +cprover_string_intern_func +cprover_string_insert_func +cprover_string_insert_int_func +cprover_string_insert_long_func +cprover_string_insert_bool_func +cprover_string_insert_char_func +cprover_string_insert_float_func +cprover_string_insert_double_func +cprover_string_insert_char_array_func +cprover_string_is_prefix_func +cprover_string_is_suffix_func +cprover_string_is_empty_func +cprover_string_last_index_of_func +cprover_string_length_func +cprover_string_data_func +cprover_string_of_int_func +cprover_string_of_int_hex_func +cprover_string_of_long_func +cprover_string_of_bool_func +cprover_string_of_float_func +cprover_string_of_double_func +cprover_string_of_char_func +cprover_string_of_char_array_func +cprover_string_parse_int_func +cprover_string_replace_func +cprover_string_set_length_func +cprover_string_startswith_func +cprover_string_substring_func +cprover_string_to_char_array_func +cprover_string_to_lower_case_func +cprover_string_to_upper_case_func +cprover_string_trim_func +cprover_string_value_of_func \ No newline at end of file From 2da0f17d9db3b1a8c34a0594b5495cee73b248eb Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Tue, 24 Jan 2017 16:28:05 +0000 Subject: [PATCH 149/166] Added a to_unsigned_integer function to arith_tools This function converts a positive integer expression to an unsigned int and returns true in case of an error. --- src/util/arith_tools.cpp | 26 ++++++++++++++++++++++++++ src/util/arith_tools.h | 3 +++ 2 files changed, 29 insertions(+) diff --git a/src/util/arith_tools.cpp b/src/util/arith_tools.cpp index 6acac029673..4df13e8b3a0 100644 --- a/src/util/arith_tools.cpp +++ b/src/util/arith_tools.cpp @@ -114,6 +114,32 @@ bool to_integer(const constant_exprt &expr, mp_integer &int_value) /*******************************************************************\ +Function: to_unsigned_integer + + Inputs: a constant expression and a reference to an unsigned int + + Outputs: an error flag + + Purpose: convert a positive integer expression to an unsigned int + +\*******************************************************************/ + +bool to_unsigned_integer(const constant_exprt &expr, unsigned &uint_value) +{ + mp_integer i; + if(to_integer(expr, i)) + return true; + if(i<0) + return true; + else + { + uint_value=integer2unsigned(i); + return false; + } +} + +/*******************************************************************\ + Function: from_integer Inputs: diff --git a/src/util/arith_tools.h b/src/util/arith_tools.h index 2dbef68b7a3..54f83a2d923 100644 --- a/src/util/arith_tools.h +++ b/src/util/arith_tools.h @@ -22,6 +22,9 @@ bool to_integer(const exprt &expr, mp_integer &int_value); // returns 'true' on error bool to_integer(const constant_exprt &expr, mp_integer &int_value); +// returns 'true' on error +bool to_unsigned_integer(const constant_exprt &expr, unsigned &uint_value); + // assert(false) in case of unsupported type constant_exprt from_integer(const mp_integer &int_value, const typet &type); From edf57dad63cf24a98b2318d51a2bf84f6b9b60fe Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 23 Dec 2016 12:23:28 +0000 Subject: [PATCH 150/166] Class for string types used in the string solver This defines the type for string expressions used by the string solver. These string expressions contains a field length, of type index_type, a field content of type content_type. We also define functions to recognise the C and java string types. --- .../refinement/refined_string_type.cpp | 144 ++++++++++++++++++ src/solvers/refinement/refined_string_type.h | 112 ++++++++++++++ 2 files changed, 256 insertions(+) create mode 100644 src/solvers/refinement/refined_string_type.cpp create mode 100644 src/solvers/refinement/refined_string_type.h diff --git a/src/solvers/refinement/refined_string_type.cpp b/src/solvers/refinement/refined_string_type.cpp new file mode 100644 index 00000000000..cfe44ba4c29 --- /dev/null +++ b/src/solvers/refinement/refined_string_type.cpp @@ -0,0 +1,144 @@ +/********************************************************************\ + +Module: Type for string expressions used by the string solver. + These string expressions contain a field `length`, of type + `index_type`, a field `content` of type `content_type`. + This module also defines functions to recognise the C and java + string types. + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include +#include +#include + +/*******************************************************************\ + +Constructor: refined_string_typet::refined_string_typet + + Inputs: type of characters + +\*******************************************************************/ + +refined_string_typet::refined_string_typet(typet char_type) +{ + infinity_exprt infinite_index(refined_string_typet::index_type()); + array_typet char_array(char_type, infinite_index); + components().emplace_back("length", refined_string_typet::index_type()); + components().emplace_back("content", char_array); +} + +/*******************************************************************\ + +Function: refined_string_typet::is_c_string_type + + Inputs: a type + + Outputs: Boolean telling whether the type is that of C strings + +\*******************************************************************/ + +bool refined_string_typet::is_c_string_type(const typet &type) +{ + return + type.id()==ID_struct && + 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 new file mode 100644 index 00000000000..5ad67cc2c31 --- /dev/null +++ b/src/solvers/refinement/refined_string_type.h @@ -0,0 +1,112 @@ +/********************************************************************\ + +Module: Type for string expressions used by the string solver. + These string expressions contain a field `length`, of type + `index_type`, a field `content` of type `content_type`. + This module also defines functions to recognise the C and java + string types. + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#ifndef CPROVER_SOLVERS_REFINEMENT_REFINED_STRING_TYPE_H +#define CPROVER_SOLVERS_REFINEMENT_REFINED_STRING_TYPE_H + +#include +#include +#include +#include +#include +#include + +// Internal type used for string refinement +class refined_string_typet: public struct_typet +{ +public: + explicit refined_string_typet(typet char_type); + + // Type for the content (list of characters) of a string + const array_typet &get_content_type() const + { + assert(components().size()==2); + return to_array_type(components()[1].type()); + } + + const typet &get_char_type() + { + assert(components().size()==2); + return components()[0].type(); + } + + const typet &get_index_type() const + { + return get_content_type().size().type(); + } + + static typet index_type() + { + return signed_int_type(); + } + + static typet java_index_type() + { + return java_int_type(); + } + + // For C the unrefined string type is __CPROVER_string, for java it is a + // pointer to a struct with tag java.lang.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 typet get_char_type(const exprt &expr) + { + if(is_c_string_type(expr.type())) + return char_type(); + else + return java_char_type(); + } + + static typet get_index_type(const exprt &expr) + { + if(is_c_string_type(expr.type())) + return index_type(); + else + return java_index_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())); + } + + constant_exprt index_of_int(int i) const + { + return from_integer(i, get_index_type()); + } +}; + +const refined_string_typet &to_refined_string_type(const typet &type) +{ + assert(type.id()==ID_struct); + return static_cast(type); +} + +#endif From 651e53d51e27a45116fc8bff3c708fab48bcaa7a Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 23 Dec 2016 12:28:20 +0000 Subject: [PATCH 151/166] Class for string expressions to be used by the string solver --- src/solvers/refinement/string_expr.cpp | 55 +++++++++ src/solvers/refinement/string_expr.h | 150 +++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 src/solvers/refinement/string_expr.cpp create mode 100644 src/solvers/refinement/string_expr.h diff --git a/src/solvers/refinement/string_expr.cpp b/src/solvers/refinement/string_expr.cpp new file mode 100644 index 00000000000..0c284621d8d --- /dev/null +++ b/src/solvers/refinement/string_expr.cpp @@ -0,0 +1,55 @@ +/*******************************************************************\ + +Module: String expressions for the string solver + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include + +unsigned string_exprt::next_symbol_id=1; + +/*******************************************************************\ + +Function: string_exprt::fresh_symbol + + Inputs: a prefix and a type + + Outputs: a symbol of type tp whose name starts with + "string_refinement#" followed by prefix + + Purpose: generate a new symbol expression of the given type with some prefix + +\*******************************************************************/ + +symbol_exprt string_exprt::fresh_symbol( + const irep_idt &prefix, const typet &type) +{ + std::ostringstream buf; + buf << "string_refinement#" << prefix << "#" << (next_symbol_id++); + irep_idt name(buf.str()); + return symbol_exprt(name, type); +} + +/*******************************************************************\ + +Constructor: string_exprt + + Inputs: a type for characters + + Purpose: construct a string expression whose length and content are new + variables + +\*******************************************************************/ + +string_exprt::string_exprt(typet char_type): + struct_exprt(refined_string_typet(char_type)) +{ + refined_string_typet t(char_type); + symbol_exprt length= + fresh_symbol("string_length", refined_string_typet::index_type()); + symbol_exprt content=fresh_symbol("string_content", t.get_content_type()); + move_to_operands(length, content); +} + diff --git a/src/solvers/refinement/string_expr.h b/src/solvers/refinement/string_expr.h new file mode 100644 index 00000000000..29d6b12eae7 --- /dev/null +++ b/src/solvers/refinement/string_expr.h @@ -0,0 +1,150 @@ +/******************************************************************\ + +Module: String expressions for the string solver + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#ifndef CPROVER_SOLVERS_REFINEMENT_STRING_EXPR_H +#define CPROVER_SOLVERS_REFINEMENT_STRING_EXPR_H + +#include + +#include +#include +#include + + +// Expressions that encode strings +class string_exprt: public struct_exprt +{ +public: + // Initialize string from the type of characters + explicit string_exprt(typet char_type); + + // Default uses C character type + string_exprt() : string_exprt(char_type()) {} + + // Generate a new symbol of the given type with a prefix + static symbol_exprt fresh_symbol( + const irep_idt &prefix, const typet &type=bool_typet()); + + // Expression corresponding to the length of the string + const exprt &length() const { return op0(); } + exprt &length() { return op0(); } + + // Expression corresponding to the content (array of characters) of the string + const exprt &content() const { return op1(); } + exprt &content() { return op1(); } + + // Type of the expression as a refined string type + const refined_string_typet &refined_type() const + { + return to_refined_string_type(type()); + } + + static exprt within_bounds(const exprt &idx, const exprt &bound); + + // Expression of the character at position idx in the string + index_exprt operator[] (const exprt &idx) const + { + return index_exprt(content(), idx); + } + + index_exprt operator[] (int i) const + { + return index_exprt(content(), refined_type().index_of_int(i)); + } + + // Comparison on the length of the strings + binary_relation_exprt axiom_for_is_longer_than( + const string_exprt &rhs) const + { + return binary_relation_exprt(length(), ID_ge, rhs.length()); + } + + binary_relation_exprt axiom_for_is_longer_than( + const exprt &rhs) const + { + return binary_relation_exprt(length(), ID_ge, rhs); + } + + binary_relation_exprt axiom_for_is_strictly_longer_than( + const exprt &rhs) const + { + return binary_relation_exprt(rhs, ID_lt, length()); + } + + binary_relation_exprt axiom_for_is_strictly_longer_than( + const string_exprt &rhs) const + { + return binary_relation_exprt(rhs.length(), ID_lt, length()); + } + + binary_relation_exprt axiom_for_is_strictly_longer_than(int i) const + { + return axiom_for_is_strictly_longer_than(refined_type().index_of_int(i)); + } + + binary_relation_exprt axiom_for_is_shorter_than( + const string_exprt &rhs) const + { + return binary_relation_exprt(length(), ID_le, rhs.length()); + } + + binary_relation_exprt axiom_for_is_shorter_than( + const exprt &rhs) const + { + return binary_relation_exprt(length(), ID_le, rhs); + } + + binary_relation_exprt axiom_for_is_shorter_than(int i) const + { + return axiom_for_is_shorter_than(refined_type().index_of_int(i)); + } + + binary_relation_exprt axiom_for_is_strictly_shorter_than( + const string_exprt &rhs) const + { + return binary_relation_exprt(length(), ID_lt, rhs.length()); + } + + binary_relation_exprt axiom_for_is_strictly_shorter_than( + const exprt &rhs) const + { + return binary_relation_exprt(length(), ID_lt, rhs); + } + + equal_exprt axiom_for_has_same_length_as( + const string_exprt &rhs) const + { + return equal_exprt(length(), rhs.length()); + } + + equal_exprt axiom_for_has_length(const exprt &rhs) const + { + return equal_exprt(length(), rhs); + } + + equal_exprt axiom_for_has_length(int i) const + { + return axiom_for_has_length(refined_type().index_of_int(i)); + } + + static irep_idt extract_java_string(const symbol_exprt &s); + + static unsigned next_symbol_id; + + friend inline string_exprt &to_string_expr(exprt &expr); +}; + + +inline string_exprt &to_string_expr(exprt &expr) +{ + assert(expr.id()==ID_struct); + return static_cast(expr); +} + + +#endif From f4fd79c40cfa5c9dbfdb4da850e7d706490d00c6 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 23 Dec 2016 12:30:56 +0000 Subject: [PATCH 152/166] Class for string constraints. String constraints are formula about strings. They can contains universaly quantified variables. --- src/solvers/refinement/string_constraint.h | 183 +++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 src/solvers/refinement/string_constraint.h diff --git a/src/solvers/refinement/string_constraint.h b/src/solvers/refinement/string_constraint.h new file mode 100644 index 00000000000..1f5a56ae9b7 --- /dev/null +++ b/src/solvers/refinement/string_constraint.h @@ -0,0 +1,183 @@ +/*******************************************************************\ + +Module: Defines string constraints. These are formulas talking about strings. + We implemented two forms of constraints: `string_constraintt` + are formulas of the form $\forall univ_var \in [lb,ub[. prem => body$, + and not_contains_constraintt of the form: + $\forall x in [lb,ub[. p(x) => \exists y in [lb,ub[. s1[x+y] != s2[y]$. + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#ifndef CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_H +#define CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_H + +#include +#include +#include + +class string_constraintt: public exprt +{ +public: + // String constraints are of the form + // forall univ_var in [lower_bound,upper_bound[. premise => body + + const exprt &premise() const + { + return op0(); + } + + const exprt &body() const + { + return op1(); + } + + const symbol_exprt &univ_var() const + { + return to_symbol_expr(op2()); + } + + const exprt &upper_bound() const + { + return op3(); + } + + const exprt &lower_bound() const + { + return operands()[4]; + } + + + private: + string_constraintt(); + + public: + string_constraintt( + const symbol_exprt &_univ_var, + const exprt &bound_inf, + const exprt &bound_sup, + const exprt &prem, + const exprt &body): + exprt(ID_string_constraint) + { + copy_to_operands(prem, body); + copy_to_operands(_univ_var, bound_sup, bound_inf); + } + + // Default bound inferior is 0 + string_constraintt( + const symbol_exprt &_univ_var, + const exprt &bound_sup, + const exprt &prem, + const exprt &body): + string_constraintt( + _univ_var, + from_integer(0, _univ_var.type()), + bound_sup, + prem, + body) + {} + + // Default premise is true + string_constraintt( + const symbol_exprt &_univ_var, + const exprt &bound_sup, + const exprt &body): + string_constraintt(_univ_var, bound_sup, true_exprt(), body) + {} + + exprt univ_within_bounds() const + { + return and_exprt( + binary_relation_exprt(lower_bound(), ID_le, univ_var()), + binary_relation_exprt(upper_bound(), ID_gt, univ_var())); + } +}; + +extern inline const string_constraintt &to_string_constraint(const exprt &expr) +{ + assert(expr.id()==ID_string_constraint && expr.operands().size()==5); + return static_cast(expr); +} + +extern inline string_constraintt &to_string_constraint(exprt &expr) +{ + assert(expr.id()==ID_string_constraint && expr.operands().size()==5); + return static_cast(expr); +} + +class string_not_contains_constraintt: public exprt +{ +public: + // string_not contains_constraintt are formula of the form: + // forall x in [lb,ub[. p(x) => exists y in [lb,ub[. s1[x+y] != s2[y] + + string_not_contains_constraintt( + exprt univ_lower_bound, + exprt univ_bound_sup, + exprt premise, + exprt exists_bound_inf, + exprt exists_bound_sup, + exprt s0, + exprt s1) : + exprt(ID_string_not_contains_constraint) + { + copy_to_operands(univ_lower_bound, univ_bound_sup, premise); + copy_to_operands(exists_bound_inf, exists_bound_sup, s0); + copy_to_operands(s1); + }; + + const exprt &univ_lower_bound() const + { + return op0(); + } + + const exprt &univ_upper_bound() const + { + return op1(); + } + + const exprt &premise() const + { + return op2(); + } + + const exprt &exists_lower_bound() const + { + return op3(); + } + + const exprt &exists_upper_bound() const + { + return operands()[4]; + } + + const exprt &s0() const + { + return operands()[5]; + } + + const exprt &s1() const + { + return operands()[6]; + } +}; + +inline const string_not_contains_constraintt +&to_string_not_contains_constraint(const exprt &expr) +{ + assert(expr.id()==ID_string_not_contains_constraint); + assert(expr.operands().size()==7); + return static_cast(expr); +} + +inline string_not_contains_constraintt +&to_string_not_contains_constraint(exprt &expr) +{ + assert(expr.id()==ID_string_not_contains_constraint); + assert(expr.operands().size()==7); + return static_cast(expr); +} + +#endif From df336c33aa759f1c5936ec719b2e88e6f0f5f460 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 23 Dec 2016 12:40:52 +0000 Subject: [PATCH 153/166] Class for generating string constraints from string functions --- .../refinement/string_constraint_generator.h | 315 ++++++++ ...tring_constraint_generator_code_points.cpp | 283 +++++++ ...string_constraint_generator_comparison.cpp | 344 +++++++++ .../string_constraint_generator_concat.cpp | 222 ++++++ .../string_constraint_generator_constants.cpp | 143 ++++ .../string_constraint_generator_indexof.cpp | 285 +++++++ .../string_constraint_generator_insert.cpp | 220 ++++++ .../string_constraint_generator_main.cpp | 700 ++++++++++++++++++ .../string_constraint_generator_testing.cpp | 246 ++++++ ...ng_constraint_generator_transformation.cpp | 460 ++++++++++++ .../string_constraint_generator_valueof.cpp | 646 ++++++++++++++++ 11 files changed, 3864 insertions(+) create mode 100644 src/solvers/refinement/string_constraint_generator.h create mode 100644 src/solvers/refinement/string_constraint_generator_code_points.cpp create mode 100644 src/solvers/refinement/string_constraint_generator_comparison.cpp create mode 100644 src/solvers/refinement/string_constraint_generator_concat.cpp create mode 100644 src/solvers/refinement/string_constraint_generator_constants.cpp create mode 100644 src/solvers/refinement/string_constraint_generator_indexof.cpp create mode 100644 src/solvers/refinement/string_constraint_generator_insert.cpp create mode 100644 src/solvers/refinement/string_constraint_generator_main.cpp create mode 100644 src/solvers/refinement/string_constraint_generator_testing.cpp create mode 100644 src/solvers/refinement/string_constraint_generator_transformation.cpp create mode 100644 src/solvers/refinement/string_constraint_generator_valueof.cpp diff --git a/src/solvers/refinement/string_constraint_generator.h b/src/solvers/refinement/string_constraint_generator.h new file mode 100644 index 00000000000..a78f1473510 --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator.h @@ -0,0 +1,315 @@ +/*******************************************************************\ + +Module: Generates string constraints to link results from string functions + with their arguments. This is inspired by the PASS paper at HVC'13: + "PASS: String Solving with Parameterized Array and Interval Automaton" + by Guodong Li and Indradeep Ghosh, which gives examples of constraints + for several functions. + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#ifndef CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H +#define CPROVER_SOLVERS_REFINEMENT_STRING_CONSTRAINT_GENERATOR_H + +#include +#include +#include +#include + +class string_constraint_generatort +{ +public: + // This module keeps a list of axioms. It has methods which generate + // string constraints for different string funcitons and add them + // to the axiom list. + + string_constraint_generatort(): + mode(ID_unknown), refined_string_type(char_type()) + { } + + void set_mode(irep_idt _mode) + { + // only C and java modes supported + assert((_mode==ID_java) || (_mode==ID_C)); + mode=_mode; + refined_string_type=refined_string_typet(get_char_type()); + } + + irep_idt &get_mode() { return mode; } + + typet get_char_type() const; + typet get_index_type() const + { + if(mode==ID_java) + return refined_string_typet::java_index_type(); + assert(mode==ID_C); + return refined_string_typet::index_type(); + } + + const refined_string_typet &get_refined_string_type() const + { + return refined_string_type; + } + + // Axioms are of three kinds: universally quantified string constraint, + // not contains string constraints and simple formulas. + std::list axioms; + + // Boolean symbols for the results of some string functions + std::list boolean_symbols; + + // Symbols used in existential quantifications + std::list index_symbols; + + // Used to store information about witnesses for not_contains constraints + std::map witness; + + exprt get_witness_of( + const string_not_contains_constraintt &c, + const exprt &univ_val) const + { + return index_exprt(witness.at(c), univ_val); + } + + symbol_exprt fresh_exist_index(const irep_idt &prefix); + symbol_exprt fresh_univ_index(const irep_idt &prefix); + symbol_exprt fresh_boolean(const irep_idt &prefix); + + // We maintain a map from symbols to strings. + std::map symbol_to_string; + + 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 add_axioms_for_string_expr(const exprt &expr); + void set_string_symbol_equal_to_expr( + const symbol_exprt &sym, const exprt &str); + + exprt add_axioms_for_function_application( + const function_application_exprt &expr); + + constant_exprt constant_char(int i) const; + +private: + // The integer with the longest string is Integer.MIN_VALUE which is -2^31, + // that is -2147483648 so takes 11 characters to write. + // The long with the longest string is Long.MIN_VALUE which is -2^63, + // approximately -9.223372037*10^18 so takes 20 characters to write. + const std::size_t MAX_INTEGER_LENGTH=11; + const std::size_t MAX_LONG_LENGTH=20; + const std::size_t MAX_FLOAT_LENGTH=15; + const std::size_t MAX_DOUBLE_LENGTH=30; + + irep_idt extract_java_string(const symbol_exprt &s) const; + + exprt axiom_for_is_positive_index(const exprt &x); + + // The following functions add axioms for the returned value + // to be equal to the result of the function given as argument. + // They are not accessed directly from other classes: they call + // `add_axioms_for_function_application` which determines which of + // these methods should be called. + + exprt add_axioms_for_char_at(const function_application_exprt &f); + exprt add_axioms_for_code_point_at(const function_application_exprt &f); + exprt add_axioms_for_code_point_before(const function_application_exprt &f); + exprt add_axioms_for_contains(const function_application_exprt &f); + exprt add_axioms_for_equals(const function_application_exprt &f); + exprt add_axioms_for_equals_ignore_case(const function_application_exprt &f); + exprt add_axioms_for_data(const function_application_exprt &f); + + // Add axioms corresponding to the String.hashCode java function + // 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); + + exprt add_axioms_for_is_empty(const function_application_exprt &f); + exprt add_axioms_for_is_prefix( + const string_exprt &prefix, const string_exprt &str, const exprt &offset); + exprt add_axioms_for_is_prefix( + const function_application_exprt &f, bool swap_arguments=false); + exprt add_axioms_for_is_suffix( + const function_application_exprt &f, bool swap_arguments=false); + exprt add_axioms_for_length(const function_application_exprt &f); + string_exprt add_axioms_for_empty_string(const function_application_exprt &f); + string_exprt add_axioms_for_char_set(const function_application_exprt &expr); + string_exprt add_axioms_for_copy(const function_application_exprt &f); + string_exprt add_axioms_for_concat( + const string_exprt &s1, const string_exprt &s2); + string_exprt add_axioms_for_concat(const function_application_exprt &f); + string_exprt add_axioms_for_concat_int(const function_application_exprt &f); + string_exprt add_axioms_for_concat_long(const function_application_exprt &f); + string_exprt add_axioms_for_concat_bool(const function_application_exprt &f); + string_exprt add_axioms_for_concat_char(const function_application_exprt &f); + string_exprt add_axioms_for_concat_double( + const function_application_exprt &f); + string_exprt add_axioms_for_concat_float(const function_application_exprt &f); + string_exprt add_axioms_for_concat_code_point( + const function_application_exprt &f); + string_exprt add_axioms_for_constant(irep_idt sval); + string_exprt add_axioms_for_delete( + const string_exprt &str, const exprt &start, const exprt &end); + string_exprt add_axioms_for_delete(const function_application_exprt &expr); + string_exprt add_axioms_for_delete_char_at( + const function_application_exprt &expr); + string_exprt add_axioms_for_insert( + const string_exprt &s1, const string_exprt &s2, const exprt &offset); + string_exprt add_axioms_for_insert(const function_application_exprt &f); + string_exprt add_axioms_for_insert_int(const function_application_exprt &f); + string_exprt add_axioms_for_insert_long(const function_application_exprt &f); + string_exprt add_axioms_for_insert_bool(const function_application_exprt &f); + string_exprt add_axioms_for_insert_char(const function_application_exprt &f); + string_exprt add_axioms_for_insert_double( + const function_application_exprt &f); + string_exprt add_axioms_for_insert_float(const function_application_exprt &f); + string_exprt add_axioms_for_insert_char_array( + const function_application_exprt &f); + string_exprt add_axioms_from_literal(const function_application_exprt &f); + string_exprt add_axioms_from_int(const function_application_exprt &f); + string_exprt add_axioms_from_int(const exprt &i, size_t max_size); + string_exprt add_axioms_from_int_hex(const exprt &i); + string_exprt add_axioms_from_int_hex(const function_application_exprt &f); + string_exprt add_axioms_from_long(const function_application_exprt &f); + string_exprt add_axioms_from_long(const exprt &i, size_t max_size); + string_exprt add_axioms_from_bool(const function_application_exprt &f); + string_exprt add_axioms_from_bool(const exprt &i); + string_exprt add_axioms_from_char(const function_application_exprt &f); + string_exprt add_axioms_from_char(const exprt &i); + string_exprt add_axioms_from_char_array(const function_application_exprt &f); + string_exprt add_axioms_from_char_array( + const exprt &length, + const exprt &data, + const exprt &offset, + const exprt &count); + exprt add_axioms_for_index_of( + const string_exprt &str, + const exprt &c, + const exprt &from_index); + + // Add axioms corresponding to the String.indexOf:(String;I) java function + // TODO: the specifications are only partial: + // we add axioms stating that the returned value is either -1 or greater than + // from_index and the string beggining there has prefix substring + exprt add_axioms_for_index_of_string( + const string_exprt &str, + const string_exprt &substring, + const exprt &from_index); + + // Add axioms corresponding to the String.indexOf java functions + // TODO: the specifications are only partial for the ones that look for + // strings + exprt add_axioms_for_index_of(const function_application_exprt &f); + + // Add axioms corresponding to the String.lastIndexOf:(String;I) java function + // TODO: the specifications are only partial + exprt add_axioms_for_last_index_of_string( + const string_exprt &str, + const string_exprt &substring, + const exprt &from_index); + + // Add axioms corresponding to the String.lastIndexOf:(CI) java function + exprt add_axioms_for_last_index_of( + const string_exprt &str, + const exprt &c, + const exprt &from_index); + + // Add axioms corresponding to the String.lastIndexOf java functions + // TODO: the specifications is only partial + exprt add_axioms_for_last_index_of(const function_application_exprt &f); + + // TODO: the specifications of these functions is only partial + // We currently only specify that the string for NaN is "NaN", for infinity + // and minus infinity the string are "Infinity" and "-Infinity respectively + // otherwise the string contains only characters in [0123456789.] and '-' at + // 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); + + // Add axioms corresponding to the String.valueOf(D) java function + // TODO: the specifications is only partial + string_exprt add_axioms_from_double(const function_application_exprt &f); + + string_exprt add_axioms_for_replace(const function_application_exprt &f); + string_exprt add_axioms_for_set_length(const function_application_exprt &f); + + // TODO: the specification may not be correct for the case where the + // string is shorter than end. An actual java program should throw an + // exception in that case + string_exprt add_axioms_for_substring( + const string_exprt &str, const exprt &start, const exprt &end); + string_exprt add_axioms_for_substring(const function_application_exprt &expr); + + string_exprt add_axioms_for_to_lower_case( + const function_application_exprt &expr); + string_exprt add_axioms_for_to_upper_case( + const function_application_exprt &expr); + string_exprt add_axioms_for_trim(const function_application_exprt &expr); + + // Add axioms corresponding to the String.valueOf([CII) function + // TODO: not working correctly at the moment + string_exprt add_axioms_for_value_of(const function_application_exprt &f); + + string_exprt add_axioms_for_code_point(const exprt &code_point); + string_exprt add_axioms_for_java_char_array(const exprt &char_array); + string_exprt add_axioms_for_if(const if_exprt &expr); + exprt add_axioms_for_char_literal(const function_application_exprt &f); + + // Add axioms corresponding the String.codePointCount java function + // TODO: this function is underspecified, we do not compute the exact value + // but over approximate it. + exprt add_axioms_for_code_point_count(const function_application_exprt &f); + + // Add axioms corresponding the String.offsetByCodePointCount java function + // TODO: this function is underspecified, it should return the index within + // this String that is offset from the given first argument by second argument + // code points and we approximate this by saying the result is + // between index + offset and index + 2 * offset + exprt add_axioms_for_offset_by_code_point( + const function_application_exprt &f); + + exprt add_axioms_for_parse_int(const function_application_exprt &f); + exprt add_axioms_for_to_char_array(const function_application_exprt &f); + exprt add_axioms_for_compare_to(const function_application_exprt &f); + + // Add axioms corresponding to the String.intern java function + // TODO: this does not work at the moment because of the way we treat + // string pointers + symbol_exprt add_axioms_for_intern(const function_application_exprt &f); + + // Tells which language is used. C and Java are supported + irep_idt mode; + + // Type of strings used in the refinement + refined_string_typet refined_string_type; + + // assert that the number of argument is equal to nb and extract them + static const function_application_exprt::argumentst &args( + const function_application_exprt &expr, size_t nb) + { + const function_application_exprt::argumentst &args=expr.arguments(); + assert(args.size()==nb); + return args; + } + + exprt int_of_hex_char(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 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 new file mode 100644 index 00000000000..807587cbc45 --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator_code_points.cpp @@ -0,0 +1,283 @@ +/*******************************************************************\ + +Module: Generates string constraints for Java functions dealing with + code points + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include + +/******************************************************************* \ + +Function: string_constraint_generatort::add_axioms_for_code_point + + Inputs: an expression representing a java code point + + Outputs: a new string expression + + Purpose: add axioms for the conversion of an integer representing a java + code point to a utf-16 string + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_code_point( + const exprt &code_point) +{ + string_exprt res(get_char_type()); + const typet &type=code_point.type(); + assert(type.id()==ID_signedbv); + + // We add axioms: + // a1 : code_point<0x010000 => |res|=1 + // a2 : code_point>=0x010000 => |res|=2 + // a3 : code_point<0x010000 => res[0]=code_point + // a4 : code_point>=0x010000 => res[0]=0xD800+(code_point-0x10000)/0x0400 + // a5 : code_point>=0x010000 => res[1]=0xDC00+(code_point-0x10000)/0x0400 + // For more explenations about this conversion, see: + // https://en.wikipedia.org/wiki/UTF-16 + + exprt hex010000=from_integer(0x010000, type); + exprt hexD800=from_integer(0xD800, type); + exprt hexDC00=from_integer(0xDC00, type); + exprt hex0400=from_integer(0x0400, type); + + binary_relation_exprt small(code_point, ID_lt, hex010000); + implies_exprt a1(small, res.axiom_for_has_length(1)); + axioms.push_back(a1); + + implies_exprt a2(not_exprt(small), res.axiom_for_has_length(2)); + axioms.push_back(a2); + + typecast_exprt code_point_as_char(code_point, get_char_type()); + implies_exprt a3(small, equal_exprt(res[0], code_point_as_char)); + axioms.push_back(a3); + + plus_exprt first_char( + hexD800, div_exprt(minus_exprt(code_point, hex010000), hex0400)); + implies_exprt a4( + not_exprt(small), + equal_exprt(res[0], typecast_exprt(first_char, get_char_type()))); + axioms.push_back(a4); + + plus_exprt second_char(hexDC00, mod_exprt(code_point, hex0400)); + implies_exprt a5( + not_exprt(small), + equal_exprt(res[1], typecast_exprt(second_char, get_char_type()))); + axioms.push_back(a5); + + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::is_high_surrogate + + Inputs: a character expression + + Outputs: a Boolean expression + + Purpose: the output is true when the character is a high surrogate for + UTF-16 encoding, see https://en.wikipedia.org/wiki/UTF-16 for + more explenation about the encoding; + this is true when the character is in the range 0xD800..0xDBFF + +\*******************************************************************/ + +exprt string_constraint_generatort::is_high_surrogate(const exprt &chr) const +{ + return and_exprt( + binary_relation_exprt(chr, ID_ge, constant_char(0xD800)), + binary_relation_exprt(chr, ID_le, constant_char(0xDBFF))); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::is_low_surrogate + + Inputs: a character expression + + Outputs: a Boolean expression + + Purpose: the output is true when the character is a low surrogate for + UTF-16 encoding, see https://en.wikipedia.org/wiki/UTF-16 for + more explenation about the encoding; + this is true when the character is in the range 0xDC00..0xDFFF + +\*******************************************************************/ + +exprt string_constraint_generatort::is_low_surrogate(const exprt &chr) const +{ + return and_exprt( + binary_relation_exprt(chr, ID_ge, constant_char(0xDC00)), + binary_relation_exprt(chr, ID_le, constant_char(0xDFFF))); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::pair_value + + Inputs: two character expressions and a return type + char1 and char2 should be of type return_type + + Outputs: an integer expression of type return_type + + Purpose: the output corresponds to the unicode character given by the + pair of characters of inputs assuming it has been encoded in + UTF-16, see https://en.wikipedia.org/wiki/UTF-16 for + more explenation about the encoding; + the operation we perform is: + pair_value=0x10000+(((char1%0x0800)*0x0400)+char2%0x0400) + +\*******************************************************************/ + +exprt pair_value(exprt char1, exprt char2, typet return_type) +{ + exprt hex010000=from_integer(0x010000, return_type); + exprt hex0800=from_integer(0x0800, return_type); + exprt hex0400=from_integer(0x0400, return_type); + mult_exprt m1(mod_exprt(char1, hex0800), hex0400); + mod_exprt m2(char2, hex0400); + plus_exprt pair_value(hex010000, plus_exprt(m1, m2)); + return pair_value; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_code_point_at + + Inputs: function application with two arguments: a string and an index + + Outputs: a integer expression corresponding to a code point + + Purpose: add axioms corresponding to the String.codePointAt java function + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_code_point_at( + const function_application_exprt &f) +{ + typet return_type=f.type(); + assert(return_type.id()==ID_signedbv); + string_exprt str=add_axioms_for_string_expr(args(f, 2)[0]); + const exprt &pos=args(f, 2)[1]; + + symbol_exprt result=string_exprt::fresh_symbol("char", return_type); + exprt index1=from_integer(1, get_index_type()); + const exprt &char1=str[pos]; + const exprt &char2=str[plus_exprt(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 return_pair=and_exprt(is_high_surrogate(str[pos]), is_low); + + axioms.push_back(implies_exprt(return_pair, equal_exprt(result, pair))); + axioms.push_back( + implies_exprt(not_exprt(return_pair), equal_exprt(result, char1_as_int))); + return result; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_code_point_before + + Inputs: function application with two arguments: a string and an index + + Outputs: a integer expression corresponding to a code point + + Purpose: add axioms corresponding to the String.codePointBefore java function + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_code_point_before( + const function_application_exprt &f) +{ + const function_application_exprt::argumentst &args=f.arguments(); + assert(args.size()==2); + typet return_type=f.type(); + assert(return_type.id()==ID_signedbv); + symbol_exprt result=string_exprt::fresh_symbol("char", return_type); + string_exprt str=add_axioms_for_string_expr(args[0]); + + const exprt &char1= + str[minus_exprt(args[1], from_integer(2, get_index_type()))]; + const exprt &char2= + str[minus_exprt(args[1], from_integer(1, get_index_type()))]; + 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 return_pair=and_exprt( + is_high_surrogate(char1), is_low_surrogate(char2)); + + axioms.push_back(implies_exprt(return_pair, equal_exprt(result, pair))); + axioms.push_back( + implies_exprt(not_exprt(return_pair), equal_exprt(result, char2_as_int))); + return result; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_code_point_count + + Inputs: function application with three arguments: a string and two indexes + + Outputs: an integer expression + + Purpose: add axioms giving approximate bounds on the result of the + String.codePointCount java function + +\*******************************************************************/ + +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]); + const exprt &begin=args(f, 3)[1]; + const exprt &end=args(f, 3)[2]; + const typet &return_type=f.type(); + symbol_exprt result= + string_exprt::fresh_symbol("code_point_count", return_type); + minus_exprt length(end, begin); + div_exprt minimum(length, from_integer(2, get_index_type())); + axioms.push_back(binary_relation_exprt(result, ID_le, length)); + axioms.push_back(binary_relation_exprt(result, ID_ge, minimum)); + + return result; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_offset_by_code_point + + Inputs: function application with three arguments: a string and two indexes + + Outputs: a new string expression + + Purpose: add axioms giving approximate bounds on the result of the + String.offsetByCodePointCount java function. + We approximate the result by saying the result is + between index + offset and index + 2 * offset + +\*******************************************************************/ + +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]); + const exprt &index=args(f, 3)[1]; + const exprt &offset=args(f, 3)[2]; + const typet &return_type=f.type(); + symbol_exprt result= + string_exprt::fresh_symbol("offset_by_code_point", return_type); + + exprt minimum=plus_exprt(index, offset); + exprt maximum=plus_exprt(index, plus_exprt(offset, offset)); + axioms.push_back(binary_relation_exprt(result, ID_le, maximum)); + axioms.push_back(binary_relation_exprt(result, ID_ge, minimum)); + + return result; +} + diff --git a/src/solvers/refinement/string_constraint_generator_comparison.cpp b/src/solvers/refinement/string_constraint_generator_comparison.cpp new file mode 100644 index 00000000000..1cec8cf5442 --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator_comparison.cpp @@ -0,0 +1,344 @@ +/*******************************************************************\ + +Module: Generates string constraints for function comparing strings, + such as: equals, equalsIgnoreCase, compareTo, hashCode, intern + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_equals + + Inputs: function application with two string arguments + + 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 + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_equals( + const function_application_exprt &f) +{ + assert(f.type()==bool_typet() || f.type().id()==ID_c_bool); + 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]); + + // We want to write: + // eq <=> (s1.length=s2.length &&forall i s1.length=s2.length + // a2 : forall i s1[i]=s2[i] + // a3 : !eq => s1.length!=s2.length + // || (witness |s1|=|s2| + // a2 : forall qvar, 0<=qvar<|s1|, + // eq => char_equal_ignore_case(s1[qvar],s2[qvar]); + // a3 : !eq => |s1|!=s2 || (0 <=witness<|s1| &&!char_equal_ignore_case) + + implies_exprt a1(eq, s1.axiom_for_has_same_length_as(s2)); + axioms.push_back(a1); + + symbol_exprt qvar=fresh_univ_index("QA_equal_ignore_case"); + exprt constr2=character_equals_ignore_case( + s1[qvar], s2[qvar], char_a, char_A, char_Z); + string_constraintt a2(qvar, s1.length(), eq, constr2); + axioms.push_back(a2); + + symbol_exprt witness=fresh_exist_index("witness_unequal_ignore_case"); + exprt zero=from_integer(0, get_index_type()); + and_exprt bound_witness( + binary_relation_exprt(witness, ID_lt, s1.length()), + binary_relation_exprt(witness, ID_ge, zero)); + exprt witness_eq=character_equals_ignore_case( + s1[witness], s2[witness], char_a, char_A, char_Z); + not_exprt witness_diff(witness_eq); + implies_exprt a3( + not_exprt(eq), + or_exprt( + notequal_exprt(s1.length(), s2.length()), + and_exprt(bound_witness, witness_diff))); + axioms.push_back(a3); + + return tc_eq; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_hash_code + + Inputs: function application with a string argument + + Outputs: a integer expression corresponding to the hash code of the string + + Purpose: add axioms stating that if two strings are equal then their hash + codes are equals + +\*******************************************************************/ + +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]); + typet return_type=f.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]=string_exprt::fresh_symbol("hash", return_type); + + // for each string s. either: + // c1: hash(str)=hash(s) + // c2: |str|!=|s| + // 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++) + { + symbol_exprt i=fresh_exist_index("index_hash"); + equal_exprt c1(hash[it->second], hash[str]); + not_exprt c2(equal_exprt(it->second.length(), str.length())); + and_exprt c3( + equal_exprt(it->second.length(), str.length()), + and_exprt( + not_exprt(equal_exprt(str[i], it->second[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]; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_compare_to + + Inputs: function application with two string arguments + + Outputs: a integer expression + + Purpose: add axioms corresponding to the String.compareTo java function + +\*******************************************************************/ + +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]); + const typet &return_type=f.type(); + symbol_exprt res=string_exprt::fresh_symbol("compare_to", return_type); + + // In the lexicographic comparison, x is the first point where the two + // strings differ. + // We add axioms: + // 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] + + assert(return_type.id()==ID_signedbv); + + equal_exprt res_null=equal_exprt(res, from_integer(0, return_type)); + implies_exprt a1(res_null, s1.axiom_for_has_same_length_as(s2)); + axioms.push_back(a1); + + symbol_exprt i=fresh_univ_index("QA_compare_to"); + string_constraintt a2(i, s1.length(), res_null, equal_exprt(s1[i], s2[i])); + axioms.push_back(a2); + + symbol_exprt x=fresh_exist_index("index_compare_to"); + equal_exprt ret_char_diff( + res, + minus_exprt( + typecast_exprt(s1[x], return_type), + typecast_exprt(s2[x], return_type))); + equal_exprt ret_length_diff( + res, + minus_exprt( + typecast_exprt(s1.length(), return_type), + typecast_exprt(s2.length(), return_type))); + or_exprt guard1( + and_exprt(s1.axiom_for_is_shorter_than(s2), + s1.axiom_for_is_strictly_longer_than(x)), + and_exprt(s1.axiom_for_is_longer_than(s2), + s2.axiom_for_is_strictly_longer_than(x))); + and_exprt cond1(ret_char_diff, guard1); + or_exprt guard2( + and_exprt(s2.axiom_for_is_strictly_longer_than(s1), + s1.axiom_for_has_length(x)), + and_exprt(s1.axiom_for_is_strictly_longer_than(s2), + s2.axiom_for_has_length(x))); + and_exprt cond2(ret_length_diff, guard2); + + implies_exprt a3( + not_exprt(res_null), + and_exprt( + binary_relation_exprt(x, ID_ge, from_integer(0, return_type)), + or_exprt(cond1, cond2))); + axioms.push_back(a3); + + string_constraintt a4(i, x, not_exprt(res_null), equal_exprt(s1[i], s2[i])); + axioms.push_back(a4); + + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_intern + + Inputs: function application with one string argument + + Outputs: a string expression + + Purpose: add axioms stating that the return value for two equal string + should be the same + +\*******************************************************************/ + +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]); + const typet &return_type=f.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]=string_exprt::fresh_symbol("pool", return_type); + + // intern(str)=s_0 || s_1 || ... + // for each string s. + // intern(str)=intern(s) || |str|!=|s| + // || (|str|==|s| &&exists i<|s|. s[i]!=str[i]) + + // symbol_exprt intern=string_exprt::fresh_symbol("intern",return_type); + + exprt disj=false_exprt(); + for(it=symbol_to_string.begin(); it!=symbol_to_string.end(); it++) + disj=or_exprt( + disj, equal_exprt(pool[str], symbol_exprt(it->first, return_type))); + + 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) + { + symbol_exprt i=fresh_exist_index("index_intern"); + axioms.push_back( + or_exprt( + equal_exprt(pool[it->second], pool[str]), + or_exprt( + not_exprt(str.axiom_for_has_same_length_as(it->second)), + and_exprt( + str.axiom_for_has_same_length_as(it->second), + and_exprt( + not_exprt(equal_exprt(str[i], it->second[i])), + and_exprt(str.axiom_for_is_strictly_longer_than(i), + axiom_for_is_positive_index(i))))))); + } + + return pool[str]; +} diff --git a/src/solvers/refinement/string_constraint_generator_concat.cpp b/src/solvers/refinement/string_constraint_generator_concat.cpp new file mode 100644 index 00000000000..c6a1a7e52e7 --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator_concat.cpp @@ -0,0 +1,222 @@ +/*******************************************************************\ + +Module: Generates string constraints for functions adding content + add the end of strings + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_concat + + Inputs: two string expressions + + Outputs: a new string expression + + Purpose: add axioms to say that the returned string expression is equal to + the concatenation of the two string expressions given as input + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_concat( + const string_exprt &s1, const string_exprt &s2) +{ + string_exprt res(get_char_type()); + + // We add axioms: + // a1 : |res|=|s1|+|s2| + // a2 : |s1| <= |res| (to avoid overflow with very long strings) + // a3 : |s2| <= |res| (to avoid overflow with very long strings) + // 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); + axioms.push_back(s1.axiom_for_is_shorter_than(res)); + axioms.push_back(s2.axiom_for_is_shorter_than(res)); + + symbol_exprt idx=fresh_univ_index("QA_index_concat"); + string_constraintt a4(idx, s1.length(), equal_exprt(s1[idx], res[idx])); + axioms.push_back(a4); + + symbol_exprt idx2=fresh_univ_index("QA_index_concat2"); + equal_exprt res_eq(s2[idx2], res[plus_exprt(idx2, s1.length())]); + string_constraintt a5(idx2, s2.length(), res_eq); + axioms.push_back(a5); + + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_concat + + Inputs: function application with two arguments which are strings + + Outputs: a new string expression + + Purpose: add axioms to say that the returned string expression is equal to + the concatenation of the two string arguments of + the function application + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_concat( + const function_application_exprt &f) +{ + 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]); + + return add_axioms_for_concat(s1, s2); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_concat_int + + Inputs: function application with two arguments: a string and an integer + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.append(I) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_concat_int( + const function_application_exprt &f) +{ + string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt s2=add_axioms_from_int(args(f, 2)[1], MAX_INTEGER_LENGTH); + return add_axioms_for_concat(s1, s2); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_long + + Inputs: function application with two arguments: a string and a + integer of type long + + Outputs: a new string expression + + Purpose: Add axioms corresponding to the StringBuilder.append(J) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_concat_long( + const function_application_exprt &f) +{ + string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]); + string_exprt s2=add_axioms_from_int(args(f, 2)[1], MAX_LONG_LENGTH); + return add_axioms_for_concat(s1, s2); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_concat_bool + + Inputs: function application two arguments: a string and a bool + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.append(Z) java function + +\*******************************************************************/ + +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 s2=add_axioms_from_bool(args(f, 2)[1]); + return add_axioms_for_concat(s1, s2); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_concat_char + + Inputs: function application with two arguments: a string and a char + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.append(C) java function + +\*******************************************************************/ + +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 s2=add_axioms_from_char(args(f, 2)[1]); + return add_axioms_for_concat(s1, s2); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_concat_double + + Inputs: function application with two arguments: a string and a double + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.append(D) java function + +\*******************************************************************/ + +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); + return add_axioms_for_concat(s1, s2); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_concat_float + + Inputs: function application with two arguments: a string and a float + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.append(F) java function + +\*******************************************************************/ + +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); + return add_axioms_for_concat(s1, s2); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_concat_code_point + + Inputs: function application with two arguments: a string and a code point + + Outputs: a new string expression + + Purpose: Add axioms corresponding to the StringBuilder.appendCodePoint(I) + function + +\*******************************************************************/ + +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 s2=add_axioms_for_code_point(args(f, 2)[1]); + 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 new file mode 100644 index 00000000000..aa3466a2e57 --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator_constants.cpp @@ -0,0 +1,143 @@ +/*******************************************************************\ + +Module: Generates string constraints for constant strings + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include +#include +#include +#include + +/*******************************************************************\ + +Function: string_constraint_generatort::extract_java_string + + Inputs: a symbol expression representing a java literal + + Outputs: a string constant + + Purpose: extract java string from symbol expression when they are encoded + inside the symbol name + +\*******************************************************************/ + +irep_idt string_constraint_generatort::extract_java_string( + const symbol_exprt &s) const +{ + std::string tmp=id2string(s.get_identifier()); + std::string prefix("java::java.lang.String.Literal."); + assert(has_prefix(tmp, prefix)); + std::string value=tmp.substr(prefix.length()); + return irep_idt(value); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_constant + + Inputs: a string constant + + Outputs: a string expression + + Purpose: add axioms saying the returned string expression should be equal + to the string constant + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_constant( + irep_idt sval) +{ + string_exprt res(get_char_type()); + std::string c_str=id2string(sval); + std::wstring str; + + // TODO: we should have a special treatment for java strings when the + // conversion function is available: +#if 0 + if(mode==ID_java) + str=utf8_to_utf16_little_endian(c_str); + else +#endif + str=widen(c_str); + + for(std::size_t i=0; i + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_index_of + + Inputs: a string expression, a character expression and an integer expression + + Outputs: a integer expression + + Purpose: add axioms that the returned value is either -1 or greater than + from_index and the character at that position equals to c + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_index_of( + const string_exprt &str, const exprt &c, const exprt &from_index) +{ + symbol_exprt index=fresh_exist_index("index_of"); + symbol_exprt contains=fresh_boolean("contains_in_index_of"); + + // We add axioms: + // a1 : -1 <= index<|str| + // a2 : !contains <=> index=-1 + // a3 : contains => from_index<=index&&str[index]=c + // a4 : forall n, from_index<=n str[n]!=c + // a5 : forall m, from_index<=n<|str|. !contains => str[m]!=c + + exprt minus1=from_integer(-1, get_index_type()); + and_exprt a1( + binary_relation_exprt(index, ID_ge, minus1), + binary_relation_exprt(index, ID_lt, str.length())); + axioms.push_back(a1); + + equal_exprt a2(not_exprt(contains), equal_exprt(index, minus1)); + axioms.push_back(a2); + + implies_exprt a3( + contains, + and_exprt( + binary_relation_exprt(from_index, ID_le, index), + equal_exprt(str[index], c))); + axioms.push_back(a3); + + symbol_exprt n=fresh_univ_index("QA_index_of"); + string_constraintt a4( + n, from_index, index, contains, not_exprt(equal_exprt(str[n], c))); + axioms.push_back(a4); + + symbol_exprt m=fresh_univ_index("QA_index_of"); + string_constraintt a5( + m, + from_index, + str.length(), + not_exprt(contains), + not_exprt(equal_exprt(str[m], c))); + axioms.push_back(a5); + + return index; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_index_of_string + + Inputs: two string expressions and an integer expression + + Outputs: a integer expression + + Purpose: add axioms stating that the returned value is either -1 or greater + than from_index and the string beggining there has prefix substring + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_index_of_string( + const string_exprt &str, + const string_exprt &substring, + const exprt &from_index) +{ + symbol_exprt offset=fresh_exist_index("index_of"); + symbol_exprt contains=fresh_boolean("contains_substring"); + + // We add axioms: + // a1 : contains => |substring|>=offset>=from_index + // a2 : !contains => offset=-1 + // a3 : forall 0 <= witness str[witness+offset]=substring[witness] + + implies_exprt a1( + contains, + and_exprt( + str.axiom_for_is_longer_than(plus_exprt(substring.length(), offset)), + binary_relation_exprt(offset, ID_ge, from_index))); + axioms.push_back(a1); + + implies_exprt a2( + not_exprt(contains), + equal_exprt(offset, from_integer(-1, get_index_type()))); + axioms.push_back(a2); + + symbol_exprt qvar=fresh_univ_index("QA_index_of_string"); + string_constraintt a3( + qvar, + substring.length(), + contains, + equal_exprt(str[plus_exprt(qvar, offset)], substring[qvar])); + axioms.push_back(a3); + + return offset; +} + +exprt string_constraint_generatort::add_axioms_for_last_index_of_string( + const string_exprt &str, + const string_exprt &substring, + const exprt &from_index) +{ + symbol_exprt offset=fresh_exist_index("index_of"); + symbol_exprt contains=fresh_boolean("contains_substring"); + + // We add axioms: + // a1 : contains => |substring| >= length &&offset <= from_index + // a2 : !contains => offset=-1 + // a3 : forall 0 <= witness str[witness+offset]=substring[witness] + + implies_exprt a1( + contains, + and_exprt( + str.axiom_for_is_longer_than(plus_exprt(substring.length(), offset)), + binary_relation_exprt(offset, ID_le, from_index))); + axioms.push_back(a1); + + implies_exprt a2( + not_exprt(contains), + equal_exprt(offset, from_integer(-1, get_index_type()))); + axioms.push_back(a2); + + symbol_exprt qvar=fresh_univ_index("QA_index_of_string"); + equal_exprt constr3(str[plus_exprt(qvar, offset)], substring[qvar]); + string_constraintt a3(qvar, substring.length(), contains, constr3); + axioms.push_back(a3); + + return offset; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_index_of + + Inputs: function application with 2 or 3 arguments + + Outputs: a integer expression + + Purpose: add axioms corresponding to the String.indexOf:(C), + String.indexOf:(CI), String.indexOf:(String), and + String.indexOf:(String,I) java functions + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_index_of( + const function_application_exprt &f) +{ + const function_application_exprt::argumentst &args=f.arguments(); + assert(f.type()==get_index_type()); + string_exprt str=add_axioms_for_string_expr(args[0]); + const exprt &c=args[1]; + exprt from_index; + + if(args.size()==2) + from_index=from_integer(0, get_index_type()); + else if(args.size()==3) + from_index=args[2]; + else + assert(false); + + if(refined_string_typet::is_java_string_pointer_type(c.type())) + { + 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, get_char_type()), from_index); +} + +exprt string_constraint_generatort::add_axioms_for_last_index_of( + const string_exprt &str, const exprt &c, const exprt &from_index) +{ + symbol_exprt index=fresh_exist_index("last_index_of"); + symbol_exprt contains=fresh_boolean("contains_in_last_index_of"); + + // We add axioms: + // a1 : -1 <= i <= from_index + // a2 : (i=-1 <=> !contains) + // a3 : (contains => i <= from_index &&s[i]=c) + // a4 : forall n. i+1 <= n < from_index +1 &&contains => s[n]!=c + // a5 : forall m. 0 <= m < from_index +1 &&!contains => s[m]!=c + + exprt index1=from_integer(1, get_index_type()); + exprt minus1=from_integer(-1, get_index_type()); + exprt from_index_plus_one=plus_exprt(from_index, index1); + and_exprt a1( + binary_relation_exprt(index, ID_ge, minus1), + binary_relation_exprt(index, ID_lt, from_index_plus_one)); + axioms.push_back(a1); + + equal_exprt a2(not_exprt(contains), equal_exprt(index, minus1)); + axioms.push_back(a2); + + implies_exprt a3( + contains, + and_exprt( + binary_relation_exprt(from_index, ID_ge, index), + equal_exprt(str[index], c))); + axioms.push_back(a3); + + symbol_exprt n=fresh_univ_index("QA_last_index_of"); + string_constraintt a4( + n, + plus_exprt(index, index1), + from_index_plus_one, + contains, + not_exprt(equal_exprt(str[n], c))); + axioms.push_back(a4); + + symbol_exprt m=fresh_univ_index("QA_last_index_of"); + string_constraintt a5( + m, + from_index_plus_one, + not_exprt(contains), + not_exprt(equal_exprt(str[m], c))); + axioms.push_back(a5); + + return index; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_last_index_of + + Inputs: function application with 2 or 3 arguments + + Outputs: a integer expression + + Purpose: add axioms corresponding to the String.lastIndexOf:(C), + String.lastIndexOf:(CI), String.lastIndexOf:(String), and + String.lastIndexOf:(String,I) java functions + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_last_index_of( + const function_application_exprt &f) +{ + const function_application_exprt::argumentst &args=f.arguments(); + assert(f.type()==get_index_type()); + string_exprt str=add_axioms_for_string_expr(args[0]); + exprt c=args[1]; + exprt from_index; + + if(args.size()==2) + from_index=minus_exprt(str.length(), from_integer(1, get_index_type())); + else if(args.size()==3) + from_index=args[2]; + else + assert(false); + + if(refined_string_typet::is_java_string_pointer_type(c.type())) + { + 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, get_char_type()), from_index); +} + diff --git a/src/solvers/refinement/string_constraint_generator_insert.cpp b/src/solvers/refinement/string_constraint_generator_insert.cpp new file mode 100644 index 00000000000..8073ab4cb1f --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator_insert.cpp @@ -0,0 +1,220 @@ +/*******************************************************************\ + +Module: Generates string constraints for the family of insert Java functions + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_insert + + Inputs: two string expression and an integer offset + + Outputs: a new string expression + + Purpose: add axioms stating that the result correspond to the first string + where we inserted the second one at possition offset + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_insert( + const string_exprt &s1, const string_exprt &s2, const exprt &offset) +{ + assert(offset.type()==get_index_type()); + string_exprt pref=add_axioms_for_substring( + s1, from_integer(0, get_index_type()), offset); + string_exprt suf=add_axioms_for_substring(s1, offset, s1.length()); + string_exprt concat1=add_axioms_for_concat(pref, s2); + return add_axioms_for_concat(concat1, suf); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_insert + + Inputs: function application with three arguments: two strings and an index + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.insert(String) java + function + +\*******************************************************************/ + +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]); + return add_axioms_for_insert(s1, s2, args(f, 3)[1]); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_insert_int + + Inputs: function application with three arguments: a string, an integer + offset, and an integer + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.insert(I) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_insert_int( + const function_application_exprt &f) +{ + string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt s2=add_axioms_from_int(args(f, 3)[2], MAX_INTEGER_LENGTH); + return add_axioms_for_insert(s1, s2, args(f, 3)[1]); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_insert_long + + Inputs: function application with three arguments: a string, an integer + offset and a long + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.insert(J) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_insert_long( + const function_application_exprt &f) +{ + string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt s2=add_axioms_from_int(args(f, 3)[2], MAX_LONG_LENGTH); + return add_axioms_for_insert(s1, s2, args(f, 3)[1]); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_insert_bool + + Inputs: function application with three arguments: a string, an integer + offset, and a Boolean + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.insert(Z) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_insert_bool( + const function_application_exprt &f) +{ + string_exprt s1=add_axioms_for_string_expr(args(f, 3)[0]); + string_exprt s2=add_axioms_from_bool(args(f, 3)[2]); + return add_axioms_for_insert(s1, s2, args(f, 3)[1]); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_insert_char + + Inputs: function application with three arguments: a string, an integer + offset, and a character + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.insert(C) java function + +\*******************************************************************/ + +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 s2=add_axioms_from_char(args(f, 3)[2]); + return add_axioms_for_insert(s1, s2, args(f, 3)[1]); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_insert_double + + Inputs: function application with three arguments: a string, an integer + offset, and a double + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.insert(D) java function + +\*******************************************************************/ + +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]); + return add_axioms_for_insert(s1, s2, args(f, 3)[1]); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_insert_float + + Inputs: function application with three arguments: a string, an integer + offset, and a float + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.insert(F) java function + +\*******************************************************************/ + +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]); + return add_axioms_for_insert(s1, s2, args(f, 3)[1]); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_insert_char_array + + Inputs: function application with 4 arguments plus two optional arguments: + a string, an offset index, a length, data array, an offset and a + count + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.insert:(I[CII) + and StringBuilder.insert:(I[C) java functions + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_insert_char_array( + const function_application_exprt &f) +{ + exprt offset; + exprt count; + if(f.arguments().size()==6) + { + offset=f.arguments()[4]; + count=f.arguments()[5]; + } + else + { + assert(f.arguments().size()==4); + count=f.arguments()[2]; + offset=from_integer(0, get_index_type()); + } + + string_exprt str=add_axioms_for_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( + length, data, offset, count); + return add_axioms_for_insert(str, arr, f.arguments()[1]); +} diff --git a/src/solvers/refinement/string_constraint_generator_main.cpp b/src/solvers/refinement/string_constraint_generator_main.cpp new file mode 100644 index 00000000000..e76ae3f1f3d --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator_main.cpp @@ -0,0 +1,700 @@ +/*******************************************************************\ + +Module: Generates string constraints to link results from string functions + with their arguments. This is inspired by the PASS paper at HVC'13: + "PASS: String Solving with Parameterized Array and Interval Automaton" + by Guodong Li and Indradeep Ghosh, which gives examples of constraints + for several functions. + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include +#include +#include +#include +#include +#include + +/*******************************************************************\ + +Function: string_constraint_generatort::constant_char + + Inputs: integer representing a character, we do not use char type here + because java characters use more than 8 bits. + + Outputs: constant expression corresponding to the character. + + Purpose: generate constant character expression with character type. + +\*******************************************************************/ + +constant_exprt string_constraint_generatort::constant_char(int i) const +{ + return from_integer(i, get_char_type()); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::get_char_type + + Outputs: a type for characters + + Purpose: returns the type of characters that is adapted to the current mode + +\*******************************************************************/ + +typet string_constraint_generatort::get_char_type() const +{ + if(mode==ID_C) + return char_type(); + else if(mode==ID_java) + return java_char_type(); + else + assert(false); // only C and java modes supported +} + +/*******************************************************************\ + +Function: string_constraint_generatort::fresh_univ_index + + Inputs: a prefix + + Outputs: a symbol of index type whose name starts with the prefix + + Purpose: generate an index symbol to be used as an universaly quantified + variable + +\*******************************************************************/ + +symbol_exprt string_constraint_generatort::fresh_univ_index( + const irep_idt &prefix) +{ + return string_exprt::fresh_symbol(prefix, get_index_type()); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::fresh_exist_index + + Inputs: a prefix + + Outputs: a symbol of index type whose name starts with the prefix + + Purpose: generate an index symbol which is existentially quantified + +\*******************************************************************/ + +symbol_exprt string_constraint_generatort::fresh_exist_index( + const irep_idt &prefix) +{ + symbol_exprt s=string_exprt::fresh_symbol(prefix, get_index_type()); + index_symbols.push_back(s); + return s; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::fresh_boolean + + Inputs: a prefix + + Outputs: a symbol of index type whose name starts with the prefix + + Purpose: generate a Boolean symbol which is existentially quantified + +\*******************************************************************/ + +symbol_exprt string_constraint_generatort::fresh_boolean( + const irep_idt &prefix) +{ + symbol_exprt b=string_exprt::fresh_symbol(prefix, bool_typet()); + boolean_symbols.push_back(b); + return b; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_string_expr + + Inputs: an expression of type string + + 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 + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_string_expr( + const exprt &unrefined_string) +{ + string_exprt s; + + if(unrefined_string.id()==ID_function_application) + { + exprt res=add_axioms_for_function_application( + to_function_application_expr(unrefined_string)); + assert(res.type()==refined_string_type); + s=to_string_expr(res); + } + 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) + { + assert(unrefined_string.op0().id()==ID_symbol); + s=find_or_add_string_of_symbol(to_symbol_expr(unrefined_string.op0())); + } + 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) + { + // TODO: for now we ignore non deterministic symbols and struct + } + else if(unrefined_string.id()==ID_typecast) + { + exprt arg=to_typecast_expr(unrefined_string).op(); + exprt res=add_axioms_for_string_expr(arg); + assert(res.type()==refined_string_typet(get_char_type())); + s=to_string_expr(res); + } + else + { + throw "add_axioms_for_string_expr:\n"+unrefined_string.pretty()+ + "\nwhich is not a function application, "+ + "a symbol or an if expression"; + } + + axioms.push_back( + s.axiom_for_is_longer_than(from_integer(0, get_index_type()))); + return s; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_if + + Inputs: an if expression + + Outputs: a string expression + + Purpose: add axioms for an if expression which should return a string + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_if( + const if_exprt &expr) +{ + string_exprt res(get_char_type()); + assert( + refined_string_typet::is_unrefined_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())); + string_exprt f=add_axioms_for_string_expr(expr.false_case()); + + axioms.push_back( + implies_exprt(expr.cond(), res.axiom_for_has_same_length_as(t))); + symbol_exprt qvar=fresh_univ_index("QA_string_if_true"); + equal_exprt qequal(res[qvar], t[qvar]); + axioms.push_back(string_constraintt(qvar, t.length(), expr.cond(), qequal)); + axioms.push_back( + implies_exprt(not_exprt(expr.cond()), res.axiom_for_has_same_length_as(f))); + symbol_exprt qvar2=fresh_univ_index("QA_string_if_false"); + equal_exprt qequal2(res[qvar2], f[qvar2]); + string_constraintt sc2(qvar2, f.length(), not_exprt(expr.cond()), qequal2); + axioms.push_back(sc2); + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::find_or_add_string_of_symbol + + Inputs: a symbol expression + + Outputs: a string expression + + Purpose: if a symbol represent 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. + +\*******************************************************************/ + +string_exprt string_constraint_generatort::find_or_add_string_of_symbol( + const symbol_exprt &sym) +{ + irep_idt id=sym.get_identifier(); + auto entry=symbol_to_string.insert( + std::make_pair(id, string_exprt(get_char_type()))); + return entry.first->second; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_function_application + + Inputs: an expression containing a function application + + Outputs: expression corresponding to the result of the function application + + Purpose: strings contained in this call are converted to objects of type + `string_exprt`, through adding axioms. Axioms are then added to + enforce that the result corresponds to the function application. + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_function_application( + const function_application_exprt &expr) +{ + const exprt &name=expr.function(); + assert(name.id()==ID_symbol); + + const irep_idt &id=is_ssa_expr(name)?to_ssa_expr(name).get_object_name(): + to_symbol_expr(name).get_identifier(); + + // TODO: improve efficiency of this test by either ordering test by frequency + // or using a map + + if(id==ID_cprover_char_literal_func) + return add_axioms_for_char_literal(expr); + else if(id==ID_cprover_string_length_func) + return add_axioms_for_length(expr); + else if(id==ID_cprover_string_equal_func) + return add_axioms_for_equals(expr); + else if(id==ID_cprover_string_equals_ignore_case_func) + return add_axioms_for_equals_ignore_case(expr); + else if(id==ID_cprover_string_is_empty_func) + return add_axioms_for_is_empty(expr); + else if(id==ID_cprover_string_char_at_func) + return add_axioms_for_char_at(expr); + else if(id==ID_cprover_string_is_prefix_func) + return add_axioms_for_is_prefix(expr); + else if(id==ID_cprover_string_is_suffix_func) + return add_axioms_for_is_suffix(expr); + else if(id==ID_cprover_string_startswith_func) + return add_axioms_for_is_prefix(expr, true); + else if(id==ID_cprover_string_endswith_func) + return add_axioms_for_is_suffix(expr, true); + else if(id==ID_cprover_string_contains_func) + return add_axioms_for_contains(expr); + else if(id==ID_cprover_string_hash_code_func) + return add_axioms_for_hash_code(expr); + else if(id==ID_cprover_string_index_of_func) + return add_axioms_for_index_of(expr); + else if(id==ID_cprover_string_last_index_of_func) + return add_axioms_for_last_index_of(expr); + else if(id==ID_cprover_string_parse_int_func) + return add_axioms_for_parse_int(expr); + else if(id==ID_cprover_string_to_char_array_func) + return 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); + else if(id==ID_cprover_string_code_point_before_func) + return 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); + else if(id==ID_cprover_string_offset_by_code_point_func) + return add_axioms_for_offset_by_code_point(expr); + else if(id==ID_cprover_string_compare_to_func) + return add_axioms_for_compare_to(expr); + else if(id==ID_cprover_string_literal_func) + return add_axioms_from_literal(expr); + else if(id==ID_cprover_string_concat_func) + return add_axioms_for_concat(expr); + else if(id==ID_cprover_string_concat_int_func) + return add_axioms_for_concat_int(expr); + else if(id==ID_cprover_string_concat_long_func) + return add_axioms_for_concat_long(expr); + else if(id==ID_cprover_string_concat_bool_func) + return add_axioms_for_concat_bool(expr); + else if(id==ID_cprover_string_concat_char_func) + return add_axioms_for_concat_char(expr); + else if(id==ID_cprover_string_concat_double_func) + return add_axioms_for_concat_double(expr); + else if(id==ID_cprover_string_concat_float_func) + return add_axioms_for_concat_float(expr); + else if(id==ID_cprover_string_concat_code_point_func) + return add_axioms_for_concat_code_point(expr); + else if(id==ID_cprover_string_insert_func) + return add_axioms_for_insert(expr); + else if(id==ID_cprover_string_insert_int_func) + return add_axioms_for_insert_int(expr); + else if(id==ID_cprover_string_insert_long_func) + return add_axioms_for_insert_long(expr); + else if(id==ID_cprover_string_insert_bool_func) + return add_axioms_for_insert_bool(expr); + else if(id==ID_cprover_string_insert_char_func) + return add_axioms_for_insert_char(expr); + else if(id==ID_cprover_string_insert_double_func) + return add_axioms_for_insert_double(expr); + else if(id==ID_cprover_string_insert_float_func) + return add_axioms_for_insert_float(expr); + else if(id==ID_cprover_string_insert_char_array_func) + return add_axioms_for_insert_char_array(expr); + else if(id==ID_cprover_string_substring_func) + return add_axioms_for_substring(expr); + else if(id==ID_cprover_string_trim_func) + return add_axioms_for_trim(expr); + else if(id==ID_cprover_string_to_lower_case_func) + return 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); + else if(id==ID_cprover_string_char_set_func) + return add_axioms_for_char_set(expr); + else if(id==ID_cprover_string_value_of_func) + return add_axioms_for_value_of(expr); + else if(id==ID_cprover_string_empty_string_func) + return add_axioms_for_empty_string(expr); + else if(id==ID_cprover_string_copy_func) + return add_axioms_for_copy(expr); + else if(id==ID_cprover_string_of_int_func) + return add_axioms_from_int(expr); + else if(id==ID_cprover_string_of_int_hex_func) + return add_axioms_from_int_hex(expr); + else if(id==ID_cprover_string_of_float_func) + return add_axioms_from_float(expr); + else if(id==ID_cprover_string_of_double_func) + return add_axioms_from_double(expr); + else if(id==ID_cprover_string_of_long_func) + return add_axioms_from_long(expr); + else if(id==ID_cprover_string_of_bool_func) + return 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); + else if(id==ID_cprover_string_set_length_func) + return add_axioms_for_set_length(expr); + else if(id==ID_cprover_string_delete_func) + return add_axioms_for_delete(expr); + else if(id==ID_cprover_string_delete_char_at_func) + return add_axioms_for_delete_char_at(expr); + else if(id==ID_cprover_string_replace_func) + return add_axioms_for_replace(expr); + else if(id==ID_cprover_string_data_func) + return add_axioms_for_data(expr); + else + { + std::string msg("string_exprt::function_application: unknown symbol :"); + msg+=id2string(id); + throw msg; + } +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_copy + + Inputs: function application with one argument, which is a string + + Outputs: a new string expression + + Purpose: add axioms to say that the returned string expression is equal to + the argument of the function application + +\*******************************************************************/ + +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]); + string_exprt res(get_char_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"); + string_constraintt a2(idx, s1.length(), equal_exprt(s1[idx], res[idx])); + axioms.push_back(a2); + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_java_char_array + + Inputs: an expression corresponding to a java object of type char array + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.valueOf([C) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_java_char_array( + const exprt &char_array) +{ + string_exprt res(get_char_type()); + exprt arr=to_address_of_expr(char_array).object(); + exprt len=member_exprt(arr, "length", res.length().type()); + exprt cont=member_exprt(arr, "data", res.content().type()); + res.length()=len; + res.content()=cont; + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_length + + Inputs: function application with one string argument + + Outputs: a string expression of index type + + Purpose: add axioms corresponding to the String.length java function + +\*******************************************************************/ + +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]); + return str.length(); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_data + + Inputs: function application with three arguments: one string, a java + Array object and the corresponding data field + + Outputs: an expression of type void + + Purpose: add axioms stating that the content of the string argument is + equal to the content of the array argument + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_data( + const function_application_exprt &f) +{ + string_exprt str=add_axioms_for_string_expr(args(f, 3)[0]); + const exprt &tab_data=args(f, 3)[1]; + const exprt &data=args(f, 3)[2]; + symbol_exprt qvar=fresh_univ_index("QA_string_data"); + + // translating data[qvar] to the correct expression + // which is (signed int)byte_extract_little_endian + // (data, (2l*qvar) + POINTER_OFFSET(byte_extract_little_endian + // (tab.data, 0l, unsigned short int *)), unsigned short int) + mult_exprt qvar2( + from_integer(2, java_long_type()), + typecast_exprt(qvar, java_long_type())); + byte_extract_exprt extract( + ID_byte_extract_little_endian, + tab_data, + from_integer(0, java_long_type()), + pointer_typet(java_char_type())); + plus_exprt arg2(qvar2, pointer_offset(extract)); + + byte_extract_exprt extract2( + ID_byte_extract_little_endian, data, arg2, java_char_type()); + exprt char_in_tab=typecast_exprt(extract2, get_char_type()); + + string_constraintt eq( + qvar, str.length(), equal_exprt(str[qvar], char_in_tab)); + axioms.push_back(eq); + + exprt void_expr; + void_expr.type()=void_typet(); + return void_expr; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_char_array + + Inputs: a length expression, an array expression, a offset index, and a + count index + + Outputs: a new string expression + + Purpose: add axioms stating that the content of the returned string + equals to the content of the array argument, starting at offset and + with `count` characters + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_char_array( + const exprt &length, + const exprt &data, + const exprt &offset, + const exprt &count) +{ + string_exprt str(get_char_type()); + + // We add axioms: + // a1 : forall q < count. str[q] = data[q+offset] + // a2 : |str| = count + + symbol_exprt qvar=fresh_univ_index("QA_string_of_char_array"); + exprt char_in_tab=data; + assert(char_in_tab.id()==ID_index); + char_in_tab.op1()=plus_exprt(qvar, offset); + + string_constraintt a1(qvar, count, equal_exprt(str[qvar], char_in_tab)); + axioms.push_back(a1); + axioms.push_back(equal_exprt(str.length(), count)); + + return str; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_char_array + + Inputs: function application with 2 arguments and 2 additional optional + arguments: length, char array, offset and count + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.:(I[CII) + and String.:(I[C) java functions + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_char_array( + const function_application_exprt &f) +{ + exprt offset; + exprt count; + if(f.arguments().size()==4) + { + offset=f.arguments()[2]; + count=f.arguments()[3]; + } + else + { + assert(f.arguments().size()==2); + count=f.arguments()[0]; + offset=from_integer(0, get_index_type()); + } + const exprt &tab_length=f.arguments()[0]; + const exprt &data=f.arguments()[1]; + return add_axioms_from_char_array(tab_length, data, offset, count); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_is_positive_index + + Inputs: an index expression + + Outputs: a Boolean expression + + Purpose: expression true exactly when the index is positive + +\*******************************************************************/ + +exprt string_constraint_generatort::axiom_for_is_positive_index(const exprt &x) +{ + return binary_relation_exprt( + x, ID_ge, from_integer(0, get_index_type())); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_char_literal + + Inputs: function application with one character argument + + Outputs: a new character expression + + Purpose: add axioms stating that the returned value is equal to the argument + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_char_literal( + const function_application_exprt &f) +{ + const function_application_exprt::argumentst &args=f.arguments(); + assert(args.size()==1); // there should be exactly 1 argument to char literal + + const exprt &arg=args[0]; + // for C programs argument to char literal should be one string constant + // of size 1. + if(arg.operands().size()==1 && + arg.op0().operands().size()==1 && + arg.op0().op0().operands().size()==2 && + arg.op0().op0().op0().id()==ID_string_constant) + { + const string_constantt s=to_string_constant(arg.op0().op0().op0()); + irep_idt sval=s.get_value(); + assert(sval.size()==1); + return from_integer(unsigned(sval[0]), get_char_type()); + } + else + { + throw "convert_char_literal unimplemented"; + } +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_char_at + + Inputs: function application with two arguments: a string and an integer + + Outputs: a character expression + + Purpose: add axioms stating that the character of the string at the given + position is equal to the returned value + +\*******************************************************************/ + +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]); + symbol_exprt char_sym=string_exprt::fresh_symbol("char", get_char_type()); + axioms.push_back(equal_exprt(char_sym, str[args(f, 2)[1]])); + return char_sym; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_to_char_array + + Inputs: function application with one string argument + + Outputs: a char array expression + + Purpose: add axioms corresponding to the String.toCharArray java function + +\*******************************************************************/ + +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]); + 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 new file mode 100644 index 00000000000..6df308c533e --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator_testing.cpp @@ -0,0 +1,246 @@ +/*******************************************************************\ + +Module: Generates string constraints for string functions that return + Boolean values + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_is_prefix + + Inputs: a prefix string, a string and an integer offset + + Outputs: a Boolean expression + + Purpose: add axioms stating that the returned expression is true exactly + when the first string is a prefix of the second one, starting at + position offset + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_is_prefix( + const string_exprt &prefix, const string_exprt &str, const exprt &offset) +{ + symbol_exprt isprefix=fresh_boolean("isprefix"); + + // 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]) + + implies_exprt a1( + isprefix, + str.axiom_for_is_longer_than(plus_exprt(prefix.length(), offset))); + axioms.push_back(a1); + + symbol_exprt qvar=fresh_univ_index("QA_isprefix"); + string_constraintt a2( + qvar, + prefix.length(), + isprefix, + equal_exprt(str[plus_exprt(qvar, offset)], prefix[qvar])); + axioms.push_back(a2); + + symbol_exprt witness=fresh_exist_index("witness_not_isprefix"); + and_exprt witness_diff( + 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]))); + 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)))); + + implies_exprt a3(not_exprt(isprefix), s0_notpref_s1); + axioms.push_back(a3); + return isprefix; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_is_prefix + + Inputs: a function application with 2 or 3 arguments and a Boolean telling + whether the prefix is the second argument (when swap_arguments is + true) or the first argument + + Outputs: a Boolean expression + + Purpose: add axioms corresponding to the String.isPrefix java function + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_is_prefix( + const function_application_exprt &f, bool swap_arguments) +{ + 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]); + exprt offset; + if(args.size()==2) + offset=from_integer(0, get_index_type()); + else if(args.size()==3) + offset=args[2]; + return typecast_exprt(add_axioms_for_is_prefix(s0, s1, offset), f.type()); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_is_empty + + Inputs: function application with a string argument + + Outputs: a Boolean expression + + Purpose: add axioms stating that the returned value is true exactly when + the argument string is empty + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_is_empty( + const function_application_exprt &f) +{ + assert(f.type()==bool_typet() || f.type().id()==ID_c_bool); + + // We add axioms: + // a1 : is_empty => |s0| = 0 + // a2 : s0 => is_empty + + symbol_exprt is_empty=fresh_boolean("is_empty"); + string_exprt s0=add_axioms_for_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()); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_is_suffix + + Inputs: a function application with 2 or 3 arguments and a Boolean telling + whether the suffix is the second argument (when swap_arguments is + true) or the first argument + + Outputs: a Boolean expression + + Purpose: add axioms corresponding to the String.isSuffix java function + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_is_suffix( + const function_application_exprt &f, bool swap_arguments) +{ + const function_application_exprt::argumentst &args=f.arguments(); + assert(args.size()==2); // bad args to string issuffix? + assert(f.type()==bool_typet() || f.type().id()==ID_c_bool); + + 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]); + + // We add axioms: + // a1 : issufix => s0.length >= s1.length + // a2 : forall witness s1[witness]=s0[witness + s0.length-s1.length] + // a3 : !issuffix => + // s1.length > s0.length + // || (s1.length > witness>=0 + // &&s1[witness]!=s0[witness + s0.length-s1.length] + + implies_exprt a1(issuffix, s1.axiom_for_is_longer_than(s0)); + axioms.push_back(a1); + + symbol_exprt qvar=fresh_univ_index("QA_suffix"); + exprt qvar_shifted=plus_exprt( + qvar, minus_exprt(s1.length(), s0.length())); + string_constraintt a2( + qvar, s0.length(), issuffix, equal_exprt(s0[qvar], s1[qvar_shifted])); + axioms.push_back(a2); + + symbol_exprt witness=fresh_exist_index("witness_not_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( + notequal_exprt(s0[witness], s1[shifted]), + and_exprt( + s0.axiom_for_is_strictly_longer_than(witness), + axiom_for_is_positive_index(witness)))); + implies_exprt a3(not_exprt(issuffix), constr3); + + axioms.push_back(a3); + return tc_issuffix; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_contains + + Inputs: function application with two string arguments + + Outputs: a Boolean expression + + Purpose: add axioms corresponding to the String.contains java function + +\*******************************************************************/ + +exprt string_constraint_generatort::add_axioms_for_contains( + const function_application_exprt &f) +{ + 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]); + + // We add axioms: + // a1 : contains => s0.length >= s1.length + // a2 : 0 <= startpos <= s0.length-s1.length + // a3 : forall qvar s1[qvar]=s0[startpos + qvar] + // a4 : !contains => s1.length > s0.length + // || (forall startpos <= s0.length-s1.length. + // exists witness= |s1| ) + // ==> exists witness<|s1|. s1[witness]!=s0[startpos+witness] + string_not_contains_constraintt a4( + from_integer(0, get_index_type()), + plus_exprt(from_integer(1, get_index_type()), length_diff), + and_exprt(not_exprt(contains), s0.axiom_for_is_longer_than(s1)), + from_integer(0, get_index_type()), s1.length(), s0, s1); + axioms.push_back(a4); + + return tc_contains; +} diff --git a/src/solvers/refinement/string_constraint_generator_transformation.cpp b/src/solvers/refinement/string_constraint_generator_transformation.cpp new file mode 100644 index 00000000000..c361c9d4e48 --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator_transformation.cpp @@ -0,0 +1,460 @@ +/*******************************************************************\ + +Module: Generates string constraints for string transformations, + that is, functions taking one string and returning another + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_set_length + + Inputs: function application with two arguments, the first of which is + a string and the second an integer which should have same type has + return by get_index_type() + + Outputs: a new string expression + + Purpose: add axioms to say that the returned string expression has length + given by the second argument and whose characters are equal to + those of the first argument for the positions which are defined in + both strings + +\*******************************************************************/ + +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]); + exprt k=args(f, 2)[1]; + string_exprt res(get_char_type()); + + // We add axioms: + // a1 : |res|=k + // a2 : forall i s[i]=s1[i]) &&(i >= k ==> s[i]=0) + + axioms.push_back(res.axiom_for_has_length(k)); + + symbol_exprt idx=fresh_univ_index("QA_index_set_length"); + string_constraintt a2( + idx, k, and_exprt( + implies_exprt( + s1.axiom_for_is_strictly_longer_than(idx), + equal_exprt(s1[idx], res[idx])), + implies_exprt( + s1.axiom_for_is_shorter_than(idx), + equal_exprt(s1[idx], constant_char(0))))); + axioms.push_back(a2); + + return res; +} + + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_substring + + Inputs: function application with one string argument, one start index + argument and an optional end index argument + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.substring java function + Warning: the specification may not be correct for the case where the + string is shorter than the end index + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_substring( + const function_application_exprt &f) +{ + const function_application_exprt::argumentst &args=f.arguments(); + assert(args.size()>=2); + string_exprt str=add_axioms_for_string_expr(args[0]); + exprt i(args[1]); + exprt j; + if(args.size()==3) + { + j=args[2]; + } + else + { + assert(args.size()==2); + j=str.length(); + } + return add_axioms_for_substring(str, i, j); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_substring + + Inputs: a string expression, an expression for the start index, and an + expression for the end index + + Outputs: a new string expression + + Purpose: add axioms stating that the returned string expression is equal + to the input one starting at `start` and ending before `end` + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_substring( + const string_exprt &str, const exprt &start, const exprt &end) +{ + symbol_exprt idx=fresh_exist_index("index_substring"); + assert(start.type()==get_index_type()); + assert(end.type()==get_index_type()); + string_exprt res(get_char_type()); + + // We add axioms: + // a1 : start < end => |res| = end - start + // a2 : start >= end => |res| = 0 + // a3 : |str| > end + // a4 : forall idx= 0 + // a3 : str >= idx + // a4 : |res|>= 0 + // a5 : |res|<=|str| + // (this is necessary to prevent exceeding the biggest integer) + // a6 : forall n' ' &&s[m+|s1|-1]>' ') || m=|s| + + exprt a1=str.axiom_for_is_longer_than(plus_exprt(idx, res.length())); + axioms.push_back(a1); + + binary_relation_exprt a2(idx, ID_ge, from_integer(0, get_index_type())); + axioms.push_back(a2); + + exprt a3=str.axiom_for_is_longer_than(idx); + axioms.push_back(a3); + + exprt a4=res.axiom_for_is_longer_than( + from_integer(0, get_index_type())); + axioms.push_back(a4); + + exprt a5=res.axiom_for_is_shorter_than(str); + axioms.push_back(a5); + + symbol_exprt n=fresh_univ_index("QA_index_trim"); + binary_relation_exprt non_print(str[n], ID_le, space_char); + string_constraintt a6(n, idx, non_print); + axioms.push_back(a6); + + symbol_exprt n2=fresh_univ_index("QA_index_trim2"); + minus_exprt bound(str.length(), plus_exprt(idx, res.length())); + binary_relation_exprt eqn2( + str[plus_exprt(idx, plus_exprt(res.length(), n2))], + ID_le, + space_char); + + string_constraintt a7(n2, bound, eqn2); + axioms.push_back(a7); + + symbol_exprt n3=fresh_univ_index("QA_index_trim3"); + equal_exprt eqn3(res[n3], str[plus_exprt(n3, idx)]); + string_constraintt a8(n3, res.length(), eqn3); + axioms.push_back(a8); + + minus_exprt index_before( + plus_exprt(idx, res.length()), from_integer(1, get_index_type())); + binary_relation_exprt no_space_before(str[index_before], ID_gt, space_char); + or_exprt a9( + equal_exprt(idx, str.length()), + and_exprt( + binary_relation_exprt(str[idx], ID_gt, space_char), + no_space_before)); + axioms.push_back(a9); + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_to_lower_case + + Inputs: function application with one string argument + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.toLowerCase java function + +\*******************************************************************/ + +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 res(get_char_type()); + exprt char_a=constant_char('a'); + exprt char_A=constant_char('A'); + exprt char_z=constant_char('z'); + exprt char_Z=constant_char('Z'); + + // TODO: add support for locales using case mapping information + // from the UnicodeData file. + + // We add axioms: + // a1 : |res| = |str| + // a2 : forall idx res[idx]=str[idx]+'a'-'A' + // a3 : forall idx res[idx]=str[idx] + // forall idx res[idx]=str[idx]+'A'-'a' + // a3 : forall idx res[idx]=str[idx] + + exprt a1=res.axiom_for_has_same_length_as(str); + axioms.push_back(a1); + + symbol_exprt idx=fresh_univ_index("QA_upper_case"); + exprt is_lower_case=and_exprt( + binary_relation_exprt(char_a, ID_le, str[idx]), + binary_relation_exprt(str[idx], ID_le, char_z)); + minus_exprt diff(char_A, char_a); + equal_exprt convert(res[idx], plus_exprt(str[idx], diff)); + string_constraintt a2(idx, res.length(), is_lower_case, convert); + axioms.push_back(a2); + + equal_exprt eq(res[idx], str[idx]); + string_constraintt a3(idx, res.length(), not_exprt(is_lower_case), eq); + axioms.push_back(a3); + return res; +} + + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_char_set + + Inputs: function application with three arguments, the first is a string + the second an index and the third a character + + Outputs: a new string expression + + Purpose: add axioms corresponding stating that the result is similar to + that of the StringBuilder.setCharAt java function + Warning: this may be underspecified in the case wher the index exceed + the length of the string + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_char_set( + const function_application_exprt &f) +{ + string_exprt res(get_char_type()); + string_exprt str=add_axioms_for_string_expr(args(f, 3)[0]); + with_exprt sarrnew(str.content(), args(f, 3)[1], args(f, 3)[2]); + + // We add axiom: + // a1 : arg1 < |str| => res = str with [arg1]=arg2 + + implies_exprt a1( + binary_relation_exprt(args(f, 3)[1], ID_lt, str.length()), + and_exprt( + equal_exprt(res.content(), sarrnew), + res.axiom_for_has_same_length_as(str))); + axioms.push_back(a1); + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_replace + + Inputs: function application with three arguments, the first is a string, + the second and the third are characters + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.replace java function + +\*******************************************************************/ + +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]); + const exprt &old_char=args(f, 3)[1]; + const exprt &new_char=args(f, 3)[2]; + string_exprt res(get_char_type()); + + // We add axioms: + // a1 : |res| = |str| + // a2 : forall qvar, 0<=qvar<|res|, + // str[qvar]=oldChar => res[qvar]=newChar + // !str[qvar]=oldChar => res[qvar]=str[qvar] + + axioms.push_back(res.axiom_for_has_same_length_as(str)); + + symbol_exprt qvar=fresh_univ_index("QA_replace"); + implies_exprt case1( + equal_exprt(str[qvar], old_char), + equal_exprt(res[qvar], new_char)); + implies_exprt case2( + not_exprt(equal_exprt(str[qvar], old_char)), + equal_exprt(res[qvar], str[qvar])); + string_constraintt a2(qvar, res.length(), and_exprt(case1, case2)); + axioms.push_back(a2); + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_delete_char_at + + Inputs: function application with two arguments, the first is a string + and the second is an index + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.deleteCharAt java + function + +\*******************************************************************/ + +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]); + exprt index_one=from_integer(1, get_index_type()); + return add_axioms_for_delete( + str, args(f, 2)[1], plus_exprt(args(f, 2)[1], index_one)); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_delete + + Inputs: a string expression, a start index and an end index + + Outputs: a new string expression + + Purpose: add axioms stating that the returned string corresponds to the input + one where we removed characters between the positions + start (included) and end (not included) + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_delete( + const string_exprt &str, const exprt &start, const exprt &end) +{ + assert(start.type()==get_index_type()); + assert(end.type()==get_index_type()); + string_exprt str1=add_axioms_for_substring( + str, from_integer(0, get_index_type()), start); + string_exprt str2=add_axioms_for_substring(str, end, str.length()); + return add_axioms_for_concat(str1, str2); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_delete + + Inputs: function application with three arguments: a string + expression, a start index and an end index + + Outputs: a new string expression + + Purpose: add axioms corresponding to the StringBuilder.delete java function + +\*******************************************************************/ + +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]); + 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 new file mode 100644 index 00000000000..3712b297386 --- /dev/null +++ b/src/solvers/refinement/string_constraint_generator_valueof.cpp @@ -0,0 +1,646 @@ +/*******************************************************************\ + +Module: Generates string constraints for functions generating strings + from other types, in particular int, long, float, double, char, bool + +Author: Romain Brenguier, romain.brenguier@diffblue.com + +\*******************************************************************/ + +#include +#include + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_int + + Inputs: function application with one integer argument + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.valueOf(I) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_int( + const function_application_exprt &expr) +{ + return add_axioms_from_int(args(expr, 1)[0], MAX_INTEGER_LENGTH); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_long + + Inputs: function application with one long argument + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.valueOf(J) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_long( + const function_application_exprt &expr) +{ + return add_axioms_from_int(args(expr, 1)[0], MAX_LONG_LENGTH); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_float + + Inputs: function application with one float argument + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.valueOf(F) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_float( + const function_application_exprt &f) +{ + return add_axioms_from_float(args(f, 1)[0], false); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_double + + Inputs: function application with one double argument + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.valueOf(D) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_double( + const function_application_exprt &f) +{ + return add_axioms_from_float(args(f, 1)[0], true); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_float + + Inputs: float expression and Boolean signaling that the argument has + double precision + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.valueOf(F) java function + Warning: we currently only have partial specification + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_float( + const exprt &f, bool double_precision) +{ + typet char_type=get_char_type(); + string_exprt res(char_type); + const exprt &index24=from_integer(24, get_index_type()); + axioms.push_back(res.axiom_for_is_shorter_than(index24)); + + string_exprt magnitude(char_type); + string_exprt sign_string(char_type); + string_exprt nan_string=add_axioms_for_constant("NaN"); + + // We add the axioms: + // a1 : If the argument is NaN, the result length is that of "NaN". + // a2 : If the argument is NaN, the result content is the string "NaN". + // a3 : f<0 => |sign_string|=1 + // a4 : f>=0 => |sign_string|=0 + // a5 : f<0 => sign_string[0]='-' + // a6 : f infinite => |magnitude|=|"Infinity"| + // a7 : forall i<|"Infinity"|, f infinite => magnitude[i]="Infinity"[i] + // a8 : f=0 => |magnitude|=|"0.0"| + // a9 : forall i<|"0.0"|, f=0 => f[i]="0.0"[i] + + ieee_float_spect fspec= + double_precision?ieee_float_spect::double_precision() + :ieee_float_spect::single_precision(); + + exprt isnan=float_bvt().isnan(f, fspec); + implies_exprt a1(isnan, magnitude.axiom_for_has_same_length_as(nan_string)); + axioms.push_back(a1); + + symbol_exprt qvar=fresh_univ_index("QA_equal_nan"); + string_constraintt a2( + qvar, + nan_string.length(), + isnan, + equal_exprt(magnitude[qvar], nan_string[qvar])); + axioms.push_back(a2); + + // If the argument is not NaN, the result is a string that represents + // the sign and magnitude (absolute value) of the argument. + // If the sign is negative, the first character of the result is '-'; + // if the sign is positive, no sign character appears in the result. + + bitvector_typet bv_type=to_bitvector_type(f.type()); + unsigned width=bv_type.get_width(); + exprt isneg=extractbit_exprt(f, width-1); + + implies_exprt a3(isneg, sign_string.axiom_for_has_length(1)); + axioms.push_back(a3); + + implies_exprt a4(not_exprt(isneg), sign_string.axiom_for_has_length(0)); + axioms.push_back(a4); + + implies_exprt a5(isneg, equal_exprt(sign_string[0], constant_char('-'))); + axioms.push_back(a5); + + // If m is infinity, it is represented by the characters "Infinity"; + // thus, positive infinity produces the result "Infinity" and negative + // infinity produces the result "-Infinity". + + string_exprt infinity_string=add_axioms_for_constant("Infinity"); + exprt isinf=float_bvt().isinf(f, fspec); + implies_exprt a6( + isinf, magnitude.axiom_for_has_same_length_as(infinity_string)); + axioms.push_back(a6); + + symbol_exprt qvar_inf=fresh_univ_index("QA_equal_infinity"); + equal_exprt meq(magnitude[qvar_inf], infinity_string[qvar_inf]); + string_constraintt a7(qvar_inf, infinity_string.length(), isinf, meq); + axioms.push_back(a7); + + // If m is zero, it is represented by the characters "0.0"; thus, negative + // zero produces the result "-0.0" and positive zero produces "0.0". + + string_exprt zero_string=add_axioms_for_constant("0.0"); + exprt iszero=float_bvt().is_zero(f, fspec); + implies_exprt a8(iszero, magnitude.axiom_for_has_same_length_as(zero_string)); + axioms.push_back(a8); + + symbol_exprt qvar_zero=fresh_univ_index("QA_equal_zero"); + equal_exprt eq_zero(magnitude[qvar_zero], zero_string[qvar_zero]); + string_constraintt a9(qvar_zero, zero_string.length(), iszero, eq_zero); + axioms.push_back(a9); + + return add_axioms_for_concat(sign_string, magnitude); +} + + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_bool + + Inputs: function application with on Boolean argument + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.valueOf(Z) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_bool( + const function_application_exprt &f) +{ + return add_axioms_from_bool(args(f, 1)[0]); +} + + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_bool + + Inputs: Boolean expression + + Outputs: a new string expression + + Purpose: add axioms stating that the returned string equals "true" when + the Boolean expression is true and "false" when it is false + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_bool( + const exprt &b) +{ + typet char_type=get_char_type(); + string_exprt res(char_type); + + assert(b.type()==bool_typet() || b.type().id()==ID_c_bool); + + typecast_exprt eq(b, bool_typet()); + + string_exprt true_string=add_axioms_for_constant("true"); + string_exprt false_string=add_axioms_for_constant("false"); + + // We add axioms: + // a1 : eq => res = |"true"| + // a2 : forall i < |"true"|. eq => res[i]="true"[i] + // a3 : !eq => res = |"false"| + // a4 : forall i < |"false"|. !eq => res[i]="false"[i] + + implies_exprt a1(eq, res.axiom_for_has_same_length_as(true_string)); + axioms.push_back(a1); + symbol_exprt qvar=fresh_univ_index("QA_equal_true"); + string_constraintt a2( + qvar, + true_string.length(), + eq, + equal_exprt(res[qvar], true_string[qvar])); + axioms.push_back(a2); + + implies_exprt a3( + not_exprt(eq), res.axiom_for_has_same_length_as(false_string)); + axioms.push_back(a3); + + symbol_exprt qvar1=fresh_univ_index("QA_equal_false"); + string_constraintt a4( + qvar, + false_string.length(), + not_exprt(eq), + equal_exprt(res[qvar1], false_string[qvar1])); + axioms.push_back(a4); + + return res; +} + +/*******************************************************************\ + +Function: smallest_by_digit + + Inputs: number of digit + + Outputs: an integer with the right number of digit + + Purpose: gives the smallest integer with the specified number of digits + +\*******************************************************************/ + +static mp_integer smallest_by_digit(int nb) +{ + return power(10, nb-1); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_int + + Inputs: a signed integer expression, and a maximal size for the string + representation + + Outputs: a string expression + + Purpose: add axioms to say the string corresponds to the result of + String.valueOf(I) or String.valueOf(J) java functions applied on the + integer expression + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_int( + const exprt &i, size_t max_size) +{ + string_exprt res(get_char_type()); + const typet &type=i.type(); + assert(type.id()==ID_signedbv); + exprt ten=from_integer(10, type); + exprt zero_char=constant_char('0'); + exprt nine_char=constant_char('9'); + exprt minus_char=constant_char('-'); + exprt zero=from_integer(0, get_index_type()); + exprt max=from_integer(max_size, get_index_type()); + + // We add axioms: + // a1 : 0 <|res|<=max_size + // a2 : (res[0]='-')||('0'<=res[0]<='9') + + and_exprt a1(res.axiom_for_is_strictly_longer_than(zero), + res.axiom_for_is_shorter_than(max)); + axioms.push_back(a1); + + exprt chr=res[0]; + exprt starts_with_minus=equal_exprt(chr, minus_char); + exprt starts_with_digit=and_exprt( + 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); + + for(size_t size=1; size<=max_size; size++) + { + // For each possible size, we add axioms: + // all_numbers: forall 1<=i<=size. '0'<=res[i]<='9' + // a3 : |res|=size&&'0'<=res[0]<='9' => + // i=sum+str[0]-'0' &&all_numbers + // a4 : |res|=size&&res[0]='-' => i=-sum + // a5 : size>1 => |res|=size&&'0'<=res[0]<='9' => res[0]!='0' + // a6 : size>1 => |res|=size&&res[0]'-' => res[1]!='0' + // a7 : size==max_size => i>1000000000 + exprt sum=from_integer(0, type); + exprt all_numbers=true_exprt(); + chr=res[0]; + exprt first_value=typecast_exprt(minus_exprt(chr, zero_char), type); + + for(size_t j=1; j1) + { + equal_exprt r0_zero(res[zero], zero_char); + implies_exprt a5( + and_exprt(premise, starts_with_digit), + not_exprt(r0_zero)); + axioms.push_back(a5); + + exprt one=from_integer(1, get_index_type()); + equal_exprt r1_zero(res[one], zero_char); + implies_exprt a6( + and_exprt(premise, starts_with_minus), + not_exprt(r1_zero)); + axioms.push_back(a6); + } + + // we have to be careful when exceeding the maximal size of integers + 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); + axioms.push_back(a7); + } + } + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::int_of_hex_char + + Inputs: a character expression in the following set: 0123456789abcdef + + Outputs: an integer expression + + Purpose: returns the value represented by the character + +\*******************************************************************/ + +exprt string_constraint_generatort::int_of_hex_char(exprt chr) const +{ + exprt zero_char=constant_char('0'); + exprt nine_char=constant_char('9'); + exprt a_char=constant_char('a'); + return if_exprt( + binary_relation_exprt(chr, ID_gt, nine_char), + plus_exprt(constant_char(10), minus_exprt(chr, a_char)), + minus_exprt(chr, zero_char)); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_int_hex + + Inputs: one integer argument + + Outputs: a new string expression + + Purpose: add axioms stating that the returned string corresponds to the + integer argument written in hexadecimal + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_int_hex( + const exprt &i) +{ + string_exprt res(get_char_type()); + const typet &type=i.type(); + assert(type.id()==ID_signedbv); + exprt sixteen=from_integer(16, type); + exprt minus_char=constant_char('-'); + exprt zero_char=constant_char('0'); + exprt nine_char=constant_char('9'); + exprt a_char=constant_char('a'); + exprt f_char=constant_char('f'); + + size_t max_size=8; + axioms.push_back( + and_exprt(res.axiom_for_is_strictly_longer_than(0), + res.axiom_for_is_shorter_than(max_size))); + + for(size_t size=1; size<=max_size; size++) + { + exprt sum=from_integer(0, type); + exprt all_numbers=true_exprt(); + exprt chr=res[0]; + + for(size_t j=0; j1) + axioms.push_back( + implies_exprt(premise, not_exprt(equal_exprt(res[0], zero_char)))); + } + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_int_hex + + Inputs: function application with integer argument + + Outputs: a new string expression + + Purpose: add axioms corresponding to the Integer.toHexString(I) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_int_hex( + const function_application_exprt &f) +{ + return add_axioms_from_int_hex(args(f, 1)[0]); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_char + + Inputs: function application one char argument + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.valueOf(C) java function + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_char( + const function_application_exprt &f) +{ + return add_axioms_from_char(args(f, 1)[0]); +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_from_char + + Inputs: one expression of type char + + Outputs: a new string expression + + Purpose: add axioms stating that the returned string as length 1 and + the character it contains correspond to the input expression + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_from_char(const exprt &c) +{ + string_exprt res(get_char_type()); + and_exprt lemma(equal_exprt(res[0], c), res.axiom_for_has_length(1)); + axioms.push_back(lemma); + return res; +} + +/*******************************************************************\ + +Function: string_constraint_generatort::add_axioms_for_value_of + + Inputs: function application with one or three arguments + + Outputs: a new string expression + + Purpose: add axioms corresponding to the String.valueOf([C) and + String.valueOf([CII) functions + +\*******************************************************************/ + +string_exprt string_constraint_generatort::add_axioms_for_value_of( + const function_application_exprt &f) +{ + const function_application_exprt::argumentst &args=f.arguments(); + if(args.size()==3) + { + string_exprt res(get_char_type()); + exprt char_array=args[0]; + exprt offset=args[1]; + exprt count=args[2]; + + // We add axioms: + // a1 : |res| = count + // a2 : forall idx i=sum+first_value + // a2 : starts_with_plus => i=sum + // a3 : starts_with_minus => i=-sum + + equal_exprt premise=str.axiom_for_has_length(size); + implies_exprt a1( + and_exprt(premise, starts_with_digit), + equal_exprt(i, plus_exprt(sum, first_value))); + axioms.push_back(a1); + + implies_exprt a2(and_exprt(premise, starts_with_plus), equal_exprt(i, sum)); + axioms.push_back(a2); + + implies_exprt a3( + and_exprt(premise, starts_with_minus), + equal_exprt(i, unary_minus_exprt(sum))); + axioms.push_back(a3); + } + return i; +} From f7645ab2d84035ebc6572feb99d399d208c3664b Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Fri, 23 Dec 2016 12:44:12 +0000 Subject: [PATCH 154/166] String refinement class Inherits from `bv_refinementt`. It implements a string solver by creating string constraints via a `string_constraint_generatort` objects, and sove them by progressively instantiating universal constraints as needed. --- src/solvers/refinement/string_refinement.cpp | 1099 ++++++++++++++++++ src/solvers/refinement/string_refinement.h | 120 ++ 2 files changed, 1219 insertions(+) create mode 100644 src/solvers/refinement/string_refinement.cpp create mode 100644 src/solvers/refinement/string_refinement.h diff --git a/src/solvers/refinement/string_refinement.cpp b/src/solvers/refinement/string_refinement.cpp new file mode 100644 index 00000000000..cb406cbacb2 --- /dev/null +++ b/src/solvers/refinement/string_refinement.cpp @@ -0,0 +1,1099 @@ +/*******************************************************************\ + +Module: String support via creating string constraints and progressively + instantiating the universal constraints as needed. + The procedure is described in the PASS paper at HVC'13: + "PASS: String Solving with Parameterized Array and Interval Automaton" + by Guodong Li and Indradeep Ghosh. + +Author: Alberto Griggio, alberto.griggio@gmail.com + +\*******************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +string_refinementt::string_refinementt( + const namespacet &_ns, propt &_prop, unsigned refinement_bound): + supert(_ns, _prop), + use_counter_example(false), + initial_loop_bound(refinement_bound) +{ } + +/*******************************************************************\ + +Function: string_refinementt::set_mode + + Purpose: determine which language should be used + +\*******************************************************************/ + +void string_refinementt::set_mode() +{ + debug() << "initializing mode" << eom; + symbolt init=ns.lookup(irep_idt(CPROVER_PREFIX"initialize")); + irep_idt mode=init.mode; + debug() << "mode detected as " << mode << eom; + generator.set_mode(mode); +} + +/*******************************************************************\ + +Function: string_refinementt::display_index_set + + Purpose: display the current index set, for debugging + +\*******************************************************************/ + +void string_refinementt::display_index_set() +{ + for(const auto &i : index_set) + { + const exprt &s=i.first; + debug() << "IS(" << from_expr(s) << ")=={"; + + for(auto j : i.second) + debug() << from_expr(j) << "; "; + debug() << "}" << eom; + } +} + +/*******************************************************************\ + +Function: string_refinementt::add_instantiations + + Purpose: compute the index set for all formulas, instantiate the formulas + with the found indexes, and add them as lemmas. + +\*******************************************************************/ + +void string_refinementt::add_instantiations() +{ + debug() << "string_constraint_generatort::add_instantiations: " + << "going through the current index set:" << eom; + for(const auto &i : current_index_set) + { + const exprt &s=i.first; + debug() << "IS(" << from_expr(s) << ")=={"; + + for(const auto &j : i.second) + debug() << from_expr(j) << "; "; + debug() << "}" << eom; + + for(const auto &j : i.second) + { + const exprt &val=j; + + for(const auto &ua : universal_axioms) + { + exprt lemma=instantiate(ua, s, val); + add_lemma(lemma); + } + } + } +} + +/*******************************************************************\ + +Function: string_refinementt::convert_rest + + Inputs: an expression + + Outputs: a literal + + Purpose: if the expression is a function application, we convert it + using our own convert_function_application method + +\*******************************************************************/ + +literalt string_refinementt::convert_rest(const exprt &expr) +{ + if(expr.id()==ID_function_application) + { + // can occur in __CPROVER_assume + bvt bv=convert_function_application(to_function_application_expr(expr)); + assert(bv.size()==1); + return bv[0]; + } + else + { + return supert::convert_rest(expr); + } +} + +/*******************************************************************\ + +Function: string_refinementt::convert_symbol + + Inputs: an expression + + Outputs: a bitvector + + 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 + +\*******************************************************************/ + +bvt string_refinementt::convert_symbol(const exprt &expr) +{ + const typet &type=expr.type(); + const irep_idt &identifier=expr.get(ID_identifier); + assert(!identifier.empty()); + + if(refined_string_typet::is_unrefined_string_type(type)) + { + string_exprt str= + generator.find_or_add_string_of_symbol(to_symbol_expr(expr)); + bvt bv=convert_bv(str); + return bv; + } + else + return supert::convert_symbol(expr); +} + +/*******************************************************************\ + +Function: string_refinementt::convert_function_application + + Inputs: a function_application + + Outputs: a bitvector + + Purpose: generate an expression, add lemmas stating that this expression + corresponds to the result of the given function call, and convert + this expression + +\*******************************************************************/ + +bvt string_refinementt::convert_function_application +(const function_application_exprt &expr) +{ + debug() << "string_refinementt::convert_function_application " + << from_expr(expr) << eom; + exprt f=generator.add_axioms_for_function_application(expr); + return convert_bv(f); +} + +/*******************************************************************\ + +Function: string_refinementt::boolbv_set_equality_to_true + + Inputs: an equality expression + + Outputs: a Boolean flag to signal a proble + + Purpose: add lemmas to the solver corresponding to the given equation + +\*******************************************************************/ + +bool string_refinementt::boolbv_set_equality_to_true(const equal_exprt &expr) +{ + if(!equality_propagation) + return true; + + // We should not do that everytime, but I cannot find + // another good entry point + if(generator.get_mode()==ID_unknown) + set_mode(); + + typet type=ns.follow(expr.lhs().type()); + + if(expr.lhs().id()==ID_symbol && + // We can have affectation of string from StringBuilder or CharSequence + // type==ns.follow(expr.rhs().type()) && + type.id()!=ID_bool) + { + debug() << "string_refinementt " << from_expr(expr.lhs()) << " <- " + << from_expr(expr.rhs()) << eom; + + + if(expr.rhs().id()==ID_typecast) + { + exprt uncast=to_typecast_expr(expr.rhs()).op(); + if(refined_string_typet::is_unrefined_string_type(uncast.type())) + { + debug() << "(sr) detected casted string" << eom; + symbol_exprt sym=to_symbol_expr(expr.lhs()); + generator.set_string_symbol_equal_to_expr(sym, uncast); + return false; + } + } + + if(refined_string_typet::is_unrefined_string_type(type)) + { + symbol_exprt sym=to_symbol_expr(expr.lhs()); + generator.set_string_symbol_equal_to_expr(sym, expr.rhs()); + return false; + } + else if(type==ns.follow(expr.rhs().type())) + { + if(is_unbounded_array(type)) + return true; + bvt bv1=convert_bv(expr.rhs()); + const irep_idt &identifier= + to_symbol_expr(expr.lhs()).get_identifier(); + map.set_literals(identifier, type, bv1); + if(freeze_all) + set_frozen(bv1); + return false; + } + } + + return true; +} + +/*******************************************************************\ + +Function: string_refinementt::dec_solve + + Outputs: result of the decision procedure + + Purpose: use a refinement loop to instantiate universal axioms, + call the sat solver, and instantiate more indexes if needed. + +\*******************************************************************/ + +decision_proceduret::resultt string_refinementt::dec_solve() +{ + for(const exprt &axiom : generator.axioms) + if(axiom.id()==ID_string_constraint) + { + string_constraintt c=to_string_constraint(axiom); + universal_axioms.push_back(c); + } + else if(axiom.id()==ID_string_not_contains_constraint) + { + string_not_contains_constraintt nc_axiom= + to_string_not_contains_constraint(axiom); + array_typet witness_type + (refined_string_typet::index_type(), + infinity_exprt(refined_string_typet::index_type())); + generator.witness[nc_axiom]= + string_exprt::fresh_symbol("not_contains_witness", witness_type); + not_contains_axioms.push_back(nc_axiom); + } + else + { + add_lemma(axiom); + } + + initial_index_set(universal_axioms); + update_index_set(cur); + cur.clear(); + add_instantiations(); + + while((initial_loop_bound--)>0) + { + decision_proceduret::resultt res=supert::dec_solve(); + + switch(res) + { + case D_SATISFIABLE: + if(!check_axioms()) + { + debug() << "check_SAT: got SAT but the model is not correct" << eom; + } + else + { + debug() << "check_SAT: the model is correct" << eom; + return D_SATISFIABLE; + } + + debug() << "refining..." << eom; + // Since the model is not correct although we got SAT, we need to refine + // the property we are checking by adding more indices to the index set, + // and instantiating universal formulas with this indices. + // We will then relaunch the solver with these added lemmas. + current_index_set.clear(); + update_index_set(cur); + cur.clear(); + add_instantiations(); + + if(current_index_set.empty()) + { + debug() << "current index set is empty" << eom; + return D_SATISFIABLE; + } + + display_index_set(); + debug()<< "instantiating NOT_CONTAINS constraints" << eom; + for(unsigned i=0; i lemmas; + instantiate_not_contains(not_contains_axioms[i], lemmas); + for(const exprt &lemma : lemmas) + add_lemma(lemma); + } + break; + default: + return res; + } + } + debug() << "string_refinementt::dec_solve reached the maximum number" + << "of steps allowed" << eom; + return D_ERROR; +} + +/*******************************************************************\ + +Function: string_refinementt::convert_bool_bv + + Inputs: a Boolean and a expression with the desired type + + Outputs: a bit vector + + Purpose: fills as many 0 as necessary in the bit vectors to have the + right width + +\*******************************************************************/ + +bvt string_refinementt::convert_bool_bv(const exprt &boole, const exprt &orig) +{ + bvt ret; + ret.push_back(convert(boole)); + size_t width=boolbv_width(orig.type()); + ret.resize(width, const_literal(false)); + return ret; +} + +/*******************************************************************\ + +Function: string_refinementt::add_lemma + + Inputs: a lemma + + Purpose: add the given lemma to the solver + +\*******************************************************************/ + +void string_refinementt::add_lemma(const exprt &lemma, bool add_to_index_set) +{ + if(!seen_instances.insert(lemma).second) + return; + + if(lemma.is_true()) + { + debug() << "string_refinementt::add_lemma : tautology" << eom; + return; + } + + debug() << "adding lemma " << from_expr(lemma) << eom; + + prop.l_set_to_true(convert(lemma)); + if(add_to_index_set) + cur.push_back(lemma); +} + +/*******************************************************************\ + +Function: string_refinementt::string_of_array + + Inputs: a constant array expression and a integer expression + + Outputs: a string + + Purpose: convert the content of a string to a more readable representation. + This should only be used for debbuging. + +\*******************************************************************/ + +std::string string_refinementt::string_of_array( + const exprt &arr, const exprt &size) const +{ + if(size.id()!=ID_constant) + return "string of unknown size"; + unsigned n; + if(to_unsigned_integer(to_constant_expr(size), n)) + n=0; + + if(n>MAX_CONCRETE_STRING_SIZE) + return "very long string"; + if(n==0) + return "\"\""; + + std::ostringstream buf; + buf << "\""; + exprt val=get(arr); + + if(val.id()=="array-list") + { + for(size_t i=0; i(c); + } + } + } + } + else + { + return "unable to get array-list"; + } + + buf << "\""; + return buf.str(); +} + +/*******************************************************************\ + +Function: string_refinementt::get_array + + Inputs: an array expression and a integer expression + + Outputs: a string expression + + Purpose: gets a model of an array and put it in a certain form + +\*******************************************************************/ + +exprt string_refinementt::get_array(const exprt &arr, const exprt &size) +{ + exprt val=get(arr); + typet chart; + if(arr.type().subtype()==generator.get_char_type()) + chart=generator.get_char_type(); + else + assert(false); + + if(val.id()=="array-list") + { + array_typet ret_type(chart, infinity_exprt(generator.get_index_type())); + exprt ret=array_of_exprt(generator.constant_char(0), ret_type); + + for(size_t i=0; i 2, y -> -1. + +\*******************************************************************/ + +std::map string_refinementt::map_representation_of_sum( + const exprt &f) const +{ + // number of time the leaf should be added (can be negative) + std::map elems; + + std::list > to_process; + to_process.push_back(std::make_pair(f, true)); + + while(!to_process.empty()) + { + exprt cur=to_process.back().first; + bool positive=to_process.back().second; + to_process.pop_back(); + if(cur.id()==ID_plus) + { + to_process.push_back(std::make_pair(cur.op1(), positive)); + to_process.push_back(std::make_pair(cur.op0(), positive)); + } + else if(cur.id()==ID_minus) + { + to_process.push_back(std::make_pair(cur.op1(), !positive)); + to_process.push_back(std::make_pair(cur.op0(), positive)); + } + else if(cur.id()==ID_unary_minus) + { + to_process.push_back(std::make_pair(cur.op0(), !positive)); + } + else + { + if(positive) + elems[cur]=elems[cur]+1; + else + elems[cur]=elems[cur]-1; + } + } + return elems; +} + +/*******************************************************************\ + +Function: string_refinementt::sum_over_map + + Inputs: a map from expressions to integers + + Outputs: a expression for the sum of each element in the map a number of + times given by the corresponding integer in the map. + For a map x -> 2, y -> -1 would give an expression $x + x - y$. + +\*******************************************************************/ + +exprt string_refinementt::sum_over_map( + std::map &m, bool negated) const +{ + exprt sum=from_integer(0, generator.get_index_type()); + mp_integer constants=0; + + for(const auto &term : m) + { + // We should group constants together... + const exprt &t=term.first; + int second=negated?(-term.second):term.second; + if(t.id()==ID_constant) + { + std::string value(to_constant_expr(t).get_value().c_str()); + constants+=binary2integer(value, true)*second; + } + else + { + switch(second) + { + case -1: + if(sum==from_integer(0, generator.get_index_type())) + sum=unary_minus_exprt(t); + else + sum=minus_exprt(sum, t); + break; + + case 1: + if(sum==from_integer(0, generator.get_index_type())) + sum=t; + else + sum=plus_exprt(sum, t); + break; + + default: + if(second>1) + { + for(int i=0; isecond; i--) + sum=minus_exprt(sum, t); + } + } + } + } + + exprt index_const=from_integer(constants, generator.get_index_type()); + return plus_exprt(sum, index_const); +} + +/*******************************************************************\ + +Function: string_refinementt::simplify_sum + + Inputs: an expression with only plus and minus expr + + Outputs: an equivalent expression in a cannonical form + +\*******************************************************************/ + +exprt string_refinementt::simplify_sum(const exprt &f) const +{ + std::map map=map_representation_of_sum(f); + return sum_over_map(map); +} + +/*******************************************************************\ + +Function: string_refinementt::compute_inverse_function + + Inputs: a symbol qvar, an expression val, an expression f containing + and − + operations in which qvar should appear exactly once. + + Outputs: an expression corresponding of $f^{−1}(val)$ where $f$ is seen as a + function of $qvar$, i.e. the value that is necessary for qvar for f + to be equal to val. For instance, if `f` corresponds to the expression + $q + x$, `compute_inverse_function(q,v,f)` returns an expression for + $v - x$. + +\*******************************************************************/ + +exprt string_refinementt::compute_inverse_function( + const exprt &qvar, const exprt &val, const exprt &f) +{ + exprt positive, negative; + // number of time the element should be added (can be negative) + // qvar has to be equal to val - f(0) if it appears positively in f + // (ie if f(qvar)=f(0) + qvar) and f(0) - val if it appears negatively + // in f. So we start by computing val - f(0). + std::map elems=map_representation_of_sum(minus_exprt(val, f)); + + // true if qvar appears negatively in f (positively in elems): + bool neg=false; + + auto it=elems.find(qvar); + assert(it!=elems.end()); + if(it->second==1 || it->second==-1) + { + neg=(it->second==1); + } + else + { + assert(it->second==0); + debug() << "in string_refinementt::compute_inverse_function:" + << " warning: occurrences of qvar canceled out " << eom; + } + + elems.erase(it); + return sum_over_map(elems, neg); +} + + + +class find_qvar_visitort: public const_expr_visitort +{ +private: + const exprt &qvar_; + +public: + bool found; + + explicit find_qvar_visitort(const exprt &qvar): qvar_(qvar), found(false) {} + + void operator()(const exprt &expr) + { + if(expr==qvar_) + found=true; + } +}; + +/*******************************************************************\ + +Function: find_qvar + + Inputs: an index expression and a symbol qvar + + Outputs: a Boolean + + Purpose: looks for the symbol and return true if it is found + +\*******************************************************************/ + +static bool find_qvar(const exprt index, const symbol_exprt &qvar) +{ + find_qvar_visitort v2(qvar); + index.visit(v2); + return v2.found; +} + +/*******************************************************************\ + +Function: string_refinementt::initial_index_set + + Inputs: a list of string constraints + + Purpose: add to the index set all the indices that appear in the formulas + and the upper bound minus one + +\*******************************************************************/ + +void string_refinementt::initial_index_set( + const std::vector &string_axioms) +{ + for(const auto &axiom : string_axioms) + initial_index_set(axiom); +} + +/*******************************************************************\ + +Function: string_refinementt::update_index_set + + Inputs: a list of string constraints + + Purpose: add to the index set all the indices that appear in the formulas + +\*******************************************************************/ + +void string_refinementt::update_index_set(const std::vector &cur) +{ + for(const auto &axiom : cur) + update_index_set(axiom); +} + +/*******************************************************************\ + +Function: string_refinementt::initial_index_set + + Inputs: a string constraint + + Purpose: add to the index set all the indices that appear in the formula + and the upper bound minus one + +\*******************************************************************/ + +void string_refinementt::initial_index_set(const string_constraintt &axiom) +{ + symbol_exprt qvar=axiom.univ_var(); + std::list to_process; + to_process.push_back(axiom.body()); + + while(!to_process.empty()) + { + exprt cur=to_process.back(); + to_process.pop_back(); + if(cur.id()==ID_index) + { + const exprt &s=cur.op0(); + const exprt &i=cur.op1(); + + bool has_quant_var=find_qvar(i, qvar); + + // 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); + } + else + { + // otherwise we add k-1 + exprt e(i); + minus_exprt kminus1( + axiom.upper_bound(), + from_integer(1, generator.get_index_type())); + replace_expr(qvar, kminus1, e); + current_index_set[s].insert(e); + index_set[s].insert(e); + } + } + else + forall_operands(it, cur) + to_process.push_back(*it); + } +} + +/*******************************************************************\ + +Function: string_refinementt::update_index_set + + Inputs: a string constraint + + Purpose: add to the index set all the indices that appear in the formula + +\*******************************************************************/ + +void string_refinementt::update_index_set(const exprt &formula) +{ + std::list to_process; + to_process.push_back(formula); + + while(!to_process.empty()) + { + exprt cur=to_process.back(); + to_process.pop_back(); + if(cur.id()==ID_index) + { + const exprt &s=cur.op0(); + 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); + } + } + else + { + forall_operands(it, cur) + to_process.push_back(*it); + } + } +} + + +// Will be used to visit an expression and return the index used +// with the given char array +class find_index_visitort: public const_expr_visitort +{ +private: + const exprt &str_; + +public: + explicit find_index_visitort(const exprt &str): str_(str) {} + + void operator()(const exprt &expr) + { + if(expr.id()==ID_index) + { + const index_exprt &i=to_index_expr(expr); + if(i.array()==str_) + throw i.index(); + } + } +}; + +/*******************************************************************\ + +Function: string_refinementt::update_index_set + + Inputs: a formula expr and a char array str + + Outputs: an index expression + + Purpose: find an index used in the expression for str, for instance + with arguments (str[k] == 'a') and str, the function should + return k + +\*******************************************************************/ + +exprt find_index(const exprt &expr, const exprt &str) +{ + find_index_visitort v1(str); + try + { + expr.visit(v1); + return nil_exprt(); + } + catch (exprt i) { return i; } +} + + +/*******************************************************************\ + +Function: string_refinementt::instantiate + + Inputs: an universaly quantified formula `axiom`, an array of char + variable `str`, and an index expression `val`. + + Outputs: substitute `qvar` the universaly 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'$. + +\*******************************************************************/ + +exprt string_refinementt::instantiate( + const string_constraintt &axiom, const exprt &str, const exprt &val) +{ + exprt idx=find_index(axiom.body(), str); + if(idx.is_nil()) + return true_exprt(); + if(!find_qvar(idx, axiom.univ_var())) + return true_exprt(); + + exprt r=compute_inverse_function(axiom.univ_var(), val, idx); + implies_exprt instance(axiom.premise(), axiom.body()); + replace_expr(axiom.univ_var(), r, instance); + // We are not sure the index set contains only positive numbers + exprt bounds=and_exprt( + axiom.univ_within_bounds(), + binary_relation_exprt( + from_integer(0, generator.get_index_type()), ID_le, val)); + replace_expr(axiom.univ_var(), r, bounds); + return implies_exprt(bounds, instance); +} + + +void string_refinementt::instantiate_not_contains( + const string_not_contains_constraintt &axiom, std::list &new_lemmas) +{ + exprt s0=axiom.s0(); + exprt s1=axiom.s1(); + + debug() << "instantiate not contains " << from_expr(s0) << " : " + << from_expr(s1) << eom; + expr_sett index_set0=index_set[to_string_expr(s0).content()]; + expr_sett index_set1=index_set[to_string_expr(s1).content()]; + + for(auto it0 : index_set0) + for(auto it1 : index_set1) + { + debug() << from_expr(it0) << " : " << from_expr(it1) << eom; + exprt val=minus_exprt(it0, it1); + exprt witness=generator.get_witness_of(axiom, val); + and_exprt prem_and_is_witness( + axiom.premise(), + equal_exprt(witness, it1)); + + not_exprt differ( + equal_exprt( + to_string_expr(s0)[it0], + to_string_expr(s1)[it1])); + exprt lemma=implies_exprt(prem_and_is_witness, differ); + + new_lemmas.push_back(lemma); + // we put bounds on the witnesses: + // 0 <= v <= |s0| - |s1| ==> 0 <= v+w[v] < |s0| && 0 <= w[v] < |s1| + exprt zero=from_integer(0, generator.get_index_type()); + binary_relation_exprt c1(zero, ID_le, plus_exprt(val, witness)); + binary_relation_exprt c2 + (to_string_expr(s0).length(), ID_gt, plus_exprt(val, witness)); + binary_relation_exprt c3(to_string_expr(s1).length(), ID_gt, witness); + binary_relation_exprt c4(zero, ID_le, witness); + + minus_exprt diff( + to_string_expr(s0).length(), + to_string_expr(s1).length()); + + and_exprt premise( + binary_relation_exprt(zero, ID_le, val), + binary_relation_exprt(diff, ID_ge, val)); + exprt witness_bounds=implies_exprt( + premise, + and_exprt(and_exprt(c1, c2), and_exprt(c3, c4))); + new_lemmas.push_back(witness_bounds); + } +} diff --git a/src/solvers/refinement/string_refinement.h b/src/solvers/refinement/string_refinement.h new file mode 100644 index 00000000000..aac4eed6dab --- /dev/null +++ b/src/solvers/refinement/string_refinement.h @@ -0,0 +1,120 @@ +/*******************************************************************\ + +Module: String support via creating string constraints and progressively + instantiating the universal constraints as needed. + The procedure is described in the PASS paper at HVC'13: + "PASS: String Solving with Parameterized Array and Interval Automaton" + by Guodong Li and Indradeep Ghosh + +Author: Alberto Griggio, alberto.griggio@gmail.com + +\*******************************************************************/ + +#ifndef CPROVER_SOLVERS_REFINEMENT_STRING_REFINEMENT_H +#define CPROVER_SOLVERS_REFINEMENT_STRING_REFINEMENT_H + +#include + +#include +#include +#include +#include + +// Defines a limit on the string witnesses we will output. +// Longer strings are still concidered possible by the solver but +// it will not output them. +#define MAX_CONCRETE_STRING_SIZE 500 + +#define MAX_NB_REFINEMENT 100 + +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); + + void set_mode(); + + // Should we use counter examples at each iteration? + bool use_counter_example; + + virtual std::string decision_procedure_text() const + { + return "string refinement loop with "+prop.solver_text(); + } + + static exprt is_positive(const exprt &x); + +protected: + typedef std::set expr_sett; + + virtual bvt convert_symbol(const exprt &expr); + virtual bvt convert_function_application( + const function_application_exprt &expr); + + decision_proceduret::resultt dec_solve(); + + bvt convert_bool_bv(const exprt &boole, const exprt &orig); + +private: + // Base class + typedef bv_refinementt supert; + + unsigned initial_loop_bound; + + string_constraint_generatort generator; + + // Simple constraints that have been given to the solver + expr_sett seen_instances; + + std::vector universal_axioms; + + std::vector not_contains_axioms; + + // Unquantified lemmas that have newly been added + std::vector cur; + + // See the definition in the PASS article + // Warning: this is indexed by array_expressions and not string expressions + std::map current_index_set; + std::map index_set; + + void display_index_set(); + + void add_lemma(const exprt &lemma, bool add_to_index_set=true); + + bool boolbv_set_equality_to_true(const equal_exprt &expr); + + literalt convert_rest(const exprt &expr); + + void add_instantiations(); + + bool check_axioms(); + + 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); + + exprt instantiate( + const string_constraintt &axiom, const exprt &str, const exprt &val); + + void instantiate_not_contains( + const string_not_contains_constraintt &axiom, + std::list &new_lemmas); + + 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 simplify_sum(const exprt &f) const; + + exprt get_array(const exprt &arr, const exprt &size); + + std::string string_of_array(const exprt &arr, const exprt &size) const; +}; + +#endif From 0b2a5c18d49f90a37c31aa3d92f47124d28e652d Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Nov 2016 14:53:54 +0000 Subject: [PATCH 155/166] Remove virtual functions: shorten dispatch table Previously the dispatch table contained an entry per potential callee type; this reduces that to an entry per *distinct* callee function, which can be much shorter e.g. for java.lang.Object.equals, which every type has by inheritence but is often not overridden. --- .../remove_virtual_functions.cpp | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index 56c89dac3f0..77ffb074d11 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -123,7 +123,6 @@ void remove_virtual_functionst::remove_virtual_function( assert(target->is_function_call()); to_code_function_call(target->code).function()= functions.begin()->symbol_expr; - return; } @@ -142,46 +141,54 @@ void remove_virtual_functionst::remove_virtual_function( // If necessary, cast to the last candidate function to // get the object's clsid. By the structure of get_functions, // this is the parent of all other classes under consideration. - symbol_typet suggested_type(functions.back().class_id); + const auto &base_classid=functions.back().class_id; + const auto &base_function_symbol=functions.back().symbol_expr; + symbol_typet suggested_type(base_classid); exprt c_id2=get_class_identifier_field(this_expr, suggested_type, ns); - goto_programt::targett last_function; - for(const auto &fun : functions) + std::map calls; + // Note backwards iteration, to get the least-derived candidate first. + for(auto it=functions.crbegin(), itend=functions.crend(); it!=itend; ++it) { - goto_programt::targett t1=new_code_calls.add_instruction(); - if(!fun.symbol_expr.get_identifier().empty()) + const auto &fun=*it; + auto insertit=calls.insert( + {fun.symbol_expr.get_identifier(), goto_programt::targett()}); + + // Only create one call sequence per possible target: + if(insertit.second) { + goto_programt::targett t1=new_code_calls.add_instruction(); + if(!fun.symbol_expr.get_identifier().empty()) + { // call function - t1->make_function_call(code); - auto &newcall=to_code_function_call(t1->code); - newcall.function()=fun.symbol_expr; - pointer_typet need_type(symbol_typet(fun.symbol_expr.get(ID_C_class))); - if(!type_eq(newcall.arguments()[0].type(), need_type, ns)) - newcall.arguments()[0].make_typecast(need_type); + t1->make_function_call(code); + auto &newcall=to_code_function_call(t1->code); + newcall.function()=fun.symbol_expr; + pointer_typet need_type(symbol_typet(fun.symbol_expr.get(ID_C_class))); + if(!type_eq(newcall.arguments()[0].type(), need_type, ns)) + newcall.arguments()[0].make_typecast(need_type); + } + else + { + // No definition for this type; shouldn't be possible... + t1->make_assertion(false_exprt()); + } + insertit.first->second=t1; + // goto final + goto_programt::targett t3=new_code_calls.add_instruction(); + t3->make_goto(t_final, true_exprt()); } - else + + // If this calls the base function we just fall through. + // Otherwise branch to the right call: + if(fun.symbol_expr!=base_function_symbol) { - // No definition for this type; shouldn't be possible... - t1->make_assertion(false_exprt()); + exprt c_id1=constant_exprt(fun.class_id, string_typet()); + goto_programt::targett t4=new_code_gotos.add_instruction(); + t4->make_goto(insertit.first->second, equal_exprt(c_id1, c_id2)); } - - last_function=t1; - - // goto final - goto_programt::targett t3=new_code_calls.add_instruction(); - t3->make_goto(t_final, true_exprt()); - - exprt c_id1=constant_exprt(fun.class_id, string_typet()); - - goto_programt::targett t4=new_code_gotos.add_instruction(); - t4->make_goto(t1, equal_exprt(c_id1, c_id2)); } - // In any other case (most likely a stub class) call the most basic - // version of the method we know to exist: - goto_programt::targett fallthrough=new_code_gotos.add_instruction(); - fallthrough->make_goto(last_function); - goto_programt new_code; // patch them all together From 3f0a880385dd06775a1356c86e5e9e926b722889 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 3 Nov 2016 09:41:00 +0000 Subject: [PATCH 156/166] If the only dispatch option is abstract, erase the call This can happen if the callee library isn't available and we're not mocking it. --- src/goto-programs/remove_virtual_functions.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index 77ffb074d11..dccb6c5f233 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -121,8 +121,11 @@ void remove_virtual_functionst::remove_virtual_function( if(functions.size()==1) { assert(target->is_function_call()); - to_code_function_call(target->code).function()= - functions.begin()->symbol_expr; + if(functions.begin()->symbol_expr==symbol_exprt()) + target->make_skip(); + else + to_code_function_call(target->code).function()= + functions.begin()->symbol_expr; return; } From e7208379ebd6a6bc6b3c0807a60243301c37747b Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 31 Jan 2017 16:15:58 +0000 Subject: [PATCH 157/166] Make test more tolerant of formatting differences Side-effect of the virtual function table abbreviation code was to give a callsite a more expressive source_location than before. --- regression/cbmc-java/NullPointer2/test.desc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression/cbmc-java/NullPointer2/test.desc b/regression/cbmc-java/NullPointer2/test.desc index f89103d5f52..3be1eaa44fc 100644 --- a/regression/cbmc-java/NullPointer2/test.desc +++ b/regression/cbmc-java/NullPointer2/test.desc @@ -3,7 +3,7 @@ NullPointer2.class --pointer-check --stop-on-fail ^EXIT=10$ ^SIGNAL=0$ -^ file NullPointer2.java line 9 function java::NullPointer2.main:(\[Ljava/lang/String;)V$ +^ file NullPointer2.java line 9 function java::NullPointer2.main:(\[Ljava/lang/String;)V ^VERIFICATION FAILED$ -- ^warning: ignoring From 48ffff3a5afe4d51faae594184b7a6f2e58d7b6c Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 31 Jan 2017 16:18:07 +0000 Subject: [PATCH 158/166] Add test for vtable abbreviation Also amend virtual6 whose expected results are now slightly different. --- regression/cbmc-java/virtual6/test.desc | 1 - regression/cbmc-java/virtual7/A.class | Bin 0 -> 222 bytes regression/cbmc-java/virtual7/B.class | Bin 0 -> 207 bytes regression/cbmc-java/virtual7/C.class | Bin 0 -> 207 bytes regression/cbmc-java/virtual7/D.class | Bin 0 -> 164 bytes regression/cbmc-java/virtual7/E.class | Bin 0 -> 164 bytes regression/cbmc-java/virtual7/test.class | Bin 0 -> 371 bytes regression/cbmc-java/virtual7/test.desc | 12 +++++++++++ regression/cbmc-java/virtual7/test.java | 25 +++++++++++++++++++++++ 9 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 regression/cbmc-java/virtual7/A.class create mode 100644 regression/cbmc-java/virtual7/B.class create mode 100644 regression/cbmc-java/virtual7/C.class create mode 100644 regression/cbmc-java/virtual7/D.class create mode 100644 regression/cbmc-java/virtual7/E.class create mode 100644 regression/cbmc-java/virtual7/test.class create mode 100644 regression/cbmc-java/virtual7/test.desc create mode 100644 regression/cbmc-java/virtual7/test.java diff --git a/regression/cbmc-java/virtual6/test.desc b/regression/cbmc-java/virtual6/test.desc index 8432c7b2303..5a5a7c7bf3b 100644 --- a/regression/cbmc-java/virtual6/test.desc +++ b/regression/cbmc-java/virtual6/test.desc @@ -5,4 +5,3 @@ A.class ^SIGNAL=0$ IF "java::C".*THEN GOTO IF "java::B".*THEN GOTO -IF "java::A".*THEN GOTO diff --git a/regression/cbmc-java/virtual7/A.class b/regression/cbmc-java/virtual7/A.class new file mode 100644 index 0000000000000000000000000000000000000000..c6db51203199b01a76a911c4b7531e7bb162cc1d GIT binary patch literal 222 zcmX^0Z`VEs1_l!bJ}w4k25xo+9(D#^Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2xA%}16OcPq|~C2#H1Xc2xA%}16Oc2S859_p zfaZe$6A%Ms7=V@lS+YQy5lFLYZD(NI2xKraumedpu%H-_#Q|3;36=$_KvyOKRLlvK IWMbd~0ED9%)c^nh literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/virtual7/C.class b/regression/cbmc-java/virtual7/C.class new file mode 100644 index 0000000000000000000000000000000000000000..3c1ddff3a73a3e87ff98fc3cdb357bd35cce38ad GIT binary patch literal 207 zcmX^0Z`VEs1_l!bJ}w4k25xo+9(D#^Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2xA%}16Ocb^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBFZS&~{@qL-CemdL}v!obSNz~}b^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBFZS&~{@qL-CemdL}v!obSNz~~CZP7DeROhB_i ofDwp+GC-OQ$dU!pAQ4ur?F@_?!P4wNk_{}V0VFwqJSGNC06{+(bpQYW literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/virtual7/test.class b/regression/cbmc-java/virtual7/test.class new file mode 100644 index 0000000000000000000000000000000000000000..38d77aa50e8af9680f4d61ac192b438429eddede GIT binary patch literal 371 zcmYLF%SyvQ6g@YYWRhuY&=2sV z#5-N+z`5t#a}RTe`TqI%0&s*Kg(~V2D+-q3RRv*qO~Ez1uHYHoP*A9w(56H~VvFFO zWO-J!3HILp13`2~Jx!?HWVybb3{yS6PtpN9Vwhw(K}Dm}Bb=Gr_C8_7cFAQ5JBmdK!ODqZr-aK&MzLGMW93J&ETLFcqU)w} Z_>SOzM-?`2k~rpnJ4J=>UgF-u@-HF!Hl_do literal 0 HcmV?d00001 diff --git a/regression/cbmc-java/virtual7/test.desc b/regression/cbmc-java/virtual7/test.desc new file mode 100644 index 00000000000..b2b26ecb9ce --- /dev/null +++ b/regression/cbmc-java/virtual7/test.desc @@ -0,0 +1,12 @@ +CORE +test.class +--show-goto-functions +^EXIT=0$ +^SIGNAL=0$ +IF "java::E".*THEN GOTO [12] +IF "java::B".*THEN GOTO [12] +IF "java::D".*THEN GOTO [12] +IF "java::C".*THEN GOTO [12] +-- +IF "java::A".*THEN GOTO +GOTO 4 diff --git a/regression/cbmc-java/virtual7/test.java b/regression/cbmc-java/virtual7/test.java new file mode 100644 index 00000000000..dc2d3043925 --- /dev/null +++ b/regression/cbmc-java/virtual7/test.java @@ -0,0 +1,25 @@ +public class test { + public static void main() { + A[] as = { new A(), new B(), new C(), new D(), new E() }; + as[2].f(); + } +} + +class A { + void f() { } +} + + +class B extends A { + void f() { } +} + +class C extends A { + void f() { } +} + +class D extends C { +} + +class E extends B { +} From 49d1ae7fc9ba1aad459eab0f2f9689f89d3708d6 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 1 Feb 2017 15:17:24 +0000 Subject: [PATCH 159/166] Add source locations to virt calls This confers the source location belonging to a virtual call to the code implementing its expanded vtable. --- src/goto-programs/remove_virtual_functions.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/goto-programs/remove_virtual_functions.cpp b/src/goto-programs/remove_virtual_functions.cpp index dccb6c5f233..da9cce5039f 100644 --- a/src/goto-programs/remove_virtual_functions.cpp +++ b/src/goto-programs/remove_virtual_functions.cpp @@ -104,6 +104,8 @@ void remove_virtual_functionst::remove_virtual_function( const code_function_callt &code= to_code_function_call(target->code); + const auto &vcall_source_loc=target->source_location; + const exprt &function=code.function(); assert(function.id()==ID_virtual_function); assert(!code.arguments().empty()); @@ -133,6 +135,8 @@ void remove_virtual_functionst::remove_virtual_function( goto_programt final_skip; goto_programt::targett t_final=final_skip.add_instruction(); + t_final->source_location=vcall_source_loc; + t_final->make_skip(); // build the calls and gotos @@ -161,6 +165,7 @@ void remove_virtual_functionst::remove_virtual_function( if(insertit.second) { goto_programt::targett t1=new_code_calls.add_instruction(); + t1->source_location=vcall_source_loc; if(!fun.symbol_expr.get_identifier().empty()) { // call function @@ -179,6 +184,7 @@ void remove_virtual_functionst::remove_virtual_function( insertit.first->second=t1; // goto final goto_programt::targett t3=new_code_calls.add_instruction(); + t3->source_location=vcall_source_loc; t3->make_goto(t_final, true_exprt()); } @@ -188,6 +194,7 @@ void remove_virtual_functionst::remove_virtual_function( { exprt c_id1=constant_exprt(fun.class_id, string_typet()); goto_programt::targett t4=new_code_gotos.add_instruction(); + t4->source_location=vcall_source_loc; t4->make_goto(insertit.first->second, equal_exprt(c_id1, c_id2)); } } From f84460da71216a8cb0d20ec52483633a8112295f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 6 Dec 2016 16:53:53 +0000 Subject: [PATCH 160/166] Make string literal tables global The string literal uniqueing tables only work if they can see every string in the program, and if multiple .class files are specified on the command-line, multiple java_bytecode_typecheckt instances are created. Literal symbol creation would then fail if the two classes used matching literals. Note this does not apply to classes loaded on demand or from a JAR file, which *do* share a typecheckt instance with their parent. --- src/java_bytecode/java_bytecode_typecheck.cpp | 6 ++++++ src/java_bytecode/java_bytecode_typecheck.h | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/java_bytecode/java_bytecode_typecheck.cpp b/src/java_bytecode/java_bytecode_typecheck.cpp index e72b80a885d..9e1c5f2a732 100644 --- a/src/java_bytecode/java_bytecode_typecheck.cpp +++ b/src/java_bytecode/java_bytecode_typecheck.cpp @@ -184,3 +184,9 @@ bool java_bytecode_typecheck( // fail for now return true; } + +// Static members of java_bytecode_typecheckt: +std::map + java_bytecode_typecheckt::string_literal_to_symbol_name; +std::map + java_bytecode_typecheckt::escaped_string_literal_count; diff --git a/src/java_bytecode/java_bytecode_typecheck.h b/src/java_bytecode/java_bytecode_typecheck.h index e22a9db545b..7b12a4ffbb5 100644 --- a/src/java_bytecode/java_bytecode_typecheck.h +++ b/src/java_bytecode/java_bytecode_typecheck.h @@ -64,8 +64,8 @@ class java_bytecode_typecheckt:public typecheckt virtual std::string to_string(const typet &type); std::set already_typechecked; - std::map string_literal_to_symbol_name; - std::map escaped_string_literal_count; + static std::map string_literal_to_symbol_name; + static std::map escaped_string_literal_count; }; #endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_TYPECHECK_H From b6b006350bd2177e2c0a1b759a5fc66612706865 Mon Sep 17 00:00:00 2001 From: Joel Allred Date: Tue, 7 Feb 2017 17:08:20 +0000 Subject: [PATCH 161/166] Correct return value test of to_integer (#508) to_integer returns true in case of error. The contrary was assumed in convert_constant(). --- src/java_bytecode/expr2java.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/java_bytecode/expr2java.cpp b/src/java_bytecode/expr2java.cpp index 7fb050dddad..3cd487e234a 100644 --- a/src/java_bytecode/expr2java.cpp +++ b/src/java_bytecode/expr2java.cpp @@ -215,7 +215,7 @@ std::string expr2javat::convert_constant( dest.reserve(char_representation_length); mp_integer int_value; - if(!to_integer(src, int_value)) + if(to_integer(src, int_value)) assert(false); dest+="(char)'"; @@ -238,7 +238,7 @@ std::string expr2javat::convert_constant( { // No byte-literals in Java, so just cast: mp_integer int_value; - if(!to_integer(src, int_value)) + if(to_integer(src, int_value)) assert(false); std::string dest="(byte)"; dest+=integer2string(int_value); @@ -248,7 +248,7 @@ std::string expr2javat::convert_constant( { // No short-literals in Java, so just cast: mp_integer int_value; - if(!to_integer(src, int_value)) + if(to_integer(src, int_value)) assert(false); std::string dest="(short)"; dest+=integer2string(int_value); @@ -258,7 +258,8 @@ std::string expr2javat::convert_constant( { // long integer literals must have 'L' at the end mp_integer int_value; - to_integer(src, int_value); + if(to_integer(src, int_value)) + assert(false); std::string dest=integer2string(int_value); dest+='L'; return dest; From 2ee34f339b8e0c711770e684066c70d3905b26c8 Mon Sep 17 00:00:00 2001 From: NathanJPhillips Date: Mon, 23 Jan 2017 11:46:19 +0000 Subject: [PATCH 162/166] Fixed use of inline --- src/util/json.h | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/util/json.h b/src/util/json.h index acfeafacdad..18182b97c96 100644 --- a/src/util/json.h +++ b/src/util/json.h @@ -24,53 +24,53 @@ class jsont J_TRUE, J_FALSE, J_NULL } kindt; kindt kind; - inline bool is_string() const + bool is_string() const { return kind==J_STRING; } - inline bool is_number() const + bool is_number() const { return kind==J_NUMBER; } - inline bool is_object() const + bool is_object() const { return kind==J_OBJECT; } - inline bool is_array() const + bool is_array() const { return kind==J_ARRAY; } - inline bool is_true() const + bool is_true() const { return kind==J_TRUE; } - inline bool is_false() const + bool is_false() const { return kind==J_FALSE; } - inline bool is_null() const + bool is_null() const { return kind==J_NULL; } - inline jsont():kind(J_NULL) + jsont():kind(J_NULL) { } - inline void output(std::ostream &out) const + void output(std::ostream &out) const { output_rec(out, 0); } void swap(jsont &other); - inline static jsont json_boolean(bool value) + static jsont json_boolean(bool value) { return jsont(value?J_TRUE:J_FALSE); } @@ -83,11 +83,11 @@ class jsont array.clear(); } - inline json_arrayt &make_array(); - inline json_objectt &make_object(); + json_arrayt &make_array(); + json_objectt &make_object(); // this presumes that this is an object - inline const jsont &operator[](const std::string &key) const + const jsont &operator[](const std::string &key) const { objectt::const_iterator it=object.find(key); if(it==object.end()) @@ -102,11 +102,11 @@ class jsont static const jsont null_json_object; - inline explicit jsont(kindt _kind):kind(_kind) + explicit jsont(kindt _kind):kind(_kind) { } - inline jsont(kindt _kind, const std::string &_value):kind(_kind), value(_value) + jsont(kindt _kind, const std::string &_value):kind(_kind), value(_value) { } @@ -134,7 +134,7 @@ class json_arrayt:public jsont { } - inline void resize(std::size_t size) + void resize(std::size_t size) { array.resize(size); } @@ -144,13 +144,13 @@ class json_arrayt:public jsont return array.size(); } - inline jsont &push_back(const jsont &json) + jsont &push_back(const jsont &json) { array.push_back(json); return static_cast(array.back()); } - inline jsont &push_back() + jsont &push_back() { array.push_back(jsont()); return static_cast(array.back()); @@ -182,12 +182,12 @@ class json_objectt:public jsont { } - inline jsont &operator[](const std::string &key) + jsont &operator[](const std::string &key) { return object[key]; } - inline const jsont &operator[](const std::string &key) const + const jsont &operator[](const std::string &key) const { objectt::const_iterator it=object.find(key); if(it==object.end()) @@ -215,13 +215,13 @@ class json_nullt:public jsont json_nullt():jsont(J_NULL) { } }; -json_arrayt &jsont::make_array() +inline json_arrayt &jsont::make_array() { kind=J_ARRAY; return static_cast(*this); } -json_objectt &jsont::make_object() +inline json_objectt &jsont::make_object() { kind=J_OBJECT; return static_cast(*this); From 932ba572be38dc3da56825116f29fbf2f4894e6c Mon Sep 17 00:00:00 2001 From: Lucas Cordeiro Date: Fri, 27 Jan 2017 13:51:54 +0000 Subject: [PATCH 163/166] Added regression tests for full-slice option Added 18 tests cases extracted from the literature on program slicing in order to test the full-slice option --- regression/cbmc/slice01/main.c | 70 ++++++++++++++++++++ regression/cbmc/slice01/test.desc | 8 +++ regression/cbmc/slice02/main.c | 73 +++++++++++++++++++++ regression/cbmc/slice02/test.desc | 8 +++ regression/cbmc/slice03/main.c | 102 ++++++++++++++++++++++++++++++ regression/cbmc/slice03/test.desc | 8 +++ regression/cbmc/slice04/main.c | 58 +++++++++++++++++ regression/cbmc/slice04/test.desc | 8 +++ regression/cbmc/slice05/main.c | 15 +++++ regression/cbmc/slice05/test.desc | 8 +++ regression/cbmc/slice06/main.c | 15 +++++ regression/cbmc/slice06/test.desc | 8 +++ regression/cbmc/slice07/main.c | 50 +++++++++++++++ regression/cbmc/slice07/test.desc | 8 +++ regression/cbmc/slice08/main.c | 21 ++++++ regression/cbmc/slice08/test.desc | 8 +++ regression/cbmc/slice09/main.c | 9 +++ regression/cbmc/slice09/test.desc | 8 +++ regression/cbmc/slice10/main.c | 18 ++++++ regression/cbmc/slice10/test.desc | 8 +++ regression/cbmc/slice11/main.c | 18 ++++++ regression/cbmc/slice11/test.desc | 8 +++ regression/cbmc/slice12/main.c | 12 ++++ regression/cbmc/slice12/test.desc | 8 +++ regression/cbmc/slice13/main.c | 23 +++++++ regression/cbmc/slice13/test.desc | 8 +++ regression/cbmc/slice14/main.c | 15 +++++ regression/cbmc/slice14/test.desc | 8 +++ regression/cbmc/slice15/main.c | 24 +++++++ regression/cbmc/slice15/test.desc | 8 +++ regression/cbmc/slice16/main.c | 48 ++++++++++++++ regression/cbmc/slice16/test.desc | 8 +++ regression/cbmc/slice17/main.c | 35 ++++++++++ regression/cbmc/slice17/test.desc | 8 +++ regression/cbmc/slice18/main.c | 11 ++++ regression/cbmc/slice18/test.desc | 8 +++ 36 files changed, 761 insertions(+) create mode 100644 regression/cbmc/slice01/main.c create mode 100644 regression/cbmc/slice01/test.desc create mode 100644 regression/cbmc/slice02/main.c create mode 100644 regression/cbmc/slice02/test.desc create mode 100644 regression/cbmc/slice03/main.c create mode 100644 regression/cbmc/slice03/test.desc create mode 100644 regression/cbmc/slice04/main.c create mode 100644 regression/cbmc/slice04/test.desc create mode 100644 regression/cbmc/slice05/main.c create mode 100644 regression/cbmc/slice05/test.desc create mode 100644 regression/cbmc/slice06/main.c create mode 100644 regression/cbmc/slice06/test.desc create mode 100644 regression/cbmc/slice07/main.c create mode 100644 regression/cbmc/slice07/test.desc create mode 100644 regression/cbmc/slice08/main.c create mode 100644 regression/cbmc/slice08/test.desc create mode 100644 regression/cbmc/slice09/main.c create mode 100644 regression/cbmc/slice09/test.desc create mode 100644 regression/cbmc/slice10/main.c create mode 100644 regression/cbmc/slice10/test.desc create mode 100644 regression/cbmc/slice11/main.c create mode 100644 regression/cbmc/slice11/test.desc create mode 100644 regression/cbmc/slice12/main.c create mode 100644 regression/cbmc/slice12/test.desc create mode 100644 regression/cbmc/slice13/main.c create mode 100644 regression/cbmc/slice13/test.desc create mode 100644 regression/cbmc/slice14/main.c create mode 100644 regression/cbmc/slice14/test.desc create mode 100644 regression/cbmc/slice15/main.c create mode 100644 regression/cbmc/slice15/test.desc create mode 100644 regression/cbmc/slice16/main.c create mode 100644 regression/cbmc/slice16/test.desc create mode 100644 regression/cbmc/slice17/main.c create mode 100644 regression/cbmc/slice17/test.desc create mode 100644 regression/cbmc/slice18/main.c create mode 100644 regression/cbmc/slice18/test.desc diff --git a/regression/cbmc/slice01/main.c b/regression/cbmc/slice01/main.c new file mode 100644 index 00000000000..7502ff7413a --- /dev/null +++ b/regression/cbmc/slice01/main.c @@ -0,0 +1,70 @@ +#include +#include +#include + +typedef struct list +{ + int key; + struct list *next; +} mlist; + +mlist *head; + +mlist* search_list(mlist *l, int k) +{ + l = head; + while(l!=NULL && l->key!=k) + { + l = l->next; + } + return l; +} + +int delete_list(mlist *l) +{ + mlist *tmp; + tmp = head; + if (head != l) + { + while(tmp->next!=l) + tmp = tmp->next; + tmp->next = l->next; + } + else + { + head = l->next; + } + free(l); + return 0; +} + +int insert_list(mlist *l, int k) +{ + l = (mlist*)malloc(sizeof(mlist)); + if (head==NULL) + { + l->key = k; + l->next = NULL; + } + else + { + l->key = k; + l->next = head; + } + head = l; + return 0; +} + +int main(void) +{ + int i; + mlist *mylist, *temp; + insert_list(mylist,2); + insert_list(mylist,5); + insert_list(mylist,1); + insert_list(mylist,3); + mylist = head; + temp = search_list(mylist,2); + assert(temp->key == 2); + delete_list(temp); +} diff --git a/regression/cbmc/slice01/test.desc b/regression/cbmc/slice01/test.desc new file mode 100644 index 00000000000..6f19f2d9ef6 --- /dev/null +++ b/regression/cbmc/slice01/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--unwind 2 --full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice02/main.c b/regression/cbmc/slice02/main.c new file mode 100644 index 00000000000..8c7aa38de2c --- /dev/null +++ b/regression/cbmc/slice02/main.c @@ -0,0 +1,73 @@ +#include + +#define TRUE (1) +#define FALSE (0) +#define SIZE (10) +int topo=0; + +void inc_topo(void){ + topo++; +} + +void dec_topo(void){ + topo--; +} + +int get_topo(void){ + return topo; +} + +int stack_empty(void){ + (topo==0) ? TRUE : FALSE; +} + +int push(int *stack, int x){ + if (topo==SIZE) { + printf("stack overflow\n"); + return -1; + } else { + stack[get_topo()] = x; + printf("push: stack[%d] = %d\n", get_topo(), stack[get_topo()]); + inc_topo(); + } +} + +int pop(int *stack){ + if (get_topo()==0) { + printf("stack underflow\n"); + return -1; + } else { + dec_topo(); + printf("pop: stack[%d] = %d\n", get_topo(), stack[get_topo()]); + return stack[get_topo()]; + } +} + +int main(void) { + int arr[SIZE]; + + push(arr,3); + push(arr,4); + push(arr,5); + push(arr,1); + push(arr,9); + push(arr,10); + push(arr,6); + push(arr,12); + push(arr,15); + push(arr,8); + push(arr,20); + + pop(arr); + pop(arr); + pop(arr); + pop(arr); + pop(arr); + pop(arr); + pop(arr); + pop(arr); + pop(arr); + pop(arr); + pop(arr); + +} diff --git a/regression/cbmc/slice02/test.desc b/regression/cbmc/slice02/test.desc new file mode 100644 index 00000000000..2d61905c826 --- /dev/null +++ b/regression/cbmc/slice02/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--pointer-check --full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice03/main.c b/regression/cbmc/slice03/main.c new file mode 100644 index 00000000000..589c5db2e70 --- /dev/null +++ b/regression/cbmc/slice03/main.c @@ -0,0 +1,102 @@ +#include + +#define SIZE 10 + +typedef struct{ + int elemento[SIZE]; + int inicio; + int fim; + int quantidade; +} QType; + +int inicializa(QType *q) { + q->inicio=0; + q->fim=0; + q->quantidade=0; +} + +int empty(QType * q) { + if (q->inicio == q->fim) { + printf("queue is empty\n"); + return -1; + } + else return 0; +} + +int full(QType * q) { + + if (q->quantidade == SIZE) { + printf("queue is full\n"); + return -1; + } else{ + return 0; + } +} + +int enqueue(QType *q, int x) { + q->elemento[q->fim] = x; + q->quantidade++; + if (q->fim == SIZE) { + q->fim = 0; + } else { + q->fim++; + } + return 0; +} + +int dequeue(QType *q) { + + int x; + + x = q->elemento[q->inicio]; + q->quantidade--; + if (q->inicio == SIZE) { + q->inicio = 0; + } else { + q->inicio++; + } + + return x; +} + + +int main(void) { + + QType queue; + + int i,temp; + + inicializa(&queue); + + empty(&queue); + + enqueue(&queue,2); + + empty(&queue); + + enqueue(&queue,4); + enqueue(&queue,1); + enqueue(&queue,5); + enqueue(&queue,3); + enqueue(&queue,8); + enqueue(&queue,6); + enqueue(&queue,7); + enqueue(&queue,10); + enqueue(&queue,9); + + full(&queue); + + temp = dequeue(&queue); + + printf("temp = %d\n", temp); + + temp = dequeue(&queue); + + printf("temp = %d\n", temp); + + for(i=queue.inicio; i + +#define FULP 1 + +void bug (float min) { + __CPROVER_assume(min == 0x1.fffffep-105f); + float modifier = (0x1.0p-23 * (1<0); + + return 0; +} diff --git a/regression/cbmc/slice06/test.desc b/regression/cbmc/slice06/test.desc new file mode 100644 index 00000000000..3793f7374e1 --- /dev/null +++ b/regression/cbmc/slice06/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice07/main.c b/regression/cbmc/slice07/main.c new file mode 100644 index 00000000000..b0acb74a73c --- /dev/null +++ b/regression/cbmc/slice07/main.c @@ -0,0 +1,50 @@ +#include +#include + +//#define NULL 0 + +int g; + +void *t1(void *arg) +{ + int a1, *aptr1; + + aptr1=(int *)arg; + a1=*aptr1; + g=0; + // this should pass + assert(a1==10); + assert(g==0); + + return NULL; +} + +void *t2(void *arg) +{ + int a2, *aptr2; + + aptr2=(int *)arg; + a2=*aptr2; + g=0; + // this should pass + assert(a2==20); + + return NULL; +} + +int main() +{ + pthread_t id1, id2; + + int arg1=10, arg2=20; + + pthread_create(&id1, NULL, t1, &arg1); + pthread_create(&id2, NULL, t2, &arg2); + + assert(g==0); + + pthread_join(id1, NULL); + pthread_join(id2, NULL); + + return 0; +} diff --git a/regression/cbmc/slice07/test.desc b/regression/cbmc/slice07/test.desc new file mode 100644 index 00000000000..7d88efc76ad --- /dev/null +++ b/regression/cbmc/slice07/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--full-slice +^EXIT=6$ +^SIGNAL=0$ +^\-\-full\-slice does not support C/Pthreads yet$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice08/main.c b/regression/cbmc/slice08/main.c new file mode 100644 index 00000000000..c16cd2784ab --- /dev/null +++ b/regression/cbmc/slice08/main.c @@ -0,0 +1,21 @@ +#include +#include + +int main (void) +{ + int x; + int i; + + if (x > 0) { + for (i = 0; i < x; ++i) { + // Do nothing; + } + } else { + x = 1; + } + + assert(x >= 1); + + return 0; +} + diff --git a/regression/cbmc/slice08/test.desc b/regression/cbmc/slice08/test.desc new file mode 100644 index 00000000000..67625747cf1 --- /dev/null +++ b/regression/cbmc/slice08/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--full-slice --unwind 1 +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice09/main.c b/regression/cbmc/slice09/main.c new file mode 100644 index 00000000000..6cc9ba5bc92 --- /dev/null +++ b/regression/cbmc/slice09/main.c @@ -0,0 +1,9 @@ +#include +int n=2; +void main() +{ + int i=1; + while (i <= n) + i++; + assert(i>=0); +} diff --git a/regression/cbmc/slice09/test.desc b/regression/cbmc/slice09/test.desc new file mode 100644 index 00000000000..3793f7374e1 --- /dev/null +++ b/regression/cbmc/slice09/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice10/main.c b/regression/cbmc/slice10/main.c new file mode 100644 index 00000000000..dd59d87af39 --- /dev/null +++ b/regression/cbmc/slice10/main.c @@ -0,0 +1,18 @@ +#include +int n=2, i, s, a = 0; +void main() +{ + i = 1; + s = 1; + if (a > 0) + s = 0; + while (i <= n) + { + if (a > 0) + s += 2; + else + s *= 2; + i++; + } + assert(s>0); +} diff --git a/regression/cbmc/slice10/test.desc b/regression/cbmc/slice10/test.desc new file mode 100644 index 00000000000..3793f7374e1 --- /dev/null +++ b/regression/cbmc/slice10/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice11/main.c b/regression/cbmc/slice11/main.c new file mode 100644 index 00000000000..b87123d1abe --- /dev/null +++ b/regression/cbmc/slice11/main.c @@ -0,0 +1,18 @@ +#include +int n=2, i, s, a = 0; +void main() +{ + i = 1; + s = 1; + if (a > 0) + s = 0; + while (i <= n) + { + if (a > 0) + s += 2; + else + s *= 2; + i++; + } + assert(i>0); +} diff --git a/regression/cbmc/slice11/test.desc b/regression/cbmc/slice11/test.desc new file mode 100644 index 00000000000..3793f7374e1 --- /dev/null +++ b/regression/cbmc/slice11/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice12/main.c b/regression/cbmc/slice12/main.c new file mode 100644 index 00000000000..7b395dc27d3 --- /dev/null +++ b/regression/cbmc/slice12/main.c @@ -0,0 +1,12 @@ +#include +int n=2, i, s, a = 0; +void main() +{ + i = 1; + s = 1; + if (a > 0) + s = 0; + if (n==1) + s=1; + assert(n>0); +} diff --git a/regression/cbmc/slice12/test.desc b/regression/cbmc/slice12/test.desc new file mode 100644 index 00000000000..3793f7374e1 --- /dev/null +++ b/regression/cbmc/slice12/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice13/main.c b/regression/cbmc/slice13/main.c new file mode 100644 index 00000000000..3354961512a --- /dev/null +++ b/regression/cbmc/slice13/main.c @@ -0,0 +1,23 @@ +#ifdef __GNUC__ +#include +#include +#include + +float setRoundingModeAndCast(int mode, double d) { + fesetround(mode); + return (float)d; +} + +void test (int mode, double d, float result) { + float f = setRoundingModeAndCast(mode,d); + assert(f == result); + return; +} +#endif + +int main (void) +{ + // Nearer to 0x1.fffffep+127 than to 0x1.000000p+128 + test(FE_UPWARD, 0x1.fffffe0000001p+127, +INFINITY); + return 1; +} diff --git a/regression/cbmc/slice13/test.desc b/regression/cbmc/slice13/test.desc new file mode 100644 index 00000000000..4d8899e64c7 --- /dev/null +++ b/regression/cbmc/slice13/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--floatbv --full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice14/main.c b/regression/cbmc/slice14/main.c new file mode 100644 index 00000000000..ef23ab68a1a --- /dev/null +++ b/regression/cbmc/slice14/main.c @@ -0,0 +1,15 @@ +void *malloc(__CPROVER_size_t); +void free(void *); + +int main() +{ + int *p=malloc(sizeof(int)); + int *q=p; + int i, x; + i=x; + + if(i==4711) free(q); + + // should fail if i==4711 + *p=1; +} diff --git a/regression/cbmc/slice14/test.desc b/regression/cbmc/slice14/test.desc new file mode 100644 index 00000000000..a2b36885fc7 --- /dev/null +++ b/regression/cbmc/slice14/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--pointer-check --full-slice +^EXIT=10$ +^SIGNAL=0$ +^VERIFICATION FAILED$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice15/main.c b/regression/cbmc/slice15/main.c new file mode 100644 index 00000000000..0572b279999 --- /dev/null +++ b/regression/cbmc/slice15/main.c @@ -0,0 +1,24 @@ +int nondet_int(); + +double d = 0.0; + +void f1() +{ + d = 1.0; +} + +int main() +{ + int x = 2; + + if(nondet_int()) + x = 4; + + (void) f1(); + + d += (x == 2); + + d += (x > 3); + + assert(d == 2.0); +} diff --git a/regression/cbmc/slice15/test.desc b/regression/cbmc/slice15/test.desc new file mode 100644 index 00000000000..8e6dafcc8e6 --- /dev/null +++ b/regression/cbmc/slice15/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--fixedbv --full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice16/main.c b/regression/cbmc/slice16/main.c new file mode 100644 index 00000000000..99d0cda2c16 --- /dev/null +++ b/regression/cbmc/slice16/main.c @@ -0,0 +1,48 @@ +/* running example extracted from +"In Slicing Programs with Jump Statements" +by Hiralal Afrawal */ +#include +int x; +_Bool nondet_bool(); +unsigned int nondet_uint(); + +_Bool leof() { + return nondet_bool(); +} + +int f1(int x) { + return x*1; +} + +int f2(int x) { + return x*2; +} + +int f3(int x) { + return x*3; +} + +void read(int *x) { + x = nondet_uint(); +} + +int main() { + int sum=0; + int positives=0; + while(leof()) + { + read(x); + if (x <= 0) + sum = sum + f1(x); + else + { + positives = positives + 1; + if (x%2 == 0) + sum = sum + f2(x); + else + sum = sum + f3(x); + } + } + assert(sum>=0); + assert(positives>=0); +} diff --git a/regression/cbmc/slice16/test.desc b/regression/cbmc/slice16/test.desc new file mode 100644 index 00000000000..0f63776547f --- /dev/null +++ b/regression/cbmc/slice16/test.desc @@ -0,0 +1,8 @@ +CORE +main.c +--full-slice --unwind 2 +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice17/main.c b/regression/cbmc/slice17/main.c new file mode 100644 index 00000000000..ccc03df0596 --- /dev/null +++ b/regression/cbmc/slice17/main.c @@ -0,0 +1,35 @@ +#include +#include + +union u +{ + uint32_t x; + int32_t y; + int8_t z[4]; +}; + +union u pass_through_union (uint32_t q) +{ + union u un; + + un.z[0] = 0x0; + un.y = q; + un.z[3] = 0x0; + un.z[0] = 0x0; + + return un; +} + +int main (void) +{ + uint32_t q; + + __CPROVER_assume((q & q - 1) == 0); + __CPROVER_assume(256 <= q && q <= (1 << 23)); + + union u un = pass_through_union(q); + + assert(q == un.y); + + return 1; +} diff --git a/regression/cbmc/slice17/test.desc b/regression/cbmc/slice17/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/slice17/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/cbmc/slice18/main.c b/regression/cbmc/slice18/main.c new file mode 100644 index 00000000000..0661315487b --- /dev/null +++ b/regression/cbmc/slice18/main.c @@ -0,0 +1,11 @@ +void exit(int status); + +int main() { + int x; + + if(x==10) + exit(1); + + if(x==10) + assert(0); +} diff --git a/regression/cbmc/slice18/test.desc b/regression/cbmc/slice18/test.desc new file mode 100644 index 00000000000..9efefbc7362 --- /dev/null +++ b/regression/cbmc/slice18/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring From bbe8fcc0d2d4a30337d457b3c8f9c097f34f8398 Mon Sep 17 00:00:00 2001 From: Lucas Cordeiro Date: Mon, 6 Feb 2017 16:01:08 +0000 Subject: [PATCH 164/166] moved full-slice test cases from cbmc to goto-instrument Signed-off-by: Lucas Cordeiro --- .../{cbmc => goto-instrument}/slice01/main.c | 0 .../slice01/test.desc | 2 +- .../{cbmc => goto-instrument}/slice02/main.c | 0 .../slice02/test.desc | 0 .../{cbmc => goto-instrument}/slice03/main.c | 0 .../slice03/test.desc | 0 .../{cbmc => goto-instrument}/slice04/main.c | 0 .../slice04}/test.desc | 0 .../{cbmc => goto-instrument}/slice05/main.c | 0 .../slice05}/test.desc | 0 .../{cbmc => goto-instrument}/slice06/main.c | 0 .../slice06}/test.desc | 0 .../{cbmc => goto-instrument}/slice07/main.c | 0 .../slice07/test.desc | 2 +- .../{cbmc => goto-instrument}/slice08/main.c | 0 .../slice08/test.desc | 0 .../{cbmc => goto-instrument}/slice09/main.c | 0 .../slice09}/test.desc | 0 .../{cbmc => goto-instrument}/slice10/main.c | 0 .../slice10}/test.desc | 0 .../{cbmc => goto-instrument}/slice11/main.c | 0 .../slice11}/test.desc | 0 .../{cbmc => goto-instrument}/slice12/main.c | 0 .../slice12}/test.desc | 2 +- .../{cbmc => goto-instrument}/slice13/main.c | 0 .../slice13}/test.desc | 2 +- .../{cbmc => goto-instrument}/slice14/main.c | 0 .../slice14/test.desc | 2 +- .../{cbmc => goto-instrument}/slice15/main.c | 0 .../slice15}/test.desc | 2 +- .../{cbmc => goto-instrument}/slice16/main.c | 0 .../slice16/test.desc | 0 .../{cbmc => goto-instrument}/slice17/main.c | 0 .../slice17}/test.desc | 4 +- .../{cbmc => goto-instrument}/slice18/main.c | 0 .../slice18}/test.desc | 4 +- regression/goto-instrument/slice19/main.c | 45 +++++++++++++++++++ regression/goto-instrument/slice19/test.desc | 8 ++++ regression/goto-instrument/slice20/main.c | 29 ++++++++++++ regression/goto-instrument/slice20/test.desc | 8 ++++ regression/goto-instrument/slice21/main.c | 35 +++++++++++++++ regression/goto-instrument/slice21/test.desc | 8 ++++ 42 files changed, 143 insertions(+), 10 deletions(-) rename regression/{cbmc => goto-instrument}/slice01/main.c (100%) rename regression/{cbmc => goto-instrument}/slice01/test.desc (91%) rename regression/{cbmc => goto-instrument}/slice02/main.c (100%) rename regression/{cbmc => goto-instrument}/slice02/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice03/main.c (100%) rename regression/{cbmc => goto-instrument}/slice03/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice04/main.c (100%) rename regression/{cbmc/slice05 => goto-instrument/slice04}/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice05/main.c (100%) rename regression/{cbmc/slice06 => goto-instrument/slice05}/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice06/main.c (100%) rename regression/{cbmc/slice09 => goto-instrument/slice06}/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice07/main.c (100%) rename regression/{cbmc => goto-instrument}/slice07/test.desc (92%) rename regression/{cbmc => goto-instrument}/slice08/main.c (100%) rename regression/{cbmc => goto-instrument}/slice08/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice09/main.c (100%) rename regression/{cbmc/slice10 => goto-instrument/slice09}/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice10/main.c (100%) rename regression/{cbmc/slice11 => goto-instrument/slice10}/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice11/main.c (100%) rename regression/{cbmc/slice12 => goto-instrument/slice11}/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice12/main.c (100%) rename regression/{cbmc/slice17 => goto-instrument/slice12}/test.desc (86%) rename regression/{cbmc => goto-instrument}/slice13/main.c (100%) rename regression/{cbmc/slice04 => goto-instrument/slice13}/test.desc (91%) rename regression/{cbmc => goto-instrument}/slice14/main.c (100%) rename regression/{cbmc => goto-instrument}/slice14/test.desc (91%) rename regression/{cbmc => goto-instrument}/slice15/main.c (100%) rename regression/{cbmc/slice18 => goto-instrument/slice15}/test.desc (86%) rename regression/{cbmc => goto-instrument}/slice16/main.c (100%) rename regression/{cbmc => goto-instrument}/slice16/test.desc (100%) rename regression/{cbmc => goto-instrument}/slice17/main.c (100%) rename regression/{cbmc/slice15 => goto-instrument/slice17}/test.desc (72%) rename regression/{cbmc => goto-instrument}/slice18/main.c (100%) rename regression/{cbmc/slice13 => goto-instrument/slice18}/test.desc (72%) create mode 100644 regression/goto-instrument/slice19/main.c create mode 100644 regression/goto-instrument/slice19/test.desc create mode 100644 regression/goto-instrument/slice20/main.c create mode 100644 regression/goto-instrument/slice20/test.desc create mode 100644 regression/goto-instrument/slice21/main.c create mode 100644 regression/goto-instrument/slice21/test.desc diff --git a/regression/cbmc/slice01/main.c b/regression/goto-instrument/slice01/main.c similarity index 100% rename from regression/cbmc/slice01/main.c rename to regression/goto-instrument/slice01/main.c diff --git a/regression/cbmc/slice01/test.desc b/regression/goto-instrument/slice01/test.desc similarity index 91% rename from regression/cbmc/slice01/test.desc rename to regression/goto-instrument/slice01/test.desc index 6f19f2d9ef6..76cbcfa81bd 100644 --- a/regression/cbmc/slice01/test.desc +++ b/regression/goto-instrument/slice01/test.desc @@ -1,4 +1,4 @@ -CORE +KNOWNBUG main.c --unwind 2 --full-slice ^EXIT=0$ diff --git a/regression/cbmc/slice02/main.c b/regression/goto-instrument/slice02/main.c similarity index 100% rename from regression/cbmc/slice02/main.c rename to regression/goto-instrument/slice02/main.c diff --git a/regression/cbmc/slice02/test.desc b/regression/goto-instrument/slice02/test.desc similarity index 100% rename from regression/cbmc/slice02/test.desc rename to regression/goto-instrument/slice02/test.desc diff --git a/regression/cbmc/slice03/main.c b/regression/goto-instrument/slice03/main.c similarity index 100% rename from regression/cbmc/slice03/main.c rename to regression/goto-instrument/slice03/main.c diff --git a/regression/cbmc/slice03/test.desc b/regression/goto-instrument/slice03/test.desc similarity index 100% rename from regression/cbmc/slice03/test.desc rename to regression/goto-instrument/slice03/test.desc diff --git a/regression/cbmc/slice04/main.c b/regression/goto-instrument/slice04/main.c similarity index 100% rename from regression/cbmc/slice04/main.c rename to regression/goto-instrument/slice04/main.c diff --git a/regression/cbmc/slice05/test.desc b/regression/goto-instrument/slice04/test.desc similarity index 100% rename from regression/cbmc/slice05/test.desc rename to regression/goto-instrument/slice04/test.desc diff --git a/regression/cbmc/slice05/main.c b/regression/goto-instrument/slice05/main.c similarity index 100% rename from regression/cbmc/slice05/main.c rename to regression/goto-instrument/slice05/main.c diff --git a/regression/cbmc/slice06/test.desc b/regression/goto-instrument/slice05/test.desc similarity index 100% rename from regression/cbmc/slice06/test.desc rename to regression/goto-instrument/slice05/test.desc diff --git a/regression/cbmc/slice06/main.c b/regression/goto-instrument/slice06/main.c similarity index 100% rename from regression/cbmc/slice06/main.c rename to regression/goto-instrument/slice06/main.c diff --git a/regression/cbmc/slice09/test.desc b/regression/goto-instrument/slice06/test.desc similarity index 100% rename from regression/cbmc/slice09/test.desc rename to regression/goto-instrument/slice06/test.desc diff --git a/regression/cbmc/slice07/main.c b/regression/goto-instrument/slice07/main.c similarity index 100% rename from regression/cbmc/slice07/main.c rename to regression/goto-instrument/slice07/main.c diff --git a/regression/cbmc/slice07/test.desc b/regression/goto-instrument/slice07/test.desc similarity index 92% rename from regression/cbmc/slice07/test.desc rename to regression/goto-instrument/slice07/test.desc index 7d88efc76ad..f40f8bd1c64 100644 --- a/regression/cbmc/slice07/test.desc +++ b/regression/goto-instrument/slice07/test.desc @@ -1,4 +1,4 @@ -CORE +KNOWNBUG main.c --full-slice ^EXIT=6$ diff --git a/regression/cbmc/slice08/main.c b/regression/goto-instrument/slice08/main.c similarity index 100% rename from regression/cbmc/slice08/main.c rename to regression/goto-instrument/slice08/main.c diff --git a/regression/cbmc/slice08/test.desc b/regression/goto-instrument/slice08/test.desc similarity index 100% rename from regression/cbmc/slice08/test.desc rename to regression/goto-instrument/slice08/test.desc diff --git a/regression/cbmc/slice09/main.c b/regression/goto-instrument/slice09/main.c similarity index 100% rename from regression/cbmc/slice09/main.c rename to regression/goto-instrument/slice09/main.c diff --git a/regression/cbmc/slice10/test.desc b/regression/goto-instrument/slice09/test.desc similarity index 100% rename from regression/cbmc/slice10/test.desc rename to regression/goto-instrument/slice09/test.desc diff --git a/regression/cbmc/slice10/main.c b/regression/goto-instrument/slice10/main.c similarity index 100% rename from regression/cbmc/slice10/main.c rename to regression/goto-instrument/slice10/main.c diff --git a/regression/cbmc/slice11/test.desc b/regression/goto-instrument/slice10/test.desc similarity index 100% rename from regression/cbmc/slice11/test.desc rename to regression/goto-instrument/slice10/test.desc diff --git a/regression/cbmc/slice11/main.c b/regression/goto-instrument/slice11/main.c similarity index 100% rename from regression/cbmc/slice11/main.c rename to regression/goto-instrument/slice11/main.c diff --git a/regression/cbmc/slice12/test.desc b/regression/goto-instrument/slice11/test.desc similarity index 100% rename from regression/cbmc/slice12/test.desc rename to regression/goto-instrument/slice11/test.desc diff --git a/regression/cbmc/slice12/main.c b/regression/goto-instrument/slice12/main.c similarity index 100% rename from regression/cbmc/slice12/main.c rename to regression/goto-instrument/slice12/main.c diff --git a/regression/cbmc/slice17/test.desc b/regression/goto-instrument/slice12/test.desc similarity index 86% rename from regression/cbmc/slice17/test.desc rename to regression/goto-instrument/slice12/test.desc index 9efefbc7362..3793f7374e1 100644 --- a/regression/cbmc/slice17/test.desc +++ b/regression/goto-instrument/slice12/test.desc @@ -1,6 +1,6 @@ CORE main.c - +--full-slice ^EXIT=0$ ^SIGNAL=0$ ^VERIFICATION SUCCESSFUL$ diff --git a/regression/cbmc/slice13/main.c b/regression/goto-instrument/slice13/main.c similarity index 100% rename from regression/cbmc/slice13/main.c rename to regression/goto-instrument/slice13/main.c diff --git a/regression/cbmc/slice04/test.desc b/regression/goto-instrument/slice13/test.desc similarity index 91% rename from regression/cbmc/slice04/test.desc rename to regression/goto-instrument/slice13/test.desc index 4d8899e64c7..cc8dd41ed5f 100644 --- a/regression/cbmc/slice04/test.desc +++ b/regression/goto-instrument/slice13/test.desc @@ -1,4 +1,4 @@ -CORE +KNOWNBUG main.c --floatbv --full-slice ^EXIT=0$ diff --git a/regression/cbmc/slice14/main.c b/regression/goto-instrument/slice14/main.c similarity index 100% rename from regression/cbmc/slice14/main.c rename to regression/goto-instrument/slice14/main.c diff --git a/regression/cbmc/slice14/test.desc b/regression/goto-instrument/slice14/test.desc similarity index 91% rename from regression/cbmc/slice14/test.desc rename to regression/goto-instrument/slice14/test.desc index a2b36885fc7..ef912633761 100644 --- a/regression/cbmc/slice14/test.desc +++ b/regression/goto-instrument/slice14/test.desc @@ -1,4 +1,4 @@ -CORE +KNOWNBUG main.c --pointer-check --full-slice ^EXIT=10$ diff --git a/regression/cbmc/slice15/main.c b/regression/goto-instrument/slice15/main.c similarity index 100% rename from regression/cbmc/slice15/main.c rename to regression/goto-instrument/slice15/main.c diff --git a/regression/cbmc/slice18/test.desc b/regression/goto-instrument/slice15/test.desc similarity index 86% rename from regression/cbmc/slice18/test.desc rename to regression/goto-instrument/slice15/test.desc index 9efefbc7362..3793f7374e1 100644 --- a/regression/cbmc/slice18/test.desc +++ b/regression/goto-instrument/slice15/test.desc @@ -1,6 +1,6 @@ CORE main.c - +--full-slice ^EXIT=0$ ^SIGNAL=0$ ^VERIFICATION SUCCESSFUL$ diff --git a/regression/cbmc/slice16/main.c b/regression/goto-instrument/slice16/main.c similarity index 100% rename from regression/cbmc/slice16/main.c rename to regression/goto-instrument/slice16/main.c diff --git a/regression/cbmc/slice16/test.desc b/regression/goto-instrument/slice16/test.desc similarity index 100% rename from regression/cbmc/slice16/test.desc rename to regression/goto-instrument/slice16/test.desc diff --git a/regression/cbmc/slice17/main.c b/regression/goto-instrument/slice17/main.c similarity index 100% rename from regression/cbmc/slice17/main.c rename to regression/goto-instrument/slice17/main.c diff --git a/regression/cbmc/slice15/test.desc b/regression/goto-instrument/slice17/test.desc similarity index 72% rename from regression/cbmc/slice15/test.desc rename to regression/goto-instrument/slice17/test.desc index 8e6dafcc8e6..03cff4a4fac 100644 --- a/regression/cbmc/slice15/test.desc +++ b/regression/goto-instrument/slice17/test.desc @@ -1,6 +1,6 @@ -CORE +KNOWNBUG main.c ---fixedbv --full-slice +--full-slice ^EXIT=0$ ^SIGNAL=0$ ^VERIFICATION SUCCESSFUL$ diff --git a/regression/cbmc/slice18/main.c b/regression/goto-instrument/slice18/main.c similarity index 100% rename from regression/cbmc/slice18/main.c rename to regression/goto-instrument/slice18/main.c diff --git a/regression/cbmc/slice13/test.desc b/regression/goto-instrument/slice18/test.desc similarity index 72% rename from regression/cbmc/slice13/test.desc rename to regression/goto-instrument/slice18/test.desc index 4d8899e64c7..03cff4a4fac 100644 --- a/regression/cbmc/slice13/test.desc +++ b/regression/goto-instrument/slice18/test.desc @@ -1,6 +1,6 @@ -CORE +KNOWNBUG main.c ---floatbv --full-slice +--full-slice ^EXIT=0$ ^SIGNAL=0$ ^VERIFICATION SUCCESSFUL$ diff --git a/regression/goto-instrument/slice19/main.c b/regression/goto-instrument/slice19/main.c new file mode 100644 index 00000000000..ecd39ff0d4c --- /dev/null +++ b/regression/goto-instrument/slice19/main.c @@ -0,0 +1,45 @@ +#include +#include +#include + +void sort_items_by_criteria( int * item, int left, int right ) +{ + int lidx = left, ridx = (left+right)/2 + 1, lsize = (left+right)/2 - left + 1; + int tmp; + + if ( right - left < 1 ) return; + sort_items_by_criteria( item, left, (left+right)/2 ); + sort_items_by_criteria( item, (left+right)/2 + 1, right ); + + while ( ridx <= right && lidx < ridx ) { + if ( item[lidx] > item[ridx] ) { + tmp = item[ridx]; + memmove( item + lidx + 1, item + lidx, lsize * sizeof(int) ); + item[lidx] = tmp; + ++ridx; + ++lsize; + } + ++lidx; + --lsize; + } +} + +int main(int argc, char * argv[]) { + int a[7]; + + //CBMC reports wrong results for 256, -2147221455, -2147221455, -2147221455, 16, -2147483600, 16384 + a[0] = 256; + a[1] = -2147221455; + a[2] = -2147221455; + a[3] = -2147221455; + a[4] = 16; + a[5] = -2147483600; + a[6] = 16384; + + sort_items_by_criteria(a, 0, 6); + + printf("%d %d %d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6]); + + assert(a[0]==-2147483600); + return 0; +} diff --git a/regression/goto-instrument/slice19/test.desc b/regression/goto-instrument/slice19/test.desc new file mode 100644 index 00000000000..03cff4a4fac --- /dev/null +++ b/regression/goto-instrument/slice19/test.desc @@ -0,0 +1,8 @@ +KNOWNBUG +main.c +--full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/goto-instrument/slice20/main.c b/regression/goto-instrument/slice20/main.c new file mode 100644 index 00000000000..6a9f339e7e0 --- /dev/null +++ b/regression/goto-instrument/slice20/main.c @@ -0,0 +1,29 @@ +#include + +void recursion(_Bool rec, int *p) +{ + int some_local, other_local; + + if(rec) + { + some_local=2; + other_local=30; + rec=1; + *p=20; // overwrites other_local in previous frame + assert(other_local==30); + } + else + { + some_local=1; + other_local=10; + recursion(1, &other_local); + assert(!rec); + assert(some_local==1); + assert(other_local==20); + } +} + +int main() +{ + recursion(0, 0); +} diff --git a/regression/goto-instrument/slice20/test.desc b/regression/goto-instrument/slice20/test.desc new file mode 100644 index 00000000000..03cff4a4fac --- /dev/null +++ b/regression/goto-instrument/slice20/test.desc @@ -0,0 +1,8 @@ +KNOWNBUG +main.c +--full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring diff --git a/regression/goto-instrument/slice21/main.c b/regression/goto-instrument/slice21/main.c new file mode 100644 index 00000000000..ccc03df0596 --- /dev/null +++ b/regression/goto-instrument/slice21/main.c @@ -0,0 +1,35 @@ +#include +#include + +union u +{ + uint32_t x; + int32_t y; + int8_t z[4]; +}; + +union u pass_through_union (uint32_t q) +{ + union u un; + + un.z[0] = 0x0; + un.y = q; + un.z[3] = 0x0; + un.z[0] = 0x0; + + return un; +} + +int main (void) +{ + uint32_t q; + + __CPROVER_assume((q & q - 1) == 0); + __CPROVER_assume(256 <= q && q <= (1 << 23)); + + union u un = pass_through_union(q); + + assert(q == un.y); + + return 1; +} diff --git a/regression/goto-instrument/slice21/test.desc b/regression/goto-instrument/slice21/test.desc new file mode 100644 index 00000000000..03cff4a4fac --- /dev/null +++ b/regression/goto-instrument/slice21/test.desc @@ -0,0 +1,8 @@ +KNOWNBUG +main.c +--full-slice +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +^warning: ignoring From db88e7abd4548031aae084024787eb257d89f2ce Mon Sep 17 00:00:00 2001 From: Daniel Poetzl Date: Tue, 7 Feb 2017 19:07:38 +0000 Subject: [PATCH 165/166] Fix adjustment of goto targets in the loop unwinder --- .../unwind-zero-unwind3/main.c | 9 ++++++ .../unwind-zero-unwind3/test.desc | 9 ++++++ src/goto-instrument/unwind.cpp | 29 +++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 regression/goto-instrument/unwind-zero-unwind3/main.c create mode 100644 regression/goto-instrument/unwind-zero-unwind3/test.desc diff --git a/regression/goto-instrument/unwind-zero-unwind3/main.c b/regression/goto-instrument/unwind-zero-unwind3/main.c new file mode 100644 index 00000000000..afead274440 --- /dev/null +++ b/regression/goto-instrument/unwind-zero-unwind3/main.c @@ -0,0 +1,9 @@ + +int main() +{ + do { + + } while (0); + + return 0; +} diff --git a/regression/goto-instrument/unwind-zero-unwind3/test.desc b/regression/goto-instrument/unwind-zero-unwind3/test.desc new file mode 100644 index 00000000000..94ddc4f8e82 --- /dev/null +++ b/regression/goto-instrument/unwind-zero-unwind3/test.desc @@ -0,0 +1,9 @@ +CORE +main.c +--unwind 0 +^EXIT=0$ +^SIGNAL=0$ +^VERIFICATION SUCCESSFUL$ +-- +ASSUME FALSE +^warning: ignoring diff --git a/src/goto-instrument/unwind.cpp b/src/goto-instrument/unwind.cpp index 53fc3d409e1..b6ae3e79555 100644 --- a/src/goto-instrument/unwind.cpp +++ b/src/goto-instrument/unwind.cpp @@ -7,6 +7,12 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ +//#define DEBUG + +#ifdef DEBUG +#include +#endif + #include #include #include @@ -312,7 +318,7 @@ void goto_unwindt::unwind( goto_programt::const_targett t=i_it->get_target(); - if(t->location_number>=loop_head->location_number || + if(t->location_number>=loop_head->location_number && t->location_numberlocation_number) { i_it->set_target(t_skip); @@ -385,10 +391,21 @@ void goto_unwindt::unwind( { assert(k>=-1); - forall_goto_program_instructions(i_it, goto_program) + for(goto_programt::const_targett i_it=goto_program.instructions.begin(); + i_it!=goto_program.instructions.end();) { +#ifdef DEBUG + symbol_tablet st; + namespacet ns(st); + std::cout << "Instruction:\n"; + goto_program.output_instruction(ns, "", std::cout, i_it); +#endif + if(!i_it->is_backwards_goto()) + { + i_it++; continue; + } const irep_idt func=i_it->function; assert(!func.empty()); @@ -398,7 +415,10 @@ void goto_unwindt::unwind( int final_k=get_k(func, loop_number, k, unwind_set); if(final_k==-1) + { + i_it++; continue; + } goto_programt::const_targett loop_head=i_it->get_target(); goto_programt::const_targett loop_exit=i_it; @@ -409,7 +429,6 @@ void goto_unwindt::unwind( // necessary as we change the goto program in the previous line i_it=loop_exit; - i_it--; // as for loop first increments } } @@ -440,6 +459,10 @@ void goto_unwindt::operator()( if(!goto_function.body_available()) continue; +#ifdef DEBUG + std::cout << "Function: " << it->first << std::endl; +#endif + goto_programt &goto_program=goto_function.body; unwind(goto_program, unwind_set, k, unwind_strategy); From adcd342b71c2531026d86a04df3ad88978211af6 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Sun, 22 Jan 2017 16:22:27 +0000 Subject: [PATCH 166/166] gcc style error messages for goto-cc --- src/goto-cc/armcc_mode.cpp | 4 +- src/goto-cc/armcc_mode.h | 9 +- src/goto-cc/as_mode.cpp | 5 +- src/goto-cc/as_mode.h | 3 +- src/goto-cc/cw_mode.cpp | 4 +- src/goto-cc/cw_mode.h | 5 +- src/goto-cc/gcc_mode.cpp | 6 +- src/goto-cc/gcc_mode.h | 8 +- src/goto-cc/goto_cc_mode.cpp | 10 +- src/goto-cc/goto_cc_mode.h | 10 +- src/goto-cc/ld_mode.cpp | 331 +++++++++++++++++++++++++++++++++++ src/goto-cc/ld_mode.h | 42 +++++ src/goto-cc/ms_cl_mode.cpp | 4 +- src/goto-cc/ms_cl_mode.h | 5 +- src/util/cout_message.cpp | 65 +++++++ src/util/cout_message.h | 27 ++- 16 files changed, 506 insertions(+), 32 deletions(-) create mode 100644 src/goto-cc/ld_mode.cpp create mode 100644 src/goto-cc/ld_mode.h diff --git a/src/goto-cc/armcc_mode.cpp b/src/goto-cc/armcc_mode.cpp index fbe8db16d94..f4a57655582 100644 --- a/src/goto-cc/armcc_mode.cpp +++ b/src/goto-cc/armcc_mode.cpp @@ -59,8 +59,8 @@ int armcc_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2int(cmdline.get_value("verbosity")); - compiler.ui_message_handler.set_verbosity(verbosity); - ui_message_handler.set_verbosity(verbosity); + compiler.set_message_handler(get_message_handler()); + message_handler.set_verbosity(verbosity); debug() << "ARM mode" << eom; diff --git a/src/goto-cc/armcc_mode.h b/src/goto-cc/armcc_mode.h index bf1481c8141..cbbe90a2a1e 100644 --- a/src/goto-cc/armcc_mode.h +++ b/src/goto-cc/armcc_mode.h @@ -11,25 +11,28 @@ Date: June 2006 #ifndef CPROVER_GOTO_CC_ARMCC_MODE_H #define CPROVER_GOTO_CC_ARMCC_MODE_H +#include + #include "goto_cc_mode.h" #include "armcc_cmdline.h" class armcc_modet:public goto_cc_modet { public: - virtual int doit(); - virtual void help_mode(); + int doit() final; + void help_mode() final; armcc_modet( armcc_cmdlinet &_armcc_cmdline, const std::string &_base_name): - goto_cc_modet(_armcc_cmdline, _base_name), + goto_cc_modet(_armcc_cmdline, _base_name, message_handler), cmdline(_armcc_cmdline) { } protected: armcc_cmdlinet &cmdline; + gcc_message_handlert message_handler; }; #endif // CPROVER_GOTO_CC_ARMCC_MODE_H diff --git a/src/goto-cc/as_mode.cpp b/src/goto-cc/as_mode.cpp index 75d02f2903f..bb87b6c6abb 100644 --- a/src/goto-cc/as_mode.cpp +++ b/src/goto-cc/as_mode.cpp @@ -22,6 +22,7 @@ Author: Michael Tautschnig #include #include #include +#include #include @@ -79,7 +80,7 @@ as_modet::as_modet( goto_cc_cmdlinet &_cmdline, const std::string &_base_name, bool _produce_hybrid_binary): - goto_cc_modet(_cmdline, _base_name), + goto_cc_modet(_cmdline, _base_name, message_handler), produce_hybrid_binary(_produce_hybrid_binary), native_tool_name(assembler_name(cmdline, base_name)) { @@ -137,7 +138,7 @@ int as_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2unsigned(cmdline.get_value("verbosity")); - ui_message_handler.set_verbosity(verbosity); + message_handler.set_verbosity(verbosity); if(act_as_as86) { diff --git a/src/goto-cc/as_mode.h b/src/goto-cc/as_mode.h index 8b44800420e..8dfc9bb8b05 100644 --- a/src/goto-cc/as_mode.h +++ b/src/goto-cc/as_mode.h @@ -22,11 +22,12 @@ class as_modet:public goto_cc_modet as_modet( goto_cc_cmdlinet &_cmdline, const std::string &_base_name, - bool _produce_hybrid_binar); + bool _produce_hybrid_binary); protected: bool produce_hybrid_binary; const std::string native_tool_name; + gcc_message_handlert message_handler; int run_as(); // call as with original command line diff --git a/src/goto-cc/cw_mode.cpp b/src/goto-cc/cw_mode.cpp index a3a085d843c..510f7c9c0aa 100644 --- a/src/goto-cc/cw_mode.cpp +++ b/src/goto-cc/cw_mode.cpp @@ -59,8 +59,8 @@ int cw_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2unsigned(cmdline.get_value("verbosity")); - compiler.ui_message_handler.set_verbosity(verbosity); - ui_message_handler.set_verbosity(verbosity); + compiler.set_message_handler(get_message_handler()); + message_handler.set_verbosity(verbosity); debug() << "CodeWarrior mode" << eom; diff --git a/src/goto-cc/cw_mode.h b/src/goto-cc/cw_mode.h index e81469e9460..865b1f7ea15 100644 --- a/src/goto-cc/cw_mode.h +++ b/src/goto-cc/cw_mode.h @@ -11,6 +11,8 @@ Date: June 2006 #ifndef CPROVER_GOTO_CC_CW_MODE_H #define CPROVER_GOTO_CC_CW_MODE_H +#include + #include "goto_cc_mode.h" #include "gcc_cmdline.h" @@ -21,13 +23,14 @@ class cw_modet:public goto_cc_modet virtual void help_mode(); cw_modet(gcc_cmdlinet &_gcc_cmdline, const std::string &_base_name): - goto_cc_modet(_gcc_cmdline, _base_name), + goto_cc_modet(_gcc_cmdline, _base_name, message_handler), cmdline(_gcc_cmdline) { } protected: gcc_cmdlinet &cmdline; + console_message_handlert message_handler; }; #endif // CPROVER_GOTO_CC_CW_MODE_H diff --git a/src/goto-cc/gcc_mode.cpp b/src/goto-cc/gcc_mode.cpp index 1762a4bc6a2..d56b2c3c351 100644 --- a/src/goto-cc/gcc_mode.cpp +++ b/src/goto-cc/gcc_mode.cpp @@ -121,7 +121,7 @@ gcc_modet::gcc_modet( goto_cc_cmdlinet &_cmdline, const std::string &_base_name, bool _produce_hybrid_binary): - goto_cc_modet(_cmdline, _base_name), + goto_cc_modet(_cmdline, _base_name, gcc_message_handler), produce_hybrid_binary(_produce_hybrid_binary), act_as_ld(base_name=="ld" || base_name.find("goto-ld")!=std::string::npos) @@ -223,7 +223,7 @@ int gcc_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2unsigned(cmdline.get_value("verbosity")); - ui_message_handler.set_verbosity(verbosity); + gcc_message_handler.set_verbosity(verbosity); if(act_as_ld) { @@ -303,7 +303,7 @@ int gcc_modet::doit() // determine actions to be undertaken compilet compiler(cmdline); - compiler.ui_message_handler.set_verbosity(verbosity); + compiler.set_message_handler(get_message_handler()); if(act_as_ld) compiler.mode=compilet::LINK_LIBRARY; diff --git a/src/goto-cc/gcc_mode.h b/src/goto-cc/gcc_mode.h index 669c140a45e..3b15ba2d36b 100644 --- a/src/goto-cc/gcc_mode.h +++ b/src/goto-cc/gcc_mode.h @@ -11,13 +11,15 @@ Date: June 2006 #ifndef CPROVER_GOTO_CC_GCC_MODE_H #define CPROVER_GOTO_CC_GCC_MODE_H +#include + #include "goto_cc_mode.h" class gcc_modet:public goto_cc_modet { public: - virtual int doit(); - virtual void help_mode(); + int doit() final; + void help_mode() final; gcc_modet( goto_cc_cmdlinet &_cmdline, @@ -29,6 +31,8 @@ class gcc_modet:public goto_cc_modet const bool act_as_ld; std::string native_tool_name; + + gcc_message_handlert gcc_message_handler; int preprocess( const std::string &language, diff --git a/src/goto-cc/goto_cc_mode.cpp b/src/goto-cc/goto_cc_mode.cpp index a58597e7b9b..225a703e838 100644 --- a/src/goto-cc/goto_cc_mode.cpp +++ b/src/goto-cc/goto_cc_mode.cpp @@ -35,11 +35,11 @@ Function: goto_cc_modet::goto_cc_modet goto_cc_modet::goto_cc_modet( goto_cc_cmdlinet &_cmdline, - const std::string &_base_name): - language_uit(_cmdline, ui_message_handler), - ui_message_handler(_cmdline, "goto-cc " CBMC_VERSION), - base_name(_base_name), - cmdline(_cmdline) + const std::string &_base_name, + message_handlert &_message_handler): + messaget(_message_handler), + cmdline(_cmdline), + base_name(_base_name) { register_languages(); } diff --git a/src/goto-cc/goto_cc_mode.h b/src/goto-cc/goto_cc_mode.h index 848e7e4370f..ddb0daed7a0 100644 --- a/src/goto-cc/goto_cc_mode.h +++ b/src/goto-cc/goto_cc_mode.h @@ -15,7 +15,7 @@ Date: June 2006 #include "goto_cc_cmdline.h" -class goto_cc_modet:public language_uit +class goto_cc_modet:public messaget { public: virtual int main(int argc, const char **argv); @@ -25,15 +25,15 @@ class goto_cc_modet:public language_uit virtual void usage_error(); goto_cc_modet( - goto_cc_cmdlinet &_cmdline, - const std::string &_base_name); + goto_cc_cmdlinet &, + const std::string &_base_name, + message_handlert &); ~goto_cc_modet(); protected: - ui_message_handlert ui_message_handler; - const std::string base_name; void register_languages(); goto_cc_cmdlinet &cmdline; + const std::string base_name; }; #endif // CPROVER_GOTO_CC_GOTO_CC_MODE_H diff --git a/src/goto-cc/ld_mode.cpp b/src/goto-cc/ld_mode.cpp new file mode 100644 index 00000000000..134c7aa4f26 --- /dev/null +++ b/src/goto-cc/ld_mode.cpp @@ -0,0 +1,331 @@ +/*******************************************************************\ + +Module: LD Mode + +Author: Daniel Kroening, 2013 + +\*******************************************************************/ + +#ifdef _WIN32 +#define EX_OK 0 +#define EX_USAGE 64 +#define EX_SOFTWARE 70 +#else +#include +#endif + +#include + +#include +#include + +#include + +#include "compile.h" +#include "ld_mode.h" + +/*******************************************************************\ + +Function: ld_modet::doit + + Inputs: + + Outputs: + + Purpose: does it. + +\*******************************************************************/ + +int ld_modet::doit() +{ + if(cmdline.isset("help")) + { + help(); + return EX_OK; + } + + unsigned int verbosity=1; + + compilet compiler(cmdline); + + if(cmdline.isset('v') || cmdline.isset('V')) + { + // This a) prints the version and b) increases verbosity. + // Linking continues, don't exit! + + std::cout << "GNU ld version 2.16.91 20050610 (goto-cc " CBMC_VERSION ")\n"; + + // 'V' should also print some supported "emulations". + } + + if(cmdline.isset("version")) + { + std::cout << "GNU ld version 2.16.91 20050610 (goto-cc " CBMC_VERSION ")\n"; + std::cout << "Copyright (C) 2006-2014 Daniel Kroening, Christoph Wintersteiger\n"; + return EX_OK; // Exit! + } + + if(cmdline.isset("verbosity")) + verbosity=unsafe_string2int(cmdline.get_value("verbosity")); + + compiler.set_message_handler(get_message_handler()); + message_handler.set_verbosity(verbosity); + + if(produce_hybrid_binary) + debug() << "LD mode (hybrid)" << eom; + else + debug() << "LD mode" << eom; + + // get configuration + config.set(cmdline); + + // determine actions to be undertaken + compiler.mode=compilet::LINK_LIBRARY; + + compiler.object_file_extension="o"; + + if(cmdline.isset('L')) + compiler.library_paths=cmdline.get_values('L'); + // Don't add the system paths! + + if(cmdline.isset("library-path")) + compiler.library_paths=cmdline.get_values("library-path"); + // Don't add the system paths! + + if(cmdline.isset('l')) + compiler.libraries=cmdline.get_values('l'); + + if(cmdline.isset("library")) + compiler.libraries=cmdline.get_values("library"); + + if(cmdline.isset('o')) + { + // given gcc -o file1 -o file2, + // gcc will output to file2, not file1 + compiler.output_file_object=cmdline.get_values('o').back(); + compiler.output_file_executable=cmdline.get_values('o').back(); + } + else if(cmdline.isset("output")) + { + // given gcc -o file1 -o file2, + // gcc will output to file2, not file1 + compiler.output_file_object=cmdline.get_values("output").back(); + compiler.output_file_executable=cmdline.get_values("output").back(); + } + else + { + // defaults + compiler.output_file_object=""; + compiler.output_file_executable="a.out"; + } + + // do all the rest + if(compiler.doit()) + return 1; // ld uses exit code 1 for all sorts of errors + + #if 0 + if(produce_hybrid_binary) + { + if(gcc_hybrid_binary(original_args)) + result=true; + } + #endif + + return EX_OK; +} + +/*******************************************************************\ + +Function: ld_modet::gcc_hybrid_binary + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +#if 0 +int ld_modet::gcc_hybrid_binary(const cmdlinet::argst &input_files) +{ + if(input_files.empty()) + return 0; + + std::list output_files; + + if(cmdline.isset('c')) + { + if(cmdline.isset('o')) + { + // there should be only one input file + output_files.push_back(cmdline.get_value('o')); + } + else + { + for(cmdlinet::argst::const_iterator + i_it=input_files.begin(); + i_it!=input_files.end(); + i_it++) + { + if(is_supported_source_file(*i_it) && cmdline.isset('c')) + output_files.push_back(get_base_name(*i_it)+".o"); + } + } + } + else + { + // -c is not given + if(cmdline.isset('o')) + output_files.push_back(cmdline.get_value('o')); + else + output_files.push_back("a.out"); + } + + if(output_files.empty()) return 0; + + debug("Running gcc to generate hybrid binary"); + + // save the goto-cc output files + for(std::list::const_iterator + it=output_files.begin(); + it!=output_files.end(); + it++) + { + rename(it->c_str(), (*it+".goto-cc-saved").c_str()); + } + + // build new argv + std::vector new_argv; + + new_argv.reserve(cmdline.parsed_argv.size()); + + bool skip_next=false; + + for(ld_cmdlinet::parsed_argvt::const_iterator + it=cmdline.parsed_argv.begin(); + it!=cmdline.parsed_argv.end(); + it++) + { + if(skip_next) + { + // skip + skip_next=false; + } + else if(it->arg=="--verbosity") + { + // ignore here + skip_next=true; + } + else + new_argv.push_back(it->arg); + } + + // overwrite argv[0] + assert(new_argv.size()>=1); + new_argv[0]="gcc"; + + #if 0 + std::cout << "RUN:"; + for(std::size_t i=0; i::const_iterator + it=output_files.begin(); + it!=output_files.end(); + it++) + { + #ifdef __linux__ + debug("merging "+*it); + + if(!cmdline.isset('c')) + { + // remove any existing goto-cc section + std::vector objcopy_argv; + + objcopy_argv.push_back("objcopy"); + objcopy_argv.push_back("--remove-section=goto-cc"); + objcopy_argv.push_back(*it); + + run(objcopy_argv[0], objcopy_argv); + } + + // now add goto-binary as goto-cc section + std::string saved=*it+".goto-cc-saved"; + + std::vector objcopy_argv; + + objcopy_argv.push_back("objcopy"); + objcopy_argv.push_back("--add-section"); + objcopy_argv.push_back("goto-cc="+saved); + objcopy_argv.push_back(*it); + + run(objcopy_argv[0], objcopy_argv); + + remove(saved.c_str()); + + #elif defined(__APPLE__) + // Mac + + for(std::list::const_iterator + it=output_files.begin(); + it!=output_files.end(); + it++) + { + debug("merging "+*it); + + std::vector lipo_argv; + + // now add goto-binary as hppa7100LC section + std::string saved=*it+".goto-cc-saved"; + + lipo_argv.push_back("lipo"); + lipo_argv.push_back(*it); + lipo_argv.push_back("-create"); + lipo_argv.push_back("-arch"); + lipo_argv.push_back("hppa7100LC"); + lipo_argv.push_back(saved); + lipo_argv.push_back("-output"); + lipo_argv.push_back(*it); + + run(lipo_argv[0], lipo_argv); + + remove(saved.c_str()); + } + + return 0; + + #else + + error() << "binary merging not implemented for this architecture" << eom; + return 1; + + #endif + } + + return result!=0; +} +#endif + +/*******************************************************************\ + +Function: ld_modet::help_mode + + Inputs: + + Outputs: + + Purpose: display command line help + +\*******************************************************************/ + +void ld_modet::help_mode() +{ + std::cout << "goto-ld understands the options of ld plus the following.\n\n"; +} diff --git a/src/goto-cc/ld_mode.h b/src/goto-cc/ld_mode.h new file mode 100644 index 00000000000..1fb112432aa --- /dev/null +++ b/src/goto-cc/ld_mode.h @@ -0,0 +1,42 @@ +/*******************************************************************\ + +Module: Base class for command line interpretation + +Author: CM Wintersteiger + +Date: June 2006 + +\*******************************************************************/ + +#ifndef CPROVER_GOTO_CC_LD_MODE_H +#define CPROVER_GOTO_CC_LD_MODE_H + +#include + +#include "goto_cc_mode.h" +#include "ld_cmdline.h" + +class ld_modet:public goto_cc_modet +{ +public: + int doit() final; + void help_mode() final; + + explicit ld_modet(ld_cmdlinet &_ld_cmdline): + goto_cc_modet(_ld_cmdline, message_handler), + produce_hybrid_binary(false), + cmdline(_ld_cmdline) + { + } + + bool produce_hybrid_binary; + +protected: + ld_cmdlinet &cmdline; + gcc_message_handlert message_handler; + + //int gcc_hybrid_binary(const cmdlinet::argst &input_files); + //static bool is_supported_source_file(const std::string &); +}; + +#endif // CPROVER_GOTO_CC_LD_MODE_H diff --git a/src/goto-cc/ms_cl_mode.cpp b/src/goto-cc/ms_cl_mode.cpp index 73a06455467..86aaf3f0a3d 100644 --- a/src/goto-cc/ms_cl_mode.cpp +++ b/src/goto-cc/ms_cl_mode.cpp @@ -69,8 +69,8 @@ int ms_cl_modet::doit() if(cmdline.isset("verbosity")) verbosity=unsafe_string2unsigned(cmdline.get_value("verbosity")); - compiler.ui_message_handler.set_verbosity(verbosity); - ui_message_handler.set_verbosity(verbosity); + compiler.set_message_handler(get_message_handler()); + message_handler.set_verbosity(verbosity); debug() << "Visual Studio mode" << eom; diff --git a/src/goto-cc/ms_cl_mode.h b/src/goto-cc/ms_cl_mode.h index e1ae2726c64..673c6efed35 100644 --- a/src/goto-cc/ms_cl_mode.h +++ b/src/goto-cc/ms_cl_mode.h @@ -11,6 +11,8 @@ Date: June 2006 #ifndef CPROVER_GOTO_CC_MS_CL_MODE_H #define CPROVER_GOTO_CC_MS_CL_MODE_H +#include + #include "goto_cc_mode.h" #include "ms_cl_cmdline.h" @@ -23,13 +25,14 @@ class ms_cl_modet:public goto_cc_modet ms_cl_modet( ms_cl_cmdlinet &_ms_cl_cmdline, const std::string &_base_name): - goto_cc_modet(_ms_cl_cmdline, _base_name), + goto_cc_modet(_ms_cl_cmdline, _base_name, message_handler), cmdline(_ms_cl_cmdline) { } protected: ms_cl_cmdlinet &cmdline; + console_message_handlert message_handler; }; #endif // CPROVER_GOTO_CC_MS_CL_MODE_H diff --git a/src/util/cout_message.cpp b/src/util/cout_message.cpp index 6b63f8625ad..d4936d5ad53 100644 --- a/src/util/cout_message.cpp +++ b/src/util/cout_message.cpp @@ -135,3 +135,68 @@ void console_message_handlert::print( std::cerr << message << '\n' << std::flush; #endif } + +/*******************************************************************\ + +Function: gcc_message_handlert::print + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void gcc_message_handlert::print( + unsigned level, + const std::string &message, + int sequence_number, + const source_locationt &location) +{ + std::string dest; + + const irep_idt &file=location.get_file(); + const irep_idt &line=location.get_line(); + const irep_idt &function=location.get_function(); + + if(!function.empty()) + { + if(!file.empty()) + dest+=id2string(file)+":"; + if(dest!="") dest+=' '; + dest+="In function '"+id2string(function)+"':\n"; + } + + if(!line.empty()) + { + if(!file.empty()) + dest+=id2string(file)+":"; + + dest+=id2string(line)+":"+id2string(line)+":"; + } + + dest+=message; + + print(level, dest); +} + +/*******************************************************************\ + +Function: gcc_message_handlert::print + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +void gcc_message_handlert::print( + unsigned level, + const std::string &message) +{ + // gcc appears to send everything to cerr + std::cerr << message << '\n' << std::flush; +} diff --git a/src/util/cout_message.h b/src/util/cout_message.h index 0cedb2b790c..ab78148c6d6 100644 --- a/src/util/cout_message.h +++ b/src/util/cout_message.h @@ -15,21 +15,42 @@ class cout_message_handlert:public message_handlert { public: // all messages go to cout - virtual void print(unsigned level, const std::string &message); + virtual void print( + unsigned level, + const std::string &message) override; }; class cerr_message_handlert:public message_handlert { public: // all messages go to cerr - virtual void print(unsigned level, const std::string &message); + virtual void print( + unsigned level, + const std::string &message) override; }; class console_message_handlert:public message_handlert { public: // level 4 and upwards go to cout, level 1-3 to cerr - virtual void print(unsigned level, const std::string &message); + virtual void print( + unsigned level, + const std::string &message) override; +}; + +class gcc_message_handlert:public message_handlert +{ +public: + // aims to imitate the messages gcc prints + virtual void print( + unsigned level, + const std::string &message) override; + + virtual void print( + unsigned level, + const std::string &message, + int sequence_number, + const source_locationt &location) override; }; #endif // CPROVER_UTIL_COUT_MESSAGE_H