@@ -75,6 +75,8 @@ class goto_checkt
7575    error_labels=_options.get_list_option (" error-label"  );
7676    enable_pointer_primitive_check =
7777      _options.get_bool_option (" pointer-primitive-check"  );
78+     enable_allocate_size_check =
79+       _options.get_bool_option (" allocate-size-check"  );
7880  }
7981
8082  typedef  goto_functionst::goto_functiont goto_functiont;
@@ -195,6 +197,8 @@ class goto_checkt
195197  // / \param guard: the condition under which the operation happens
196198  void  pointer_primitive_check (const  exprt &expr, const  guardt &guard);
197199
200+   void  allocate_size_check (const  side_effect_exprt &expr, const  guardt &guard);
201+ 
198202  // / Returns true if the given expression is a pointer primitive such as
199203  // / __CPROVER_r_ok()
200204  // /
@@ -256,6 +260,7 @@ class goto_checkt
256260  bool  enable_built_in_assertions;
257261  bool  enable_assumptions;
258262  bool  enable_pointer_primitive_check;
263+   bool  enable_allocate_size_check;
259264
260265  typedef  optionst::value_listt error_labelst;
261266  error_labelst error_labels;
@@ -1229,6 +1234,29 @@ void goto_checkt::pointer_primitive_check(
12291234    guard);
12301235}
12311236
1237+ void  goto_checkt::allocate_size_check (
1238+   const  side_effect_exprt &expr,
1239+   const  guardt &guard)
1240+ {
1241+   if (!enable_allocate_size_check)
1242+     return ;
1243+ 
1244+   const  exprt size_expr = expr.operands ().front ();
1245+ 
1246+   binary_relation_exprt bre (
1247+     size_expr,
1248+     ID_le,
1249+     ns.lookup (CPROVER_PREFIX " max_malloc_size"  ).symbol_expr ());
1250+ 
1251+   add_guarded_property (
1252+     bre,
1253+     " more memory allocated than can be addressed by cbmc"  ,
1254+     " allocate"  ,
1255+     expr.source_location (),
1256+     expr,
1257+     guard);
1258+ }
1259+ 
12321260bool  goto_checkt::is_pointer_primitive (const  exprt &expr)
12331261{
12341262  //  we don't need to include the __CPROVER_same_object primitive here as it
@@ -1812,6 +1840,15 @@ void goto_checkt::check_rec(const exprt &expr, guardt &guard)
18121840  {
18131841    pointer_primitive_check (expr, guard);
18141842  }
1843+   else  if (expr.id () == ID_side_effect)
1844+   {
1845+     const  auto  &side_effect_expr = to_side_effect_expr (expr);
1846+ 
1847+     if (side_effect_expr.get_statement () == ID_allocate)
1848+     {
1849+       allocate_size_check (side_effect_expr, guard);
1850+     }
1851+   }
18151852}
18161853
18171854void  goto_checkt::check (const  exprt &expr)
@@ -1934,6 +1971,8 @@ void goto_checkt::goto_check(
19341971        flag_resetter.set_flag (enable_nan_check, false );
19351972      else  if (d.first  == " disable:pointer-primitive-check"  )
19361973        flag_resetter.set_flag (enable_pointer_primitive_check, false );
1974+       else  if (d.first  == " disable:allocate-size-check"  )
1975+         flag_resetter.set_flag (enable_allocate_size_check, false );
19371976    }
19381977
19391978    new_code.clear ();
0 commit comments