Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix issue 7883 - Compiler segfaults with double inheritance and function contract #2379

Merged
merged 1 commit into from Jul 26, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/declaration.h
Expand Up @@ -721,7 +721,7 @@ class FuncDeclaration : public Declaration
bool hasNestedFrameRefs();
void buildResultVar();
Statement *mergeFrequire(Statement *);
Statement *mergeFensure(Statement *);
Statement *mergeFensure(Statement *, Identifier *oid);
Parameters *getParameters(int *pvarargs);

static FuncDeclaration *genCfunc(Type *treturn, const char *name);
Expand Down
10 changes: 5 additions & 5 deletions src/func.c
Expand Up @@ -970,7 +970,7 @@ void FuncDeclaration::semantic3(Scope *sc)
}

frequire = mergeFrequire(frequire);
fensure = mergeFensure(fensure);
fensure = mergeFensure(fensure, outId);

if (fbody || frequire || fensure)
{
Expand Down Expand Up @@ -2152,7 +2152,7 @@ Statement *FuncDeclaration::mergeFrequire(Statement *sf)
* 'out's are AND'd together, i.e. all of them need to pass.
*/

Statement *FuncDeclaration::mergeFensure(Statement *sf)
Statement *FuncDeclaration::mergeFensure(Statement *sf, Identifier *oid)
{
/* Same comments as for mergeFrequire(), except that we take care
* of generating a consistent reference to the 'result' local by
Expand All @@ -2179,15 +2179,15 @@ Statement *FuncDeclaration::mergeFensure(Statement *sf)
sc->pop();
}

sf = fdv->mergeFensure(sf);
sf = fdv->mergeFensure(sf, oid);
if (fdv->fdensure)
{
//printf("fdv->fensure: %s\n", fdv->fensure->toChars());
// Make the call: __ensure(result)
Expression *eresult = NULL;
if (outId)
{
eresult = new IdentifierExp(loc, outId);
eresult = new IdentifierExp(loc, oid);

Type *t1 = fdv->type->nextOf()->toBasetype();
Type *t2 = this->type->nextOf()->toBasetype();
Expand All @@ -2209,7 +2209,7 @@ Statement *FuncDeclaration::mergeFensure(Statement *sf)

if (sf)
{
sf = new CompoundStatement(fensure->loc, s2, sf);
sf = new CompoundStatement(sf->loc, s2, sf);
}
else
sf = s2;
Expand Down
76 changes: 76 additions & 0 deletions test/runnable/testcontracts.d
Expand Up @@ -381,6 +381,82 @@ class D7699 : P7699
override void f(int n) in { } body { }
}

/*******************************************/
// 7883

// Segmentation fault
class AA7883
{
int foo()
out (r1) { }
body { return 1; }
}

class BA7883 : AA7883
{
override int foo()
out (r2) { }
body { return 1; }
}

class CA7883 : BA7883
{
override int foo()
body { return 1; }
}

// Error: undefined identifier r2, did you mean variable r3?
class AB7883
{
int foo()
out (r1) { }
body { return 1; }
}

class BB7883 : AB7883
{
override int foo()
out (r2) { }
body { return 1; }

}

class CB7883 : BB7883
{
override int foo()
out (r3) { }
body { return 1; }
}

// Error: undefined identifier r3, did you mean variable r4?
class AC7883
{
int foo()
out (r1) { }
body { return 1; }
}

class BC7883 : AC7883
{
override int foo()
out (r2) { }
body { return 1; }
}

class CC7883 : BC7883
{
override int foo()
out (r3) { }
body { return 1; }
}

class DC7883 : CC7883
{
override int foo()
out (r4) { }
body { return 1; }
}

/*******************************************/
// 8066

Expand Down