Merge pull request #3441 from kinke/fix_captured_nonpassed

Fix ICE for *captured* parameters *not* passed on the LLVM level
This commit is contained in:
Martin Kinkelin 2020-05-29 18:28:45 +02:00 committed by GitHub
commit 75f18b49ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 44 deletions

View file

@ -815,22 +815,24 @@ void defineParameters(IrFuncTy &irFty, VarDeclarations &parameters) {
size_t llArgIdx = 0;
for (VarDeclaration *vd : parameters) {
Type *paramType = vd->type;
IrParameter *irparam = getIrParameter(vd);
// vd->type (parameter) and irparam->arg->type (argument) don't always
// match.
// E.g., for a lazy parameter of type T, vd->type is T (with lazy storage
// class) while irparam->arg->type is the delegate type.
Type *const paramType = (irparam ? irparam->arg->type : vd->type);
if (!irparam) {
// This is a parameter that is not passed on the LLVM level.
// Create the param here and set it to a "dummy" alloca that
// we do not store to here.
irparam = getIrParameter(vd, true);
irparam->value = DtoAlloca(vd, vd->ident->toChars());
} else if (!irparam->value) {
// Captured parameter not passed on the LLVM level.
assert(irparam->nestedIndex >= 0);
irparam->value = DtoAlloca(vd, vd->ident->toChars());
} else {
assert(irparam->value);
// vd->type (parameter) and irparam->arg->type (argument) don't always
// match. E.g., for a lazy parameter of type T, vd->type is T (with lazy
// storage class) while irparam->arg->type is the delegate type.
paramType = irparam->arg->type;
if (irparam->arg->byref) {
// The argument is an appropriate lvalue passed by reference.