From 27d36662857d32ef2785b540606b0fd196a94aec Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 22 May 2025 15:28:39 +0200 Subject: [PATCH] Fix pass struct rvalue return to rvalue parameter conflicting zero page registers --- autotest/autotest.bat | 2 +- autotest/copyconstructor.cpp | 9 +++--- oscar64/InterCodeGenerator.cpp | 2 +- oscar64/InterCodeGenerator.h | 2 +- oscar64/Parser.cpp | 53 ++++++++++++++++++++++++++++------ 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/autotest/autotest.bat b/autotest/autotest.bat index 0bdb9db..5881040 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -57,7 +57,7 @@ rem @echo off @call :testh constructortest.cpp @if %errorlevel% neq 0 goto :error -@call :testh copyconstructor.cpp +@call :testn copyconstructor.cpp @if %errorlevel% neq 0 goto :error @call :testh copyassign.cpp diff --git a/autotest/copyconstructor.cpp b/autotest/copyconstructor.cpp index 71f3d0f..88c1c58 100644 --- a/autotest/copyconstructor.cpp +++ b/autotest/copyconstructor.cpp @@ -1,4 +1,5 @@ #include +#include int t, n; @@ -161,7 +162,7 @@ void test_return_value(void) C2 c(test_ret_v()); } - assert(n == 4 && t == 0); + assert(n == 6 && t == 0); } void test_return_reference(void) @@ -184,7 +185,7 @@ void test_retparam_value(void) test_param_fv(test_ret_v()); } - assert(n == 4 && t == 0); + assert(n == 6 && t == 0); } void test_retparam_reference(void) @@ -200,7 +201,6 @@ void test_retparam_reference(void) int main(void) { -#if 0 test_dcopy_init(); test_copy_init(); test_minit(); @@ -208,9 +208,8 @@ int main(void) test_param_value(); test_param_ref(); test_return_value(); -#endif test_retparam_value(); -// test_retparam_reference(); + test_retparam_reference(); return 0; } \ No newline at end of file diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index f9ea31f..cd72336 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1659,7 +1659,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an addressable expression"); if (vp.mTemp != vr.mTemp) - CopyStructSimple(proc, exp, block, inlineMapper, vp, vr); + CopyStruct(proc, exp, block, vp, vr, inlineMapper, false); } else { diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 2129972..d5d192b 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -99,7 +99,7 @@ protected: ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, GotoNode*& gotos, const BranchTarget & breakBlock, const BranchTarget& continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr); void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, GotoNode*& gotos, InlineMapper* inlineMapper); ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr, ExValue* lrexp); - void CopyStruct(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper, bool moving); + void CopyStruct (InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper, bool moving); void CopyStructSimple(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock * block, InlineMapper* inlineMapper, ExValue vl, ExValue vr); void StoreValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue vl, ExValue vr); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index b455d82..0e12052 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -4371,22 +4371,57 @@ Expression* Parser::AddFunctionCallRefReturned(Expression* exp) rexp = ConcatExpression(rexp, AddFunctionCallRefReturned(pex)); - if ((pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF) && + if (pdec->mBase->mType == DT_TYPE_STRUCT && pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT) + { + Declaration* vdec = AllocTempVar(pex->mDecType); + + Expression* vexp = new Expression(pex->mLocation, EX_VARIABLE); + vexp->mDecType = pex->mDecType; + vexp->mDecValue = vdec; + + Expression* cexp = new Expression(pex->mLocation, pex->mType); + cexp->mDecType = pex->mDecType; + cexp->mDecValue = pex->mDecValue; + cexp->mLeft = pex->mLeft; + cexp->mRight = pex->mRight; + cexp->mToken = pex->mToken; + + pex->mType = EX_INITIALIZATION; + pex->mToken = TK_ASSIGN; + pex->mLeft = vexp; + pex->mRight = cexp; + pex->mDecValue = nullptr; + pex->mDecType = vdec->mBase; + + if (vdec->mBase->mDestructor) + { + Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX); + texp->mToken = TK_BINARY_AND; + texp->mLeft = vexp; + texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER); + texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; + texp->mDecType->mBase = vdec->mBase; + texp->mDecType->mSize = 2; + + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = vdec->mBase->mDestructor; + cexp->mDecType = cexp->mDecValue->mBase; + + Expression* dexp = new Expression(mScanner->mLocation, EX_CALL); + dexp->mLeft = cexp; + dexp->mRight = texp; + + rexp = ConcatExpression(rexp, dexp); + } + } + else if ((pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF) && (pex->mDecType->mType != DT_TYPE_REFERENCE && pex->mDecType->mType != DT_TYPE_RVALUEREF) && pex->mType == EX_CALL) { // Returning a value object for pass as reference // add a temporary variable Declaration* vdec = AllocTempVar(pex->mDecType); -#if 0 - int nindex = mLocalIndex++; - Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE); - - vdec->mVarIndex = nindex; - vdec->mBase = pex->mDecType; - vdec->mSize = pex->mDecType->mSize; -#endif Expression* vexp = new Expression(pex->mLocation, EX_VARIABLE); vexp->mDecType = pex->mDecType; vexp->mDecValue = vdec;