fix index bug in recursive decrements

This commit is contained in:
Folkert 2023-04-17 14:09:49 +02:00
parent e0b5a76a04
commit c848a85eb4
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
3 changed files with 54 additions and 6 deletions

View file

@ -1,6 +1,7 @@
#![allow(clippy::too_many_arguments)]
use bumpalo::collections::vec::Vec;
use bumpalo::collections::CollectIn;
use roc_module::low_level::{LowLevel, LowLevel::*};
use roc_module::symbol::{IdentIds, Symbol};
use roc_target::PtrWidth;
@ -1279,6 +1280,13 @@ fn refcount_union_contents<'a>(
// (Order is important, to avoid use-after-free for Dec)
let following = Stmt::Jump(jp_contents_modified, &[]);
let field_layouts = field_layouts
.iter()
.copied()
.enumerate()
.collect_in::<Vec<_>>(root.arena)
.into_bump_slice();
let fields_stmt = refcount_tag_fields(
root,
ident_ids,
@ -1503,7 +1511,7 @@ fn refcount_union_tailrec<'a>(
let mut tail_stmt = None;
for (i, field) in field_layouts.iter().enumerate() {
if i != tailrec_index {
filtered.push(*field);
filtered.push((i, *field));
} else {
let field_val =
root.create_symbol(ident_ids, &format!("field_{}_{}", tag_id, i));
@ -1537,7 +1545,14 @@ fn refcount_union_tailrec<'a>(
)),
));
(*field_layouts, tail_stmt)
let field_layouts = field_layouts
.iter()
.copied()
.enumerate()
.collect_in::<Vec<_>>(root.arena)
.into_bump_slice();
(field_layouts, tail_stmt)
};
let fields_stmt = refcount_tag_fields(
@ -1608,20 +1623,20 @@ fn refcount_tag_fields<'a>(
ctx: &mut Context<'a>,
layout_interner: &mut STLayoutInterner<'a>,
union_layout: UnionLayout<'a>,
field_layouts: &'a [InLayout<'a>],
field_layouts: &'a [(usize, InLayout<'a>)],
structure: Symbol,
tag_id: TagIdIntType,
following: Stmt<'a>,
) -> Stmt<'a> {
let mut stmt = following;
for (i, field_layout) in field_layouts.iter().enumerate().rev() {
for (i, field_layout) in field_layouts.iter().rev() {
if layout_interner.contains_refcounted(*field_layout) {
let field_val = root.create_symbol(ident_ids, &format!("field_{}_{}", tag_id, i));
let field_val_expr = Expr::UnionAtIndex {
union_layout,
tag_id,
index: i as u64,
index: *i as u64,
structure,
};
let field_val_stmt = |next| Stmt::Let(field_val, field_val_expr, *field_layout, next);

View file

@ -2661,7 +2661,10 @@ impl<'a> Layout<'a> {
Layout::RecursivePointer(_) => {
unreachable!("should be looked up to get an actual layout")
}
Layout::Boxed(inner) => Ord::max(ptr_width, interner.get(*inner).alignment_bytes(interner, target_info)),
Layout::Boxed(inner) => Ord::max(
ptr_width,
interner.get(*inner).alignment_bytes(interner, target_info),
),
}
}

View file

@ -496,3 +496,33 @@ fn boxed_str_dec() {
]
);
}
#[test]
#[cfg(any(feature = "gen-wasm"))]
fn non_nullable_unwrapped_alignment_8() {
assert_refcounts!(
indoc!(
r#"
Expr : [ZAdd Expr Expr, Val I64, Var I64]
eval : Expr -> I64
eval = \e ->
when e is
Var _ -> 0
Val v -> v
ZAdd l r -> eval l + eval r
expr : Expr
expr = (ZAdd (Val 4) (Val 5))
eval expr
"#
),
i64,
&[
Deallocated, // Val 4
Deallocated, // Val 5
Deallocated, // ZAdd _ _
]
);
}