Skip to content

Commit

Permalink
Merge pull request #3761 from quickfur/issue13116
Browse files Browse the repository at this point in the history
Issue 13116: should reject returning `this` from a ref class member function
  • Loading branch information
9rnsr committed Aug 5, 2014
2 parents 5418b71 + 311937f commit 24e8347
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 15 deletions.
14 changes: 5 additions & 9 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -3455,22 +3455,18 @@ int ThisExp::isBool(int result)

int ThisExp::isLvalue()
{
return 1;
// Class `this` is an rvalue; struct `this` is an lvalue.
return (type->toBasetype()->ty != Tclass);
}

Expression *ThisExp::toLvalue(Scope *sc, Expression *e)
{
return this;
}

Expression *ThisExp::modifiableLvalue(Scope *sc, Expression *e)
{
if (type->toBasetype()->ty == Tclass)
{
error("cannot modify '%s' reference", toChars());
return toLvalue(sc, e);
// Class `this` is an rvalue; struct `this` is an lvalue.
return Expression::toLvalue(sc, e);
}
return Expression::modifiableLvalue(sc, e);
return this;
}

/******************************** SuperExp **************************/
Expand Down
1 change: 0 additions & 1 deletion src/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,6 @@ class ThisExp : public Expression
int isBool(int result);
int isLvalue();
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);

void accept(Visitor *v) { v->visit(this); }
};
Expand Down
8 changes: 4 additions & 4 deletions test/fail_compilation/diag4596.d
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
TEST_OUTPUT:
---
fail_compilation/diag4596.d(15): Error: cannot modify 'this' reference
fail_compilation/diag4596.d(16): Error: cannot modify 'this' reference
fail_compilation/diag4596.d(18): Error: cannot modify 'super' reference
fail_compilation/diag4596.d(19): Error: cannot modify 'super' reference
fail_compilation/diag4596.d(15): Error: this is not an lvalue
fail_compilation/diag4596.d(16): Error: 1 ? this : this is not an lvalue
fail_compilation/diag4596.d(18): Error: super is not an lvalue
fail_compilation/diag4596.d(19): Error: 1 ? super : super is not an lvalue
---
*/

Expand Down
29 changes: 29 additions & 0 deletions test/fail_compilation/fail13116.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail13116.d(13): Error: this is not an lvalue
---
*/
struct S
{
ref S notEvil() { return this; } // this should be accepted
}
class C
{
ref C evil() { return this; } // this should be rejected
}
void main()
{
}

/*
TEST_OUTPUT:
---
fail_compilation/fail13116.d(28): Error: super is not an lvalue
---
*/
class Base { }
class Derived : Base
{
ref Base evil() { return super; } // should be rejected
}
2 changes: 1 addition & 1 deletion test/runnable/template9.d
Original file line number Diff line number Diff line change
Expand Up @@ -2065,7 +2065,7 @@ class C9083

void func()
{
void templateFunc(T)(ref const T obj)
void templateFunc(T)(const T obj)
{
enum x1 = isFunction9083!(mixin("x")); // NG
enum x2 = isFunction9083!(x); // NG
Expand Down

0 comments on commit 24e8347

Please sign in to comment.