diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 0812ac9d5..668daafda 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -3084,6 +3084,7 @@ DObject *PClass::CreateNew() if (ConstructNative == nullptr) { + M_Free(mem); I_Error("Attempt to instantiate abstract class %s.", TypeName.GetChars()); } ConstructNative (mem); diff --git a/src/dthinker.cpp b/src/dthinker.cpp index a5d78a504..4b690efbc 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -709,7 +709,7 @@ DThinker *FThinkerIterator::Next (bool exact) class DThinkerIterator : public DObject, public FThinkerIterator { - DECLARE_CLASS(DThinkerIterator, DObject) + DECLARE_ABSTRACT_CLASS(DThinkerIterator, DObject) DThinkerIterator() { @@ -722,7 +722,7 @@ public: } }; -IMPLEMENT_CLASS(DThinkerIterator, false, false); +IMPLEMENT_CLASS(DThinkerIterator, true, false); DEFINE_ACTION_FUNCTION(DThinkerIterator, Create) { PARAM_PROLOGUE; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index bfb3e3eec..5606a1102 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -7866,7 +7866,7 @@ DEFINE_ACTION_FUNCTION(AActor, GetBobOffset) class DActorIterator : public DObject, public NActorIterator { - DECLARE_CLASS(DActorIterator, DObject) + DECLARE_ABSTRACT_CLASS(DActorIterator, DObject) public: DActorIterator(PClassActor *cls= nullptr, int tid = 0) @@ -7875,7 +7875,7 @@ public: } }; -IMPLEMENT_CLASS(DActorIterator, false, false); +IMPLEMENT_CLASS(DActorIterator, true, false); DEFINE_ACTION_FUNCTION(DActorIterator, Create) { PARAM_PROLOGUE; diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index ce3e3be22..b588d15d3 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -811,7 +811,19 @@ begin: { b = B; PClass *cls = (PClass*)(pc->op == OP_NEW ? reg.a[b] : konsta[b].v); - if (cls->ObjectFlags & OF_Abstract) ThrowAbortException(X_OTHER, "Cannot instantiate abstract class %s", cls->TypeName.GetChars()); + if (cls->ConstructNative == nullptr) + { + ThrowAbortException(X_OTHER, "Class %s requires native construction", cls->TypeName.GetChars()); + } + if (cls->ObjectFlags & OF_Abstract) + { + ThrowAbortException(X_OTHER, "Cannot instantiate abstract class %s", cls->TypeName.GetChars()); + } + // Creating actors here must be outright prohibited, + if (cls->IsDescendantOf(RUNTIME_CLASS(AActor))) + { + ThrowAbortException(X_OTHER, "Cannot create actors with 'new'"); + } // [ZZ] validate readonly and between scope construction c = C; if (c) FScopeBarrier::ValidateNew(cls, c - 1);