@@ -22,6 +22,8 @@ Author: Peter Schrammel
2222
2323#include " 2ls_parse_options.h"
2424
25+ #define NOT_MATH_FUN (call, fun ) call != fun &&call != fun " f" && call != fun " l"
26+
2527void twols_parse_optionst::inline_main (goto_modelt &goto_model)
2628{
2729 irep_idt start=goto_functionst::entry_point ();
@@ -653,9 +655,12 @@ void twols_parse_optionst::handle_freed_ptr_compare(goto_modelt &goto_model)
653655 }
654656}
655657
656- // / Add assertions preventing analysis of programs using GCC builtin functions
657- // / that are not supported and can cause false results.
658- void twols_parse_optionst::assert_no_builtin_functions (goto_modelt &goto_model)
658+ // / Fail if the program contains any functions that 2LS does not currently
659+ // / support. These include:
660+ // / - builtin gcc functions
661+ // / - longjmp (not supported by CBMC)
662+ void twols_parse_optionst::assert_no_unsupported_functions (
663+ goto_modelt &goto_model)
659664{
660665 forall_goto_program_instructions (
661666 i_it,
@@ -666,6 +671,7 @@ void twols_parse_optionst::assert_no_builtin_functions(goto_modelt &goto_model)
666671 assert (
667672 name.find (" __builtin_" )==std::string::npos &&
668673 name.find (" __CPROVER_overflow" )==std::string::npos);
674+ assert (name != " longjmp" && name != " _longjmp" && name != " siglongjmp" );
669675
670676 if (i_it->is_assign ())
671677 {
@@ -674,9 +680,13 @@ void twols_parse_optionst::assert_no_builtin_functions(goto_modelt &goto_model)
674680 }
675681}
676682
677- // / Prevents usage of atexit function which is not supported, yet
678- // / Must be called before inlining since it will lose the calls
679- void twols_parse_optionst::assert_no_atexit (goto_modelt &goto_model)
683+ // / Fail if the program contains a call to an unsupported function. These
684+ // / include the atexit function and advanced math functions from math.h (
685+ // / these are either not defined in CBMC at all, or defined very imprecisely,
686+ // / e.g. the result of cos is in <-1, 1> without any further information).
687+ // / Must be called before inlining since it will lose the calls.
688+ void twols_parse_optionst::assert_no_unsupported_function_calls (
689+ goto_modelt &goto_model)
680690{
681691 for (const auto &f_it : goto_model.goto_functions .function_map )
682692 {
@@ -689,6 +699,23 @@ void twols_parse_optionst::assert_no_atexit(goto_modelt &goto_model)
689699 continue ;
690700 auto &name=id2string (to_symbol_expr (function).get_identifier ());
691701 assert (name!=" atexit" );
702+ assert (
703+ // Trigonometry
704+ NOT_MATH_FUN (name, " cos" ) && NOT_MATH_FUN (name, " acos" ) &&
705+ NOT_MATH_FUN (name, " sin" ) && NOT_MATH_FUN (name, " asin" ) &&
706+ NOT_MATH_FUN (name, " tan" ) && NOT_MATH_FUN (name, " atan" ) &&
707+ NOT_MATH_FUN (name, " atan2" ) &&
708+ // Hyperbolic
709+ NOT_MATH_FUN (name, " cosh" ) && NOT_MATH_FUN (name, " acosh" ) &&
710+ NOT_MATH_FUN (name, " sinh" ) && NOT_MATH_FUN (name, " asinh" ) &&
711+ NOT_MATH_FUN (name, " tanh" ) && NOT_MATH_FUN (name, " atanh" ) &&
712+ // Exponential
713+ NOT_MATH_FUN (name, " exp" ) && NOT_MATH_FUN (name, " exp2" ) &&
714+ NOT_MATH_FUN (name, " expm1" ) && NOT_MATH_FUN (name, " log" ) &&
715+ NOT_MATH_FUN (name, " log10" ) && NOT_MATH_FUN (name, " log2" ) &&
716+ NOT_MATH_FUN (name, " log1p" ) &&
717+ // Other
718+ NOT_MATH_FUN (name, " erf" ));
692719 }
693720 }
694721 }
0 commit comments