Skip to content

Commit

Permalink
Merge pull request #5591 from 9rnsr/fix13116
Browse files Browse the repository at this point in the history
Issue 13116 - Should not be able to return ref to 'this'
  • Loading branch information
WalterBright committed Mar 31, 2016
2 parents 1d8ce9d + b0f45b0 commit 2d59f2e
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 50 deletions.
20 changes: 4 additions & 16 deletions src/expression.d
Expand Up @@ -1616,14 +1616,7 @@ extern (C++) bool functionParameters(Loc loc, Scope* sc, TypeFunction tf, Type t
}
if (p.storageClass & STCref)
{
if (p.storageClass & STCautoref &&
(arg.op == TOKthis || arg.op == TOKsuper))
{
// suppress deprecation message for auto ref parameter
// temporary workaround for Bugzilla 14283
}
else
arg = arg.toLvalue(sc, arg);
arg = arg.toLvalue(sc, arg);
}
else if (p.storageClass & STCout)
{
Expand Down Expand Up @@ -4068,20 +4061,15 @@ public:
override final bool isLvalue()
{
// Class `this` should be an rvalue; struct `this` should be an lvalue.
// Need to deprecate the old behavior first, see Bugzilla 14262.
return true;
return type.toBasetype().ty != Tclass;
}

override final Expression toLvalue(Scope* sc, Expression e)
{
if (type.toBasetype().ty == Tclass)
{
// use Expression::toLvalue when deprecation is over
if (!e)
e = this;
else if (!loc.filename)
loc = e.loc;
deprecation("%s is not an lvalue", e.toChars());
// Class `this` is an rvalue; struct `this` is an lvalue.
return Expression.toLvalue(sc, e);
}
return this;
}
Expand Down
13 changes: 4 additions & 9 deletions test/compilable/deprecate14283.d
@@ -1,23 +1,18 @@
// REQUIRED_ARGS: -dw

// PERMUTE_ARGS:
/*
TEST_OUTPUT:
---
compilable/deprecate14283.d(17): Deprecation: this is not an lvalue
compilable/deprecate14283.d(18): Deprecation: super is not an lvalue
---
*/

class C
{
void bug()
{
autoref(this); // suppress warning for auto ref
autoref(super); // suppress warning for auto ref
ref_(this); // still warns
ref_(super); // still warns
autoref(this); // 'auto ref' becomes non-ref parameter
autoref(super); // 'auto ref' becomes non-ref parameter
}
}

void autoref(T)(auto ref T t) {}
void ref_(T)(ref T) {}
void autoref(T)(auto ref T t) { static assert(__traits(isRef, t) == false); }
21 changes: 0 additions & 21 deletions test/compilable/diag4596.d

This file was deleted.

21 changes: 21 additions & 0 deletions test/fail_compilation/diag4596.d
@@ -0,0 +1,21 @@
/*
TEST_OUTPUT:
---
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
---
*/

class NoGo4596
{
void fun()
{
this = new NoGo4596;
(1?this:this) = new NoGo4596;

super = new Object;
(1?super:super) = new Object;
}
}
6 changes: 2 additions & 4 deletions test/fail_compilation/fail13116.d
@@ -1,8 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail13116.d(14): Deprecation: this is not an lvalue
fail_compilation/fail13116.d(14): Error: escaping reference to local variable this
fail_compilation/fail13116.d(13): Error: this is not an lvalue
---
*/
struct S
Expand All @@ -20,8 +19,7 @@ void main()
/*
TEST_OUTPUT:
---
fail_compilation/fail13116.d(30): Deprecation: super is not an lvalue
fail_compilation/fail13116.d(30): Error: escaping reference to local variable this
fail_compilation/fail13116.d(28): Error: super is not an lvalue
---
*/
class Base { }
Expand Down

0 comments on commit 2d59f2e

Please sign in to comment.