+/** Infer the type of a part of the block from the type of the block
+ *
+ * TODO, handle DW_TAG_array_type as well as arrays of the object ((*p)[5], p[5])
+ *
+ * TODO, handle subfields ((*p).bar.foo, (*p)[5].bar…)
+ *
+ * @param type_id DWARF type ID of the root address
+ * @param area_size
+ * @return DWARF type ID for given offset
+ */
+static dw_type_t get_offset_type(void* real_base_address, dw_type_t type, int offset, int area_size, mc_snapshot_t snapshot){
+
+ // Beginning of the block, the infered variable type if the type of the block:
+ if(offset==0)
+ return type;
+
+ switch(type->type){
+ case DW_TAG_structure_type :
+ case DW_TAG_class_type:
+ if(type->full_type)
+ type = type->full_type;
+
+ if(area_size != -1 && type->byte_size != area_size){
+ if(area_size>type->byte_size && area_size%type->byte_size == 0)
+ return type;
+ else
+ return NULL;
+ }else{
+ unsigned int cursor = 0;
+ dw_type_t member;
+ xbt_dynar_foreach(type->members, cursor, member){
+
+ if(!member->location.size) {
+ // We have the offset, use it directly (shortcut):
+ if(member->offset == offset)
+ return member->subtype;
+ } else {
+ char* real_member = mc_member_resolve(real_base_address, type, member, snapshot);
+ if(real_member - (char*)real_base_address == offset)
+ return member->subtype;
+ }
+
+ }
+ return NULL;
+ }
+ break;
+ default:
+ /* FIXME : other cases ? */
+ return NULL;
+ break;
+ }
+}
+
+/**
+ *
+ * @param area1 Process address for state 1
+ * @param area2 Process address for state 2
+ * @param snapshot1 Snapshot of state 1
+ * @param snapshot2 Snapshot of state 2
+ * @param previous Pairs of blocks already compared on the current path (or NULL)
+ * @param type_id Type of variable
+ * @param pointer_level
+ * @return 0 (same), 1 (different), -1
+ */
+int compare_heap_area(void *area1, void* area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_dynar_t previous, dw_type_t type, int pointer_level){
+
+ struct s_mm_diff* state = mm_diff_info;