diff --git a/dmd2/expression.c b/dmd2/expression.c index 5062f139c2..1038a37869 100644 --- a/dmd2/expression.c +++ b/dmd2/expression.c @@ -5197,6 +5197,11 @@ Expression *FuncExp::inferType(Scope *sc, Type *to) sc = scope; } +#if IN_LLVM + if (fd->tok == TOKreserved && to->ty == Tpointer && to->nextOf()->ty == Tfunction) + fd->tok = TOKfunction; +#endif + Expression *e = NULL; if (td) { /// Parameter types inference from diff --git a/dmd2/mtype.c b/dmd2/mtype.c index abff3d408e..96c705724b 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -5306,6 +5306,15 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) buf->writeByte('M'); ad->type->toDecoBuffer(buf, 0, false); } + if (FuncLiteralDeclaration *literal = funcdecl->isFuncLiteralDeclaration()) { + // Never merge types of function literals of different kind + if (literal->tok == TOKreserved) + buf->writeByte('L'); + else if (literal->tok == TOKfunction) + buf->writeByte('F'); + else if (literal->tok == TOKdelegate) + buf->writeByte('D'); + } /* BUG This causes problems with delegate types On the other hand, the llvm type for nested functions *is* different so not doing anything here may be lead to bugs! diff --git a/gen/toir.cpp b/gen/toir.cpp index b8c359d6f5..f327616a5a 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2636,10 +2636,7 @@ DValue* FuncExp::toElem(IRState* p) fd->codegen(Type::sir); assert(fd->ir.irFunc->func); - if (fd->tok == TOKreserved && type->ty == Tpointer && fd->vthis) - fd->tok = TOKfunction; - - if(fd->isNested()) { + if(fd->isNested() && !(fd->tok == TOKreserved && type->ty == Tpointer && fd->vthis)) { LLType* dgty = DtoType(type); LLValue* cval; @@ -2689,9 +2686,9 @@ LLConstant* FuncExp::toConstElem(IRState* p) LOG_SCOPE; assert(fd); - if (fd->tok != TOKfunction) + if (fd->tok != TOKfunction && !(fd->tok == TOKreserved && type->ty == Tpointer && fd->vthis)) { - assert(fd->tok == TOKdelegate); + assert(fd->tok == TOKdelegate || fd->tok == TOKreserved); error("delegate literals as constant expressions are not yet allowed"); return 0; }