From 738955c4c03f7e0e82fd10ab615a7ccbb2c58cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Tue, 5 Mar 2024 19:50:36 -0300 Subject: [PATCH] fix argument pointer wrapping in function pointers --- src/common/scripting/frontend/zcc_compile.cpp | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index 14a0fd5fab9..d109717a32f 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -43,6 +43,11 @@ FSharedStringArena VMStringConstants; +static bool ShouldWrapPointer(PType * type) +{ + return ((type->isStruct() && type != TypeVector2 && type != TypeVector3 && type != TypeVector4 && type != TypeQuaternion && type != TypeFVector2 && type != TypeFVector3 && type != TypeFVector4 && type != TypeFQuaternion) || type->isDynArray() || type->isMap() || type->isMapIterator()); +} + int GetIntConst(FxExpression *ex, FCompileContext &ctx) { ex = new FxIntCast(ex, false); @@ -2049,8 +2054,17 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n } while( (t = (ZCC_Type *)t->SiblingNext) != fn->RetType); if(auto *t = fn->Params; t != nullptr) do { - args.Push(DetermineType(outertype, field, name, t->Type, false, false)); - argflags.Push(t->Flags == ZCC_Out ? VARF_Out : 0); + PType * tt = DetermineType(outertype, field, name, t->Type, false, false); + int flags = 0; + + if (ShouldWrapPointer(tt)) + { + tt = NewPointer(tt); + flags = VARF_Ref; + } + + args.Push(tt); + argflags.Push(t->Flags == ZCC_Out ? VARF_Out|flags : flags); } while( (t = (ZCC_FuncPtrParamDecl *) t->SiblingNext) != fn->Params); auto proto = NewPrototype(returns,args); @@ -2550,7 +2564,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool { auto type = DetermineType(c->Type(), p, f->Name, p->Type, false, false); int flags = 0; - if ((type->isStruct() && type != TypeVector2 && type != TypeVector3 && type != TypeVector4 && type != TypeQuaternion && type != TypeFVector2 && type != TypeFVector3 && type != TypeFVector4 && type != TypeFQuaternion) || type->isDynArray() || type->isMap() || type->isMapIterator()) + if (ShouldWrapPointer(type)) { // Structs are being passed by pointer, but unless marked 'out' that pointer must be readonly. type = NewPointer(type /*, !(p->Flags & ZCC_Out)*/);