|
13 | 13 |
|
14 | 14 | #include <algorithm>
|
15 | 15 |
|
| 16 | +#include <util/c_types.h> |
| 17 | +#include <util/invariant.h> |
16 | 18 | #include <util/simplify_expr.h>
|
17 | 19 | #include <util/array_name.h>
|
18 | 20 | #include <util/ieee_float.h>
|
@@ -900,23 +902,57 @@ void goto_checkt::pointer_overflow_check(
|
900 | 902 | if(!enable_pointer_overflow_check)
|
901 | 903 | return;
|
902 | 904 |
|
903 |
| - if(expr.id()==ID_plus || |
904 |
| - expr.id()==ID_minus) |
| 905 | + if(expr.id()!=ID_plus && |
| 906 | + expr.id()!=ID_minus) |
| 907 | + return; |
| 908 | + |
| 909 | + if(expr.operands().size()>2) |
905 | 910 | {
|
906 |
| - if(expr.operands().size()==2) |
| 911 | + // The overflow checks are binary! |
| 912 | + // We break these up. |
| 913 | + |
| 914 | + for(unsigned i=1; i<expr.operands().size(); i++) |
907 | 915 | {
|
908 |
| - exprt overflow("overflow-"+expr.id_string(), bool_typet()); |
909 |
| - overflow.operands()=expr.operands(); |
| 916 | + exprt tmp; |
910 | 917 |
|
911 |
| - add_guarded_claim( |
912 |
| - not_exprt(overflow), |
913 |
| - "pointer arithmetic overflow on "+expr.id_string(), |
914 |
| - "overflow", |
915 |
| - expr.find_source_location(), |
916 |
| - expr, |
917 |
| - guard); |
| 918 | + if(i==1) |
| 919 | + tmp=expr.op0(); |
| 920 | + else |
| 921 | + { |
| 922 | + tmp=expr; |
| 923 | + tmp.operands().resize(i); |
| 924 | + } |
| 925 | + |
| 926 | + exprt tmp2=expr; |
| 927 | + tmp2.operands().resize(2); |
| 928 | + tmp2.op0()=tmp; |
| 929 | + tmp2.op1()=expr.operands()[i]; |
| 930 | + |
| 931 | + pointer_overflow_check(tmp2, guard); |
918 | 932 | }
|
919 | 933 | }
|
| 934 | + else |
| 935 | + { |
| 936 | + DATA_INVARIANT( |
| 937 | + expr.operands().size() == 2, |
| 938 | + "overflow-" + expr.id_string() + " takes 2 operands"); |
| 939 | + |
| 940 | + exprt overflow("overflow-"+expr.id_string(), bool_typet()); |
| 941 | + overflow.operands()=expr.operands(); |
| 942 | + |
| 943 | + // this is overflow over integers |
| 944 | + overflow.op0().make_typecast(size_type()); |
| 945 | + if(overflow.op1().type()!=size_type()) |
| 946 | + overflow.op1().make_typecast(size_type()); |
| 947 | + |
| 948 | + add_guarded_claim( |
| 949 | + not_exprt(overflow), |
| 950 | + "pointer arithmetic overflow on "+expr.id_string(), |
| 951 | + "overflow", |
| 952 | + expr.find_source_location(), |
| 953 | + expr, |
| 954 | + guard); |
| 955 | + } |
920 | 956 | }
|
921 | 957 |
|
922 | 958 | void goto_checkt::pointer_validity_check(
|
|
0 commit comments