Skip to content

Commit c5cae9e

Browse files
morganthomasTomWambsgans
authored andcommitted
check for wrong number of returned vars (#107)
* check for wrong number of returned vars in function calls * check for wrong number of returned vars in return statements
1 parent 990a95e commit c5cae9e

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

crates/lean_compiler/src/a_simplify_lang.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ pub fn simplify_program(mut program: Program) -> SimpleProgram {
158158
for (name, func) in &program.functions {
159159
let mut array_manager = ArrayManager::default();
160160
let simplified_instructions = simplify_lines(
161+
&program.functions,
162+
func.n_returned_vars,
161163
&func.body,
162164
&mut counters,
163165
&mut new_functions,
@@ -430,7 +432,10 @@ impl ArrayManager {
430432
}
431433
}
432434

435+
#[allow(clippy::too_many_arguments)]
433436
fn simplify_lines(
437+
functions: &BTreeMap<String, Function>,
438+
n_returned_vars: usize,
434439
lines: &[Line],
435440
counters: &mut Counters,
436441
new_functions: &mut BTreeMap<String, SimpleFunction>,
@@ -450,6 +455,8 @@ fn simplify_lines(
450455
for (i, (pattern, statements)) in arms.iter().enumerate() {
451456
assert_eq!(*pattern, i, "match patterns should be consecutive, starting from 0");
452457
simple_arms.push(simplify_lines(
458+
functions,
459+
n_returned_vars,
453460
statements,
454461
counters,
455462
new_functions,
@@ -601,6 +608,8 @@ fn simplify_lines(
601608

602609
let mut array_manager_then = array_manager.clone();
603610
let then_branch_simplified = simplify_lines(
611+
functions,
612+
n_returned_vars,
604613
then_branch,
605614
counters,
606615
new_functions,
@@ -612,6 +621,8 @@ fn simplify_lines(
612621
array_manager_else.valid = array_manager.valid.clone(); // Crucial: remove the access added in the IF branch
613622

614623
let else_branch_simplified = simplify_lines(
624+
functions,
625+
n_returned_vars,
615626
else_branch,
616627
counters,
617628
new_functions,
@@ -661,6 +672,8 @@ fn simplify_lines(
661672
let mut body_copy = body.clone();
662673
replace_vars_for_unroll(&mut body_copy, iterator, unroll_index, i, &internal_variables);
663674
unrolled_lines.extend(simplify_lines(
675+
functions,
676+
0,
664677
&body_copy,
665678
counters,
666679
new_functions,
@@ -684,6 +697,8 @@ fn simplify_lines(
684697
let valid_aux_vars_in_array_manager_before = array_manager.valid.clone();
685698
array_manager.valid.clear();
686699
let simplified_body = simplify_lines(
700+
functions,
701+
0,
687702
body,
688703
counters,
689704
new_functions,
@@ -758,6 +773,16 @@ fn simplify_lines(
758773
return_data,
759774
line_number,
760775
} => {
776+
let function = functions
777+
.get(function_name)
778+
.expect("Function used but not defined: {function_name}");
779+
if return_data.len() != function.n_returned_vars {
780+
panic!(
781+
"Expected {} returned vars in call to {function_name}",
782+
function.n_returned_vars
783+
);
784+
}
785+
761786
let simplified_args = args
762787
.iter()
763788
.map(|arg| simplify_expr(arg, &mut res, counters, array_manager, const_malloc))
@@ -771,6 +796,11 @@ fn simplify_lines(
771796
}
772797
Line::FunctionRet { return_data } => {
773798
assert!(!in_a_loop, "Function return inside a loop is not currently supported");
799+
assert!(
800+
return_data.len() == n_returned_vars,
801+
"Wrong number of return values in return statement; expected {n_returned_vars} but got {}",
802+
return_data.len()
803+
);
774804
let simplified_return_data = return_data
775805
.iter()
776806
.map(|ret| simplify_expr(ret, &mut res, counters, array_manager, const_malloc))

crates/lean_compiler/tests/test_compiler.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,36 @@ fn test_duplicate_constant_name() {
3636
compile_and_run(program.to_string(), (&[], &[]), false);
3737
}
3838

39+
#[test]
40+
#[should_panic]
41+
fn test_wrong_n_returned_vars_1() {
42+
let program = r#"
43+
fn main() {
44+
a, b = f();
45+
}
46+
47+
fn f() -> 1 {
48+
return 0;
49+
}
50+
"#;
51+
compile_and_run(program.to_string(), (&[], &[]), DEFAULT_NO_VEC_RUNTIME_MEMORY, false);
52+
}
53+
54+
#[test]
55+
#[should_panic]
56+
fn test_wrong_n_returned_vars_2() {
57+
let program = r#"
58+
fn main() {
59+
a = f();
60+
}
61+
62+
fn f() -> 1 {
63+
return 0, 1;
64+
}
65+
"#;
66+
compile_and_run(program.to_string(), (&[], &[]), DEFAULT_NO_VEC_RUNTIME_MEMORY, false);
67+
}
68+
3969
#[test]
4070
fn test_fibonacci_program() {
4171
// a program to check the value of the 30th Fibonacci number (832040)

0 commit comments

Comments
 (0)