Skip to content

Commit

Permalink
fix issue 6549 - Implement contracts without implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ibuclaw committed Dec 26, 2017
1 parent 5c76d45 commit c7d0672
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 21 deletions.
19 changes: 12 additions & 7 deletions src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1570,8 +1570,7 @@ extern(C++) final class Semantic3Visitor : Visitor
}

// If declaration has no body, don't set sbody to prevent incorrect codegen.
InterfaceDeclaration id = funcdecl.parent.isInterfaceDeclaration();
if (funcdecl.fbody || id && (funcdecl.fdensure || funcdecl.fdrequire) && funcdecl.isVirtual())
if (funcdecl.fbody || funcdecl.fdensure || funcdecl.fdrequire)
funcdecl.fbody = sbody;
}

Expand Down Expand Up @@ -4409,11 +4408,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
funcdecl.error("destructors, postblits and invariants are not allowed in union %s", ud.toChars());
}

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

if (StructDeclaration sd = parent.isStructDeclaration())
{
if (funcdecl.isCtorDeclaration())
Expand Down Expand Up @@ -4786,6 +4780,17 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
// Reflect this.type to f because it could be changed by findVtblIndex
f = funcdecl.type.toTypeFunction();

/* Contracts can only appear without a body when they are virtual interface functions or abstract
*/
if (!funcdecl.fbody && !funcdecl.isAbstract() &&
(funcdecl.fensure || funcdecl.frequire) &&
!(id && funcdecl.isVirtual()))
{
auto cd = parent.isClassDeclaration();
if (!(cd && cd.isAbstract()))
funcdecl.error("in and out contracts on non-virtual/non-abstract functions require function body");
}

/* Do not allow template instances to add virtual functions
* to a class.
*/
Expand Down
14 changes: 0 additions & 14 deletions test/fail_compilation/fail12901.d

This file was deleted.

51 changes: 51 additions & 0 deletions test/runnable/testcontracts.d
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,56 @@ void test6417()
(new Bug6417).bar();
}

/*******************************************/
// 6549

class C6549
{
static int ocount = 0;
static int icount = 0;

abstract int foo(int)
in { ++icount; }
out { ++ocount; }
}

class CD6549 : C6549
{
override int foo(int)
in { assert(false); }
do { return 10; }
}

abstract class D6549
{
static int icount = 0;
static int ocount = 0;

int foo(int)
in { ++icount; }
out { ++ocount; }
}

class DD6549 : D6549
{
override int foo(int)
in { assert(false); }
do { return 10; }
}

void test6549()
{
auto c = new CD6549;
c.foo(10);
assert(C6549.icount == 1);
assert(C6549.ocount == 1);

auto d = new DD6549;
d.foo(10);
assert(D6549.icount == 1);
assert(D6549.ocount == 1);
}

/*******************************************/
// 7218

Expand Down Expand Up @@ -1043,6 +1093,7 @@ int main()
test9();
test4785();
test6417();
test6549();
test7218();
test7517();
test8073();
Expand Down

0 comments on commit c7d0672

Please sign in to comment.