@@ -22,6 +22,8 @@ Author: Peter Schrammel
22
22
23
23
#include " 2ls_parse_options.h"
24
24
25
+ #define NOT_MATH_FUN (call, fun ) call != fun &&call != fun " f" && call != fun " l"
26
+
25
27
void twols_parse_optionst::inline_main (goto_modelt &goto_model)
26
28
{
27
29
irep_idt start=goto_functionst::entry_point ();
@@ -653,9 +655,12 @@ void twols_parse_optionst::handle_freed_ptr_compare(goto_modelt &goto_model)
653
655
}
654
656
}
655
657
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)
659
664
{
660
665
forall_goto_program_instructions (
661
666
i_it,
@@ -666,6 +671,7 @@ void twols_parse_optionst::assert_no_builtin_functions(goto_modelt &goto_model)
666
671
assert (
667
672
name.find (" __builtin_" )==std::string::npos &&
668
673
name.find (" __CPROVER_overflow" )==std::string::npos);
674
+ assert (name != " longjmp" && name != " _longjmp" && name != " siglongjmp" );
669
675
670
676
if (i_it->is_assign ())
671
677
{
@@ -674,9 +680,13 @@ void twols_parse_optionst::assert_no_builtin_functions(goto_modelt &goto_model)
674
680
}
675
681
}
676
682
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)
680
690
{
681
691
for (const auto &f_it : goto_model.goto_functions .function_map )
682
692
{
@@ -689,6 +699,23 @@ void twols_parse_optionst::assert_no_atexit(goto_modelt &goto_model)
689
699
continue ;
690
700
auto &name=id2string (to_symbol_expr (function).get_identifier ());
691
701
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" ));
692
719
}
693
720
}
694
721
}
0 commit comments