Skip to content

Commit

Permalink
Allow exactly *unreal* VarExp to minimize code breaking
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed Feb 28, 2013
1 parent 580407c commit 3c17d5c
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 12 deletions.
4 changes: 3 additions & 1 deletion src/expression.c
Expand Up @@ -7574,7 +7574,7 @@ Expression *CallExp::resolveUFCS(Scope *sc)
if (e->op == TOKtype || e->op == TOKimport || e->op == TOKdotexp)
return NULL;

e = resolveProperties(sc, e);
e = resolvePropertiesX(sc, e);

Type *t = e->type->toBasetype();
//printf("resolveUCSS %s, e = %s, %s, %s\n",
Expand Down Expand Up @@ -8003,6 +8003,7 @@ Expression *CallExp::semantic(Scope *sc)
UnaExp *ue = (UnaExp *)(e1);

Expression *ue1 = ue->e1;
Expression *ue1old = ue1; // need for 'right this' check
VarDeclaration *v;
if (ue1->op == TOKvar &&
(v = ((VarExp *)ue1)->var->isVarDeclaration()) != NULL &&
Expand Down Expand Up @@ -8066,6 +8067,7 @@ Expression *CallExp::semantic(Scope *sc)
}
else
{
checkRightThis(sc, ue1old);
if (e1->op == TOKdotvar)
{
dve->var = f;
Expand Down
18 changes: 8 additions & 10 deletions src/mtype.c
Expand Up @@ -8135,14 +8135,13 @@ Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident)
return ve;
}

if (d->isDataseg())
bool unreal = e->op == TOKvar && (((VarExp *)e)->var->storage_class & STCfield);
if (d->isDataseg() || unreal && (d->storage_class & STCfield))
{
// (e, d)
VarExp *ve;

accessCheck(e->loc, sc, e, d);
ve = new VarExp(e->loc, d);
e = new CommaExp(e->loc, e, ve);
Expression *ve = new VarExp(e->loc, d);
e = unreal ? ve : new CommaExp(e->loc, e, ve);
e = e->semantic(sc);
return e;
}
Expand Down Expand Up @@ -8815,14 +8814,13 @@ Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident)
return ve;
}

if (d->isDataseg())
bool unreal = e->op == TOKvar && (((VarExp *)e)->var->storage_class & STCfield);
if (d->isDataseg() || unreal && (d->storage_class & STCfield))
{
// (e, d)
VarExp *ve;

accessCheck(e->loc, sc, e, d);
ve = new VarExp(e->loc, d);
e = new CommaExp(e->loc, e, ve);
Expression *ve = new VarExp(e->loc, d);
e = unreal ? ve : new CommaExp(e->loc, e, ve);
e = e->semantic(sc);
return e;
}
Expand Down
2 changes: 1 addition & 1 deletion test/runnable/aliasthis.d
Expand Up @@ -875,7 +875,7 @@ void test8169()

static assert(ValueImpl.getValue() == 42); // #0, OK
static assert(ValueUser.getValue() == 42); // #1, NG -> OK
// static assert( ValueUser.m_valueImpl .getValue() == 42); // #2, NG -> OK -> NG
static assert( ValueUser.m_valueImpl .getValue() == 42); // #2, NG -> OK
static assert(typeof(ValueUser.m_valueImpl).getValue() == 42); // #3, OK
}

Expand Down
37 changes: 37 additions & 0 deletions test/runnable/testrightthis.d
Expand Up @@ -387,13 +387,50 @@ void test5()

/********************************************************/

void test6()
{
static struct Foo
{
static struct Bar
{
static int get() { return 0; }
static int val;
void set() { assert(0); }
int num;
}
static class Baz
{
static int get() { return 0; }
static int val;
void set() { assert(0); }
int num;
}
Bar bar;
Baz baz;
}

// allowed cases that do 'use' Foo.bar without this
assert(Foo.bar.get() == 0); // Foo.bar.get()
assert(Foo.baz.get() == 0); // Foo.bar.get()
static assert(!__traits(compiles, Foo.bar.set()));
static assert(!__traits(compiles, Foo.baz.set()));

assert(Foo.bar.val == 0); // Foo.bar.val
assert(Foo.baz.val == 0); // Foo.baz.val
static assert(!__traits(compiles, Foo.bar.num = 1));
static assert(!__traits(compiles, Foo.baz.num = 1));
}

/********************************************************/

int main()
{
test1();
test2();
test3();
test4();
test5();
test6();

printf("Success\n");
return 0;
Expand Down

0 comments on commit 3c17d5c

Please sign in to comment.