Fix double padding bug in lowering

19dc94b65115723934b1308cb2052ff8f2a21b9e23c3c233024f8191906dddd5
We were in some cases padding items twice due to the fall-through.
Alexis Sellier committed ago 1 parent 85c59be1
lib/std/lang/lower.rad +19 -14
1334 1334
        set dataName = try pushDeclData(self, layout.size, layout.alignment, readOnly, backing.values, dataPrefix);
1335 1335
    }
1336 1336
    dataSliceHeader(b, dataName, arrInfo.length);
1337 1337
}
1338 1338
1339 -
/// Lower a constant expression into a builder, padding to slotSize.
1340 -
fn lowerConstDataInto(
1339 +
/// Lower a constant expression payload into a builder without slot padding.
1340 +
fn lowerConstDataPayloadInto(
1341 1341
    self: *mut Lowerer,
1342 1342
    node: *ast::Node,
1343 1343
    ty: resolver::Type,
1344 -
    slotSize: u32,
1345 1344
    dataPrefix: *[u8],
1346 1345
    b: *mut DataValueBuilder
1347 1346
) throws (LowerError) {
1348 -
    let layout = resolver::getTypeLayout(ty);
1349 -
1350 1347
    // Function pointer references in constant data.
1351 1348
    if let case resolver::Type::Fn(_) = ty {
1352 1349
        let sym = resolver::nodeData(self.resolver, node).sym
1353 1350
            else throw LowerError::MissingSymbol(node);
1354 1351
        let modId = resolver::moduleIdForSymbol(self.resolver, sym);
1355 1352
        let qualName = qualifyName(self, modId, sym.name);
1356 1353
        dataBuilderPush(b, il::DataValue {
1357 1354
            item: il::DataItem::Fn(qualName), count: 1,
1358 1355
        });
1359 -
        let pad = slotSize - layout.size;
1360 -
        if pad > 0 {
1361 -
            dataBuilderPush(b, il::DataValue {
1362 -
                item: il::DataItem::Undef, count: pad,
1363 -
            });
1364 -
        }
1365 1356
        return;
1366 1357
    }
1358 +
    let layout = resolver::getTypeLayout(ty);
1367 1359
1368 1360
    match node.value {
1369 1361
        case ast::NodeValue::Undef => {
1370 1362
            dataBuilderPush(b, il::DataValue {
1371 1363
                item: il::DataItem::Undef,
1398 1390
            let sym = resolver::nodeData(self.resolver, node).sym
1399 1391
                else throw LowerError::MissingSymbol(node);
1400 1392
            let case ast::NodeValue::ConstDecl(decl) = sym.node.value
1401 1393
                else throw LowerError::MissingConst(node);
1402 1394
1403 -
            try lowerConstDataInto(self, decl.value, ty, slotSize, dataPrefix, b);
1395 +
            try lowerConstDataPayloadInto(self, decl.value, ty, dataPrefix, b);
1404 1396
        },
1405 1397
        case ast::NodeValue::ScopeAccess(_) => {
1406 1398
            let sym = resolver::nodeData(self.resolver, node).sym
1407 1399
                else throw LowerError::MissingSymbol(node);
1408 1400
            if let case ast::NodeValue::ConstDecl(decl) = sym.node.value {
1409 -
                try lowerConstDataInto(self, decl.value, ty, slotSize, dataPrefix, b);
1401 +
                try lowerConstDataPayloadInto(self, decl.value, ty, dataPrefix, b);
1410 1402
            } else {
1411 1403
                try lowerConstScalarDataInto(self, node, ty, dataPrefix, b);
1412 1404
            }
1413 1405
        }
1414 1406
        else => {
1415 1407
            // Scalar values: integers, bools, strings, void union variants, etc.
1416 1408
            try lowerConstScalarDataInto(self, node, ty, dataPrefix, b);
1417 1409
        }
1418 1410
    }
1419 -
    // Pad to fill the slot.
1411 +
}
1412 +
1413 +
/// Lower a constant expression into a builder, padding to the given slot size.
1414 +
fn lowerConstDataInto(
1415 +
    self: *mut Lowerer,
1416 +
    node: *ast::Node,
1417 +
    ty: resolver::Type,
1418 +
    slotSize: u32,
1419 +
    dataPrefix: *[u8],
1420 +
    b: *mut DataValueBuilder
1421 +
) throws (LowerError) {
1422 +
    let layout = resolver::getTypeLayout(ty);
1423 +
    try lowerConstDataPayloadInto(self, node, ty, dataPrefix, b);
1424 +
    // Pad to fill the enclosing slot.
1420 1425
    let padding = slotSize - layout.size;
1421 1426
    if padding > 0 {
1422 1427
        dataBuilderPush(b, il::DataValue { item: il::DataItem::Undef, count: padding });
1423 1428
    }
1424 1429
}
test/tests/lower.const.record.ident.ril +0 -2
18 18
    sym $ENTRIES$literal$2;
19 19
    w32 2;
20 20
    w32 2;
21 21
    w8 10;
22 22
    undef * 7;
23 -
    undef * 7;
24 23
    sym $ENTRIES$literal$3;
25 24
    w32 2;
26 25
    w32 2;
27 26
    w8 11;
28 27
    undef * 7;
29 -
    undef * 7;
30 28
}
31 29
32 30
fn w32 $main() {
33 31
  @entry0
34 32
    ret 2;