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<df::foo>(). 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.
develop
Alexander Gavrilov 2014-04-30 21:28:02 +04:00
parent 98325757e2
commit 415cdad489
4 changed files with 13 additions and 6 deletions

@ -0,0 +1 @@
friend struct df::interfacest;

@ -997,16 +997,22 @@ df::proj_itemst *Items::makeProjectile(MapExtras::MapCache &mc, df::item *item)
if (!ref)
return NULL;
auto proj = df::allocate<df::proj_itemst>();
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)++;

@ -1 +1 @@
Subproject commit 9c280e13ab2e2421b8b8cab4a0c146fffc355a3c
Subproject commit 1558b2373fcf8fa63928167e007a7f9a709888b6

@ -88,10 +88,10 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
df::job* job = new df::job;
job->job_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<df::general_ref_building_holderst>();
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<df::general_ref_unit_workerst>();
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_map<df:
if ( construction2 ) {
df::job* job = new df::job;
job->job_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<df::general_ref_unit_workerst>();
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_map<df:
job->pos = 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<df::general_ref_unit_workerst>();
ref->unit_id = firstInvader->id;
job->general_refs.push_back(ref);
firstInvader->job.hunt_target = NULL;