@@ -676,7 +676,7 @@ object (self)
676676 let memoff_r =
677677 TR. tbind
678678 (fun memvar ->
679- let memtype = self#get_variable_type memvar in
679+ let memtype = self#env# get_variable_type memvar in
680680 let memtype =
681681 match memtype with
682682 | Some t -> t
@@ -703,7 +703,8 @@ object (self)
703703 match optbasetype with
704704 | Some t when is_pointer t -> ptr_deref t
705705 | _ -> t_unknown in
706- address_memory_offset basetype (num_constant_expr memoffset))
706+ address_memory_offset basetype
707+ ~tgtsize: (Some size) (num_constant_expr memoffset))
707708 (self#env#get_variable base#getSeqNumber) in
708709 mk_memvar memref_r memoff_r
709710
@@ -1319,23 +1320,139 @@ object (self)
13191320 method private get_variable_type (v : variable_t ): btype_t option =
13201321 if self#f#env#is_initial_register_value v then
13211322 let reg_r = self#f#env#get_initial_register_value_register v in
1322- let param_r =
1323- TR. tbind
1324- (fun reg ->
1325- if self#f#get_summary#has_parameter_for_register reg then
1326- Ok (self#f#get_summary#get_parameter_for_register reg)
1327- else
1328- Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1329- ^ (p2s v#toPretty)
1330- ^ " does not have an associated parameter" ])
1331- reg_r in
13321323 TR. tfold_default
1333- (fun param -> Some param.apar_type)
1334- (self#env#get_variable_type v)
1335- param_r
1324+ (fun reg ->
1325+ if self#f#get_summary#has_parameter_for_register reg then
1326+ let param = self#f#get_summary#get_parameter_for_register reg in
1327+ Some param.apar_type
1328+ else
1329+ self#env#get_variable_type v)
1330+ None
1331+ reg_r
1332+ else if self#env#is_initial_memory_value v then
1333+ let memvar_r = self#env#get_init_value_variable v in
1334+ TR. tfold
1335+ ~ok: self#get_variable_type
1336+ ~error: (fun e ->
1337+ begin log_error_result __FILE__ __LINE__ e; None end )
1338+ memvar_r
13361339 else
13371340 self#env#get_variable_type v
13381341
1342+ method convert_variable_offsets
1343+ ?(size =None ) (v : variable_t ): variable_t traceresult =
1344+ if self#env#is_basevar_memory_variable v then
1345+ let basevar_r = self#env#get_memvar_basevar v in
1346+ let offset_r = self#env#get_memvar_offset v in
1347+ let cbasevar_r = TR. tbind self#convert_value_offsets basevar_r in
1348+ let basetype_r = TR. tmap self#get_variable_type cbasevar_r in
1349+ let tgttype_r =
1350+ TR. tbind
1351+ (fun basetype ->
1352+ match basetype with
1353+ | Some (TPtr (t , _ )) -> Ok t
1354+ | Some t ->
1355+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1356+ ^ " Type " ^ (btype_to_string t)
1357+ ^ " is not a pointer" ]
1358+ | _ ->
1359+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1360+ ^ " No type for variable "
1361+ ^ (p2s v#toPretty)
1362+ ^ " with basevar "
1363+ ^ (p2s (TR. tget_ok cbasevar_r)#toPretty)]) basetype_r in
1364+ let coffset_r =
1365+ TR. tbind
1366+ (fun offset ->
1367+ match offset with
1368+ | ConstantOffset (n , NoOffset) ->
1369+ TR. tbind
1370+ (fun tgttype ->
1371+ address_memory_offset
1372+ ~tgtsize: size tgttype (num_constant_expr n)) tgttype_r
1373+ | _ -> Ok offset) offset_r in
1374+ TR. tbind
1375+ ~msg: (__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : " ^ (p2s v#toPretty))
1376+ (fun cbasevar ->
1377+ TR. tbind
1378+ (fun coffset ->
1379+ self#env#mk_basevar_memory_variable cbasevar coffset
1380+ ) coffset_r)
1381+ cbasevar_r
1382+ else
1383+ Ok v
1384+
1385+ method convert_value_offsets
1386+ ?(size =None ) (v : variable_t ): variable_t traceresult =
1387+ if self#env#is_basevar_memory_value v then
1388+ let basevar_r = self#env#get_memval_basevar v in
1389+ let offset_r = self#env#get_memval_offset v in
1390+ let cbasevar_r = TR. tbind self#convert_value_offsets basevar_r in
1391+ let basetype_r = TR. tmap self#get_variable_type cbasevar_r in
1392+ let tgttype_r =
1393+ TR. tbind
1394+ (fun basetype ->
1395+ match basetype with
1396+ | Some (TPtr (t , _ )) -> Ok t
1397+ | Some t ->
1398+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1399+ ^ " Type " ^ (btype_to_string t)
1400+ ^ " is not a pointer" ]
1401+ | _ ->
1402+ Error [__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : "
1403+ ^ " No type for variable "
1404+ ^ (p2s v#toPretty)
1405+ ^ " with basevar "
1406+ ^ (p2s (TR. tget_ok cbasevar_r)#toPretty)]) basetype_r in
1407+ let coffset_r =
1408+ TR. tbind
1409+ (fun offset ->
1410+ match offset with
1411+ | NoOffset ->
1412+ TR. tbind
1413+ (fun tgttype ->
1414+ address_memory_offset
1415+ ~tgtsize: size tgttype (int_constant_expr 0 )) tgttype_r
1416+ | ConstantOffset (n , NoOffset) ->
1417+ TR. tbind
1418+ (fun tgttype ->
1419+ address_memory_offset
1420+ ~tgtsize: size tgttype (num_constant_expr n)) tgttype_r
1421+ | _ -> Ok offset) offset_r in
1422+ TR. tbind
1423+ ~msg: (__FILE__ ^ " :" ^ (string_of_int __LINE__) ^ " : " ^ (p2s v#toPretty))
1424+ (fun cbasevar ->
1425+ TR. tbind
1426+ (fun coffset ->
1427+ let memvar_r =
1428+ self#env#mk_basevar_memory_variable cbasevar coffset in
1429+ TR. tbind self#env#mk_initial_memory_value memvar_r
1430+ ) coffset_r)
1431+ cbasevar_r
1432+ else
1433+ Ok v
1434+
1435+ method convert_xpr_offsets ?(size =None ) (x : xpr_t ): xpr_t traceresult =
1436+ let rec aux exp =
1437+ match exp with
1438+ | XVar v when self#env#is_basevar_memory_value v ->
1439+ TR. tmap
1440+ ~msg: (__FILE__ ^ " :" ^ (string_of_int __LINE__))
1441+ (fun v -> XVar v) (self#convert_value_offsets ~size v)
1442+ | XVar v when self#env#is_basevar_memory_variable v ->
1443+ TR. tmap
1444+ ~msg: (__FILE__ ^ " :" ^ (string_of_int __LINE__))
1445+ (fun v -> XVar v) (self#convert_variable_offsets ~size v)
1446+ | XOp ((Xf "addressofvar" ), [XVar v ]) ->
1447+ TR. tmap
1448+ ~msg: (__FILE__ ^ " :" ^ (string_of_int __LINE__))
1449+ (fun v -> XVar v) (self#convert_variable_offsets ~size v)
1450+ | XOp (op , [xx ]) -> TR. tmap (fun x -> XOp (op, [x])) (aux xx)
1451+ | XOp (op , [x1 ; x2 ]) ->
1452+ TR. tmap2 (fun x1 x2 -> XOp (op, [x1; x2])) (aux x1) (aux x2)
1453+ | _ -> Ok exp in
1454+ aux x
1455+
13391456 method get_xpr_type (x : xpr_t ): btype_t option =
13401457 match x with
13411458 | XVar v -> self#get_variable_type v
@@ -1351,9 +1468,12 @@ object (self)
13511468 | [base] ->
13521469 let offset = simplify_xpr (XOp (XMinus , [x; XVar base])) in
13531470 let memref_r = self#env#mk_base_variable_reference base in
1354- let vartype = self#get_variable_type base in
1471+ let vartype = self#env# get_variable_type base in
13551472 let vartype = match vartype with None -> t_unknown | Some t -> t in
1356- let memoff_r = address_memory_offset vartype offset in
1473+ let rvartype = TR. tvalue (resolve_type vartype) ~default: t_unknown in
1474+ let basetype =
1475+ if is_pointer rvartype then ptr_deref rvartype else t_unknown in
1476+ let memoff_r = address_memory_offset basetype offset in
13571477 (*
13581478 (match offset with
13591479 | XConst (IntConst n) -> Ok (ConstantOffset (n, NoOffset))
0 commit comments