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