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