diff --git a/autotest/autotest.bat b/autotest/autotest.bat index 2b2ddd1..26e10c4 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -6,6 +6,9 @@ rem @echo off @call :test copyconstructor.cpp @if %errorlevel% neq 0 goto :error +@call :test copyassign.cpp +@if %errorlevel% neq 0 goto :error + @call :test stdlibtest.c @if %errorlevel% neq 0 goto :error diff --git a/autotest/copyassign.cpp b/autotest/copyassign.cpp new file mode 100644 index 0000000..886a321 --- /dev/null +++ b/autotest/copyassign.cpp @@ -0,0 +1,126 @@ +#include + +int t, n; + +struct C0 +{ + int u; + + C0(int a); + ~C0(void); +}; + +C0::C0(int a) : u(a) +{ + t += u; + n++; +} + +C0::~C0(void) +{ + t -= u; +} + +struct C1 +{ + int u; + + C1(int a); + ~C1(void); + C1(const C1 & c); + C1 & operator=(const C1 & c); +}; + +C1::C1(int a) : u(a) +{ + t += u; + n++; +} + +C1::~C1(void) +{ + t -= u; +} + +C1::C1(const C1 & c) : u(c.u) +{ + t += u; + n++; +} + +C1 & C1::operator=(const C1 & c) +{ + t -= u; + u = c.u; + t += u; + return *this; +} + +void test_assign(void) +{ + n = 0; + + { + C1 c(4); + C1 d(5); + c = d; + } + + assert(n == 2 && t == 0); +} + +struct C2 +{ + C1 a, b; + + C2(int x, int y) : a(x), b(y) + {} +}; + +void test_assign_deflt(void) +{ + n = 0; + + { + C2 c(2, 3); + C2 d(5, 10); + c = d; + } + + assert(n == 4 && t == 0); +} + +int k; + +C2 test_ret_v(void) +{ + C2 c(5, 10); + return c; +} + +C2 & test_ret_r(C2 & r) +{ + return r; +} + +void test_assign_return_value(void) +{ + n = 0; + + { + C2 c(2, 3); + c = test_ret_v(); + } + + assert(n == 6 && t == 0); +} + + +int main(void) +{ + test_assign(); + test_assign_deflt(); + test_assign_return_value(); + + return 0; +} diff --git a/autotest/copyconstructor.cpp b/autotest/copyconstructor.cpp index c16f30b..71f3d0f 100644 --- a/autotest/copyconstructor.cpp +++ b/autotest/copyconstructor.cpp @@ -108,7 +108,7 @@ void test_minit_copy(void) int k; -inline void test_param_fv(C2 c) +void test_param_fv(C2 c) { k += c.a.u; } diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 7ac9e9c..94863ce 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -2412,9 +2412,9 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex { if (ndec->mBase->mType == DT_TYPE_FUNCTION && pthis) { - if (ndec->mIdent == Ident::Unique("operator==")) + if (ndec->mIdent == Ident::Unique("operator=")) { - if (ndec->mBase->mParams && ndec->mBase->mParams->mBase->mType == DT_TYPE_REFERENCE && ndec->mBase->mParams->mBase->mBase->IsSame(pthis->mBase)) + if (ndec->mBase->mParams && ndec->mBase->mParams->mBase->mType == DT_TYPE_REFERENCE && ndec->mBase->mParams->mBase->mBase->IsConstSame(pthis->mBase)) { pthis->mBase->mCopyAssignment = ndec; } @@ -3308,6 +3308,8 @@ Expression* Parser::ParseQualify(Expression* exp) return exp; } +static const int NOOVERLOAD = 0x7fffffff; + int Parser::OverloadDistance(Declaration* fdec, Expression* pexp) { Declaration* pdec = fdec->mParams; @@ -3352,17 +3354,17 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp) if (ext) { if ((etype->mFlags & DTF_CONST) && !(ptype->mBase->mFlags & DTF_CONST)) - return INT_MAX; + return NOOVERLOAD; dist += 16 * ncast; } else - return INT_MAX; + return NOOVERLOAD; } else if (ptype->IsSubType(ex->mDecType)) dist += 256; else - return INT_MAX; + return NOOVERLOAD; pdec = pdec->mNext; } @@ -3372,11 +3374,11 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp) break; } else - return INT_MAX; + return NOOVERLOAD; } if (pdec) - return INT_MAX; + return NOOVERLOAD; return dist; } @@ -3389,7 +3391,7 @@ void Parser::ResolveOverloadCall(Expression* cexp, Expression* pexp) if (fdec->mType == DT_CONST_FUNCTION && fdec->mNext) { Declaration* dbest = nullptr; - int ibest = INT_MAX, nbest = 0; + int ibest = NOOVERLOAD, nbest = 0; while (fdec) { @@ -3405,7 +3407,7 @@ void Parser::ResolveOverloadCall(Expression* cexp, Expression* pexp) fdec = fdec->mNext; } - if (ibest == INT_MAX) + if (ibest == NOOVERLOAD) mErrors->Error(cexp->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching function call"); else if (nbest > 1) mErrors->Error(cexp->mLocation, ERRO_AMBIGUOUS_FUNCTION_CALL, "Ambiguous function call");