Fix double padding bug in lowering
19dc94b65115723934b1308cb2052ff8f2a21b9e23c3c233024f8191906dddd5
We were in some cases padding items twice due to the fall-through.
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; |