diff --git a/gen/classes.cpp b/gen/classes.cpp index 0597b796..bbe4dcf7 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -1260,6 +1260,7 @@ LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl) { // sanity checks assert(fdecl->isVirtual()); + assert(!fdecl->isFinal()); assert(fdecl->vtblIndex > 0); // 0 is always ClassInfo/Interface* assert(inst->getType()->toBasetype()->ty == Tclass); diff --git a/gen/functions.cpp b/gen/functions.cpp index 3c695645..9e9065b3 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -628,13 +628,6 @@ void DtoDefineFunc(FuncDeclaration* fd) Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars()); LOG_SCOPE; - // error on naked - if (fd->naked) - { - fd->error("naked is not supported"); - fatal(); - } - // debug info if (global.params.symdebug) { Module* mo = fd->getModule(); diff --git a/gen/toir.cpp b/gen/toir.cpp index 8186d963..dd581f0c 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1970,7 +1970,7 @@ DValue* DelegateExp::toElem(IRState* p) Logger::println("func: '%s'", func->toPrettyChars()); LLValue* castfptr; - if (func->isVirtual()) + if (func->isVirtual() && !func->isFinal()) castfptr = DtoVirtualFunctionPointer(u, func); else if (func->isAbstract()) assert(0 && "TODO delegate to abstract method"); diff --git a/tests/mini/delegate3.d b/tests/mini/delegate3.d new file mode 100644 index 00000000..06c3d644 --- /dev/null +++ b/tests/mini/delegate3.d @@ -0,0 +1,18 @@ +module bar; + +class S +{ + int i; + final int foo() + { + return i; + } +} + +void main() +{ + auto s = new S; + s.i = 42; + auto dg = &s.foo; + assert(dg() == 42); +}