compiler: Check aggregate return classification

63b266a538584fff5c4de9a86a0e10daee3e5e0087bb34a26438429e59fb0dcd
Alexis Sellier committed ago 1 parent 7a69753c
lib/std/lang/lower.rad +16 -7
4388 4388
    }
4389 4389
}
4390 4390
4391 4391
/// Check if a resolver type is a small aggregate that can be
4392 4392
/// passed or returned by value in a register.
4393 -
unsafe fn isSmallAggregate(typ: resolver::Type) -> bool {
4393 +
fn isSmallAggregate(typ: resolver::Type) -> bool {
4394 4394
    match typ {
4395 -
        case resolver::Type::Nominal(_) => {
4396 -
            if resolver::isVoidUnion(typ) {
4397 -
                return false;
4395 +
        case resolver::Type::Nominal(info) => {
4396 +
            unsafe {
4397 +
                return nominalFitsRegister(*info);
4398 4398
            }
4399 -
            let layout = resolver::getTypeLayout(typ);
4400 -
            return layout.size <= resolver::PTR_SIZE;
4401 4399
        }
4402 4400
        else => return false,
4403 4401
    }
4404 4402
}
4405 4403
4404 +
/// Check whether a nominal aggregate uses one register for its value.
4405 +
fn nominalFitsRegister(info: resolver::NominalType) -> bool {
4406 +
    if let case resolver::NominalType::Union(unionInfo) = info {
4407 +
        if unionInfo.isAllVoid {
4408 +
            return false;
4409 +
        }
4410 +
    }
4411 +
    let layout = resolver::getNominalLayout(info);
4412 +
    return layout.size <= resolver::PTR_SIZE;
4413 +
}
4414 +
4406 4415
/// Whether a function needs a hidden return parameter.
4407 4416
///
4408 4417
/// This is the case for throwing functions, which return a result aggregate,
4409 4418
/// and for functions returning large aggregates that cannot be passed in
4410 4419
/// registers.
4411 -
unsafe fn requiresReturnParam(fnType: *resolver::FnType) -> bool {
4420 +
fn requiresReturnParam(fnType: *resolver::FnType) -> bool {
4412 4421
    return fnType.throwList.len > 0
4413 4422
        or (isAggregateType(*fnType.returnType)
4414 4423
        and not isSmallAggregate(*fnType.returnType));
4415 4424
}
4416 4425