diff --git a/src/common/objects/dobjtype.cpp b/src/common/objects/dobjtype.cpp index b6379106c0a..70e83f8eadf 100644 --- a/src/common/objects/dobjtype.cpp +++ b/src/common/objects/dobjtype.cpp @@ -669,7 +669,7 @@ PClass *PClass::FindClassTentative(FName name) // //========================================================================== -int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType) +int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType, bool ignorePointerReadOnly) { auto proto = variant->Proto; for (unsigned i = 0; i < Virtuals.Size(); i++) @@ -689,8 +689,22 @@ int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction { if (proto->ArgumentTypes[a] != vproto->ArgumentTypes[a]) { - fail = true; - break; + if(ignorePointerReadOnly && proto->ArgumentTypes[a]->isPointer() && vproto->ArgumentTypes[a]->isPointer()) + { + PPointer *ppa = proto->ArgumentTypes[a]->toPointer(); + PPointer *ppb = vproto->ArgumentTypes[a]->toPointer(); + + if(ppa->PointedType != ppb->PointedType) + { + fail = true; + break; + } + } + else + { + fail = true; + break; + } } } if (fail) continue; diff --git a/src/common/objects/dobjtype.h b/src/common/objects/dobjtype.h index 81fbe3aac21..7e698a6bf8e 100644 --- a/src/common/objects/dobjtype.h +++ b/src/common/objects/dobjtype.h @@ -43,7 +43,7 @@ class PClass void InitializeSpecials(void* addr, void* defaults, TArray PClass::* Inits); void WriteAllFields(FSerializer &ar, const void *addr) const; bool ReadAllFields(FSerializer &ar, void *addr) const; - int FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType); + int FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType, bool ignorePointerReadOnly); PSymbol *FindSymbol(FName symname, bool searchparents) const; PField *AddField(FName name, PType *type, uint32_t flags, int fileno = 0); void InitializeDefaults(); diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index ac3bde1e921..0504fc16006 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -291,23 +291,21 @@ bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare) if (!forcompare && fromtype->IsConst && !totype->IsConst) return false; // A type is always compatible to itself. if (fromtype == totype) return true; - // Pointers to different types are only compatible if both point to an object and the source type is a child of the destination type. if (source->isObjectPointer() && dest->isObjectPointer()) - { + { // Pointers to different types are only compatible if both point to an object and the source type is a child of the destination type. auto fromcls = static_cast(source)->PointedClass(); auto tocls = static_cast(dest)->PointedClass(); if (forcompare && tocls->IsDescendantOf(fromcls)) return true; return (fromcls->IsDescendantOf(tocls)); } - // The same rules apply to class pointers. A child type can be assigned to a variable of a parent type. - if (source->isClassPointer() && dest->isClassPointer()) - { + else if (source->isClassPointer() && dest->isClassPointer()) + { // The same rules apply to class pointers. A child type can be assigned to a variable of a parent type. auto fromcls = static_cast(source)->ClassRestriction; auto tocls = static_cast(dest)->ClassRestriction; if (forcompare && tocls->IsDescendantOf(fromcls)) return true; return (fromcls->IsDescendantOf(tocls)); } - if(source->isFunctionPointer() && dest->isFunctionPointer()) + else if(source->isFunctionPointer() && dest->isFunctionPointer()) { auto from = static_cast(source); auto to = static_cast(dest); @@ -315,6 +313,10 @@ bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare) return to->PointedType == TypeVoid || (AreCompatibleFnPtrTypes((PPrototype *)to->PointedType, (PPrototype *)from->PointedType) && from->ArgFlags == to->ArgFlags && FScopeBarrier::CheckSidesForFunctionPointer(from->Scope, to->Scope)); } + else if(source->isRealPointer() && dest->isRealPointer()) + { + return fromtype->PointedType == totype->PointedType; + } } return false; } diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index 4c3f2bc383f..14a0fd5fab9 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -2764,7 +2764,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool // [ZZ] unspecified virtual function inherits old scope. virtual function scope can't be changed. sym->Variants[0].Implementation->VarFlags = sym->Variants[0].Flags; } - + bool exactReturnType = mVersion < MakeVersion(4, 4); PClass *clstype = forclass? static_cast(c->Type())->Descriptor : nullptr; if (varflags & VARF_Virtual) @@ -2785,7 +2785,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool auto parentfunc = clstype->ParentClass? dyn_cast(clstype->ParentClass->VMType->Symbols.FindSymbol(sym->SymbolName, true)) : nullptr; - int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], parentfunc, exactReturnType); + int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], parentfunc, exactReturnType, sym->SymbolName == FName("SpecialBounceHit") && mVersion < MakeVersion(4, 12)); // specifying 'override' is necessary to prevent one of the biggest problem spots with virtual inheritance: Mismatching argument types. if (varflags & VARF_Override) { @@ -2867,7 +2867,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool } else if (forclass) { - int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], nullptr, exactReturnType); + int virtindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], nullptr, exactReturnType, sym->SymbolName == FName("SpecialBounceHit") && mVersion < MakeVersion(4, 12)); if (virtindex != -1) { Error(f, "Function %s attempts to override parent function without 'override' qualifier", FName(f->Name).GetChars()); diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index fed44435974..3fe7f189873 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -565,7 +565,7 @@ class Actor : Thinker native } // This is called when a missile bounces off something. - virtual int SpecialBounceHit(Actor bounceMobj, Line bounceLine, SecPlane bouncePlane) + virtual int SpecialBounceHit(Actor bounceMobj, Line bounceLine, readonly bouncePlane) { return MHIT_DEFAULT; } @@ -847,7 +847,7 @@ class Actor : Thinker native native void PlayPushSound(); native bool BounceActor(Actor blocking, bool onTop); native bool BounceWall(Line l = null); - native bool BouncePlane(SecPlane plane); + native bool BouncePlane(readonly plane); native void PlayBounceSound(bool onFloor); native bool ReflectOffActor(Actor blocking); diff --git a/wadsrc/static/zscript/mapdata.zs b/wadsrc/static/zscript/mapdata.zs index 88b1325496c..db217e7cc74 100644 --- a/wadsrc/static/zscript/mapdata.zs +++ b/wadsrc/static/zscript/mapdata.zs @@ -270,7 +270,7 @@ struct SecPlane native play native clearscope int PointOnSide(Vector3 pos) const; native clearscope double ZatPoint (Vector2 v) const; native clearscope double ZatPointDist(Vector2 v, double dist) const; - native clearscope bool isEqual(Secplane other) const; + native clearscope bool isEqual(readonly other) const; //native void ChangeHeight(double hdiff); native clearscope double GetChangedHeight(double hdiff) const; native clearscope double HeightDiff(double oldd, double newd = 1e37) const;