@@ -470,6 +470,20 @@ impl<'a> Linearizer<'a> {
470470 false
471471 }
472472
473+ /// Link current block to merge block if not terminated.
474+ /// Used after linearizing then/else branches to connect to merge block.
475+ fn link_to_merge_if_needed ( & mut self , merge_bb : BasicBlockId ) {
476+ if self . is_terminated ( ) {
477+ return ;
478+ }
479+ if let Some ( current) = self . current_bb {
480+ // If the block isn't terminated, it needs a branch to the merge block.
481+ // Any unreachable blocks will be cleaned up by dead code elimination.
482+ self . emit ( Instruction :: br ( merge_bb) ) ;
483+ self . link_bb ( current, merge_bb) ;
484+ }
485+ }
486+
473487 /// Link two basic blocks (parent -> child)
474488 fn link_bb ( & mut self , from : BasicBlockId , to : BasicBlockId ) {
475489 let func = self . current_func . as_mut ( ) . unwrap ( ) ;
@@ -1747,50 +1761,13 @@ impl<'a> Linearizer<'a> {
17471761 // Then block
17481762 self . switch_bb ( then_bb) ;
17491763 self . linearize_stmt ( then_stmt) ;
1750- if !self . is_terminated ( ) {
1751- // After linearize_stmt, current_bb may be different from then_bb
1752- // (e.g., if then_stmt contains nested control flow). Link the
1753- // CURRENT block to merge_bb, but only if it's reachable.
1754- if let Some ( current) = self . current_bb {
1755- // A block is reachable if it's the original block we switched to
1756- // (which has an incoming edge from the condition), or if it has
1757- // any parents from previous links.
1758- let is_reachable = current == then_bb
1759- || self
1760- . current_func
1761- . as_ref ( )
1762- . and_then ( |f| f. get_block ( current) )
1763- . map ( |bb| !bb. parents . is_empty ( ) )
1764- . unwrap_or ( false ) ;
1765- if is_reachable {
1766- self . emit ( Instruction :: br ( merge_bb) ) ;
1767- self . link_bb ( current, merge_bb) ;
1768- }
1769- }
1770- }
1764+ self . link_to_merge_if_needed ( merge_bb) ;
17711765
17721766 // Else block
17731767 if let Some ( else_s) = else_stmt {
17741768 self . switch_bb ( else_bb) ;
17751769 self . linearize_stmt ( else_s) ;
1776- if !self . is_terminated ( ) {
1777- // After linearize_stmt, current_bb may be different from else_bb
1778- // (e.g., if else_stmt is a nested if-else chain). Link the
1779- // CURRENT block to merge_bb, but only if it's reachable.
1780- if let Some ( current) = self . current_bb {
1781- let is_reachable = current == else_bb
1782- || self
1783- . current_func
1784- . as_ref ( )
1785- . and_then ( |f| f. get_block ( current) )
1786- . map ( |bb| !bb. parents . is_empty ( ) )
1787- . unwrap_or ( false ) ;
1788- if is_reachable {
1789- self . emit ( Instruction :: br ( merge_bb) ) ;
1790- self . link_bb ( current, merge_bb) ;
1791- }
1792- }
1793- }
1770+ self . link_to_merge_if_needed ( merge_bb) ;
17941771 }
17951772
17961773 // Merge block
@@ -4472,20 +4449,22 @@ impl<'a> Linearizer<'a> {
44724449 OffsetOfPath :: Field ( field_id) => {
44734450 // Look up the field in the current struct type
44744451 let struct_type = self . resolve_struct_type ( current_type) ;
4475- if let Some ( member_info) =
4476- self . types . find_member ( struct_type , * field_id )
4477- {
4478- offset += member_info . offset as u64 ;
4479- current_type = member_info. typ ;
4480- }
4452+ let member_info = self
4453+ . types
4454+ . find_member ( struct_type , * field_id )
4455+ . expect ( "offsetof: field not found in struct type" ) ;
4456+ offset + = member_info. offset as u64 ;
4457+ current_type = member_info . typ ;
44814458 }
44824459 OffsetOfPath :: Index ( index) => {
44834460 // Array indexing: offset += index * sizeof(element)
4484- if let Some ( elem_type) = self . types . base_type ( current_type) {
4485- let elem_size = self . types . size_bytes ( elem_type) ;
4486- offset += ( * index as u64 ) * ( elem_size as u64 ) ;
4487- current_type = elem_type;
4488- }
4461+ let elem_type = self
4462+ . types
4463+ . base_type ( current_type)
4464+ . expect ( "offsetof: array index on non-array type" ) ;
4465+ let elem_size = self . types . size_bytes ( elem_type) ;
4466+ offset += ( * index as u64 ) * ( elem_size as u64 ) ;
4467+ current_type = elem_type;
44894468 }
44904469 }
44914470 }
0 commit comments