Skip to content

Commit

Permalink
Issue 11909 - Struct members and static arrays break pure function es…
Browse files Browse the repository at this point in the history
…cape analysis (immutability violation).
  • Loading branch information
dnadlinger committed Jan 25, 2014
1 parent 4bfca03 commit fa6898c
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 13 deletions.
18 changes: 5 additions & 13 deletions src/func.c
Original file line number Diff line number Diff line change
Expand Up @@ -3295,18 +3295,18 @@ Type *getIndirection(Type *t)
}

/**************************************
* Traverse this and t, and then check the indirections convertibility.
* Returns true if memory reachable through a reference B to a value of type tb,
* which has been constructed with a reference A to a value of type ta
* available, can alias memory reachable from A based on the types involved
* (either directly or via any number of indirections).
*/

int traverseIndirections(Type *ta, Type *tb, void *p = NULL, bool a2b = true)
{
if (a2b) // check ta appears in tb
{
//printf("\ttraverse(1) %s appears in %s\n", ta->toChars(), tb->toChars());
if (ta->constConv(tb))
return 1;
else if (ta->immutableOf()->equals(tb->immutableOf()))
return 0;
else if (tb->ty == Tvoid && MODimplicitConv(ta->mod, tb->mod))
return 1;
}
Expand All @@ -3315,8 +3315,6 @@ int traverseIndirections(Type *ta, Type *tb, void *p = NULL, bool a2b = true)
//printf("\ttraverse(2) %s appears in %s\n", tb->toChars(), ta->toChars());
if (tb->constConv(ta))
return 1;
else if (tb->immutableOf()->equals(ta->immutableOf()))
return 0;
else if (ta->ty == Tvoid && MODimplicitConv(tb->mod, ta->mod))
return 1;
}
Expand All @@ -3329,11 +3327,10 @@ int traverseIndirections(Type *ta, Type *tb, void *p = NULL, bool a2b = true)
};
Ctxt *ctxt = (Ctxt *)p;

Type *tbb = tb->toBasetype();
Type *tbb = tb->toBasetype()->baseElemOf();
if (tbb != tb)
return traverseIndirections(ta, tbb, ctxt, a2b);

tb = tb->baseElemOf();
if (tb->ty == Tclass || tb->ty == Tstruct)
{
for (Ctxt *c = ctxt; c; c = c->prev)
Expand All @@ -3347,11 +3344,6 @@ int traverseIndirections(Type *ta, Type *tb, void *p = NULL, bool a2b = true)
{
VarDeclaration *v = sym->fields[i];
Type *tprmi = v->type->addMod(tb->mod);
if (!(v->storage_class & STCref))
tprmi = getIndirection(tprmi);
if (!tprmi)
continue;

//printf("\ttb = %s, tprmi = %s\n", tb->toChars(), tprmi->toChars());
if (traverseIndirections(ta, tprmi, &c, a2b))
return 1;
Expand Down
15 changes: 15 additions & 0 deletions test/fail_compilation/fail11503c.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
struct Data
{
char[256] buffer;
@property const(char)[] filename() const pure nothrow
{
return buffer[];
}
}

void main()
{
Data d;
string f = d.filename;
d.buffer[0] = 'a';
}
22 changes: 22 additions & 0 deletions test/fail_compilation/fail11503d.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
struct Data2
{
char buffer;
}

@property const(char)[] filename(const ref Data2 d) pure nothrow
{
return (&d.buffer)[0 .. 1];
}

@property const(char)[] filename2(const Data2* d) pure nothrow
{
return (&d.buffer)[0 .. 1];
}

void main()
{
Data2 d;
string f = d.filename;
string g = (&d).filename2;
d.buffer = 'a';
}

0 comments on commit fa6898c

Please sign in to comment.