diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index a5d959ab..15045636 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -733,6 +733,7 @@ void startfunc(char *fname); void endfunc(void); void alignframe(int numbytes); void rvalue(value *lval); +void rvalue(svalue *sval); void address(symbol *ptr,regid reg); void store(value *lval); void loadreg(cell address,regid reg); diff --git a/sourcepawn/compiler/sc3.cpp b/sourcepawn/compiler/sc3.cpp index 92a48bf5..ac840747 100644 --- a/sourcepawn/compiler/sc3.cpp +++ b/sourcepawn/compiler/sc3.cpp @@ -2784,7 +2784,8 @@ static int nesting=0; // this reduces it to an iEXPRESSION. That's ok. We don't touch it // otherwise though, so the type checking logic below basically acts the // same. We are careful to not double-evaluate however. - rvalue(&implicit_this.val); + if (implicit_this.lvalue) + rvalue(&implicit_this); pushreg(sPRI); nest_stkusage++; } diff --git a/sourcepawn/compiler/sc4.cpp b/sourcepawn/compiler/sc4.cpp index 1c0a35bf..ce302123 100644 --- a/sourcepawn/compiler/sc4.cpp +++ b/sourcepawn/compiler/sc4.cpp @@ -426,6 +426,16 @@ void rvalue(value *lval) } /* if */ } +// Wrapper that automatically markes lvalues as decayed if they are accessors, +// since it is illegal to evaluate them twice. +void rvalue(svalue *sval) +{ + int ident = sval->val.ident; + rvalue(&sval->val); + if (ident == iACCESSOR) + sval->lvalue = FALSE; +} + /* Get the address of a symbol into the primary or alternate register (used * for arrays, and for passing arguments by reference). */