Skip to content

Commit

Permalink
add contracts for interface functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Walter Bright committed Feb 1, 2010
1 parent 81c8c77 commit b0c8015
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 15 deletions.
15 changes: 11 additions & 4 deletions src/func.c
Expand Up @@ -320,6 +320,11 @@ void FuncDeclaration::semantic(Scope *sc)
error("function body is not abstract in interface %s", id->toChars());
}

/* Contracts can only appear without a body when they are virtual interface functions
*/
if (!fbody && (fensure || frequire) && !(id && isVirtual()))
error("in and out contracts require function body");

/* Template member functions aren't virtual:
* interface TestInterface { void tpl(T)(); }
* and so won't work in interfaces
Expand Down Expand Up @@ -700,15 +705,15 @@ void FuncDeclaration::semantic(Scope *sc)
fdrequire = fd;
}

if (!outId && f->nextOf() && f->nextOf()->toBasetype()->ty != Tvoid)
outId = Id::result; // provide a default

if (fensure)
{ /* out (result) { ... }
* becomes:
* tret __ensure(ref tret result) { ... }
* __ensure(result);
*/
if (!outId && f->nextOf()->toBasetype()->ty != Tvoid)
outId = Id::result; // provide a default

Loc loc = fensure->loc;
Parameters *arguments = new Parameters();
Parameter *a = NULL;
Expand Down Expand Up @@ -784,6 +789,7 @@ void FuncDeclaration::semantic3(Scope *sc)
return;
f = (TypeFunction *)(type);

#if 0
// Check the 'throws' clause
if (fthrows)
{
Expand All @@ -796,11 +802,12 @@ void FuncDeclaration::semantic3(Scope *sc)
error("can only throw classes, not %s", t->toChars());
}
}
#endif

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

if (fbody || frequire)
if (fbody || frequire || fensure)
{
/* Symbol table into which we place parameters and nested functions,
* solely to diagnose name collisions.
Expand Down
6 changes: 2 additions & 4 deletions src/glue.c
Expand Up @@ -516,8 +516,6 @@ void Module::genobjfile(int multiobj)

void FuncDeclaration::toObjFile(int multiobj)
{
Symbol *s;
func_t *f;
Symbol *senter;
Symbol *sexit;
FuncDeclaration *func = this;
Expand Down Expand Up @@ -559,8 +557,8 @@ void FuncDeclaration::toObjFile(int multiobj)
if (global.params.verbose)
printf("function %s\n",func->toChars());

s = func->toSymbol();
f = s->Sfunc;
Symbol *s = func->toSymbol();
func_t *f = s->Sfunc;

#if TARGET_WINDOS
/* This is done so that the 'this' pointer on the stack is the same
Expand Down
2 changes: 1 addition & 1 deletion src/mars.c
Expand Up @@ -169,7 +169,7 @@ void verror(Loc loc, const char *format, va_list ap)
#endif
fprintf(stdmsg, "\n");
fflush(stdmsg);
//halt();
halt();
}
global.errors++;
}
Expand Down
3 changes: 2 additions & 1 deletion src/parse.c
Expand Up @@ -3108,7 +3108,8 @@ void Parser::parseContracts(FuncDeclaration *f)
goto L1;

default:
error("semicolon expected following function declaration");
if (!f->frequire && !f->fensure) // allow these even with no body
error("semicolon expected following function declaration");
break;
}
linkage = linksave;
Expand Down
7 changes: 2 additions & 5 deletions src/toobj.c
Expand Up @@ -922,12 +922,9 @@ void InterfaceDeclaration::toObjFile(int multiobj)

// Put out the members
for (i = 0; i < members->dim; i++)
{
Dsymbol *member;
{ Dsymbol *member = (Dsymbol *)members->data[i];

member = (Dsymbol *)members->data[i];
if (!member->isFuncDeclaration())
member->toObjFile(0);
member->toObjFile(0);
}

// Generate C symbols
Expand Down

0 comments on commit b0c8015

Please sign in to comment.