From 415cdad48999fe0c1bfaa2f70a479e37a4574207 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Wed, 30 Apr 2014 21:28:02 +0400 Subject: [PATCH] Make using new for allocating DF objects with vtables a compile-time error. When done from plugins, it doesn't correctly initialize the vtable because of some weird things MSVC does, so the only safe way is to use df::allocate(). For consistency, it is also enforced for code in the main library. It reveals the issue in the digging invaders plugin, first found by warmist. This change is linked to a modification in df-structures codegen. --- library/include/df/custom/viewscreen.methods.inc | 1 + library/modules/Items.cpp | 8 +++++++- library/xml | 2 +- plugins/diggingInvaders/assignJob.cpp | 8 ++++---- 4 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 library/include/df/custom/viewscreen.methods.inc diff --git a/library/include/df/custom/viewscreen.methods.inc b/library/include/df/custom/viewscreen.methods.inc new file mode 100644 index 000000000..c5d277716 --- /dev/null +++ b/library/include/df/custom/viewscreen.methods.inc @@ -0,0 +1 @@ +friend struct df::interfacest; diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 8a3d0e128..38d63d867 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -997,16 +997,22 @@ df::proj_itemst *Items::makeProjectile(MapExtras::MapCache &mc, df::item *item) if (!ref) return NULL; + auto proj = df::allocate(); + if (!proj) { + delete ref; + return NULL; + } + if (!detachItem(mc, item)) { delete ref; + delete proj; return NULL; } item->pos = pos; item->flags.bits.in_job = true; - auto proj = new df::proj_itemst(); proj->link = new df::proj_list_link(); proj->link->item = proj; proj->id = (*proj_next_id)++; diff --git a/library/xml b/library/xml index 9c280e13a..1558b2373 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 9c280e13ab2e2421b8b8cab4a0c146fffc355a3c +Subproject commit 1558b2373fcf8fa63928167e007a7f9a709888b6 diff --git a/plugins/diggingInvaders/assignJob.cpp b/plugins/diggingInvaders/assignJob.cpp index 9472fb0e7..eff2de4ad 100644 --- a/plugins/diggingInvaders/assignJob.cpp +++ b/plugins/diggingInvaders/assignJob.cpp @@ -88,10 +88,10 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_mapjob_type = df::enums::job_type::DestroyBuilding; //job->flags.bits.special = 1; - df::general_ref_building_holderst* buildingRef = new df::general_ref_building_holderst; + df::general_ref_building_holderst* buildingRef = df::allocate(); buildingRef->building_id = building->id; job->general_refs.push_back(buildingRef); - df::general_ref_unit_workerst* workerRef = new df::general_ref_unit_workerst; + df::general_ref_unit_workerst* workerRef = df::allocate(); workerRef->unit_id = firstInvader->id; job->general_refs.push_back(workerRef); getRidOfOldJob(firstInvader); @@ -118,7 +118,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_mapjob_type = df::enums::job_type::RemoveConstruction; - df::general_ref_unit_workerst* workerRef = new df::general_ref_unit_workerst; + df::general_ref_unit_workerst* workerRef = df::allocate(); workerRef->unit_id = firstInvader->id; job->general_refs.push_back(workerRef); job->pos = pt2; @@ -189,7 +189,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_mappos = workHere; firstInvader->path.dest = goHere; location = goHere; - df::general_ref_unit_workerst* ref = new df::general_ref_unit_workerst; + df::general_ref_unit_workerst* ref = df::allocate(); ref->unit_id = firstInvader->id; job->general_refs.push_back(ref); firstInvader->job.hunt_target = NULL;