From 2bf3390cbb3acc6b761f1d9a44d304003c0a1dbb Mon Sep 17 00:00:00 2001 From: Christoph Burgdorf Date: Fri, 13 Nov 2020 11:11:15 +0100 Subject: [PATCH] Ensure blocks in if/else + while are semantically checked --- compiler/tests/evm_contracts.rs | 1 + semantics/src/traversal/functions.rs | 28 +++++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/compiler/tests/evm_contracts.rs b/compiler/tests/evm_contracts.rs index 2c1f255a26..604cd75a8e 100644 --- a/compiler/tests/evm_contracts.rs +++ b/compiler/tests/evm_contracts.rs @@ -249,6 +249,7 @@ fn test_assert() { case("if_statement.fe", vec![6], Some(u256_token(1))), case("if_statement.fe", vec![4], Some(u256_token(0))), case("if_statement_2.fe", vec![6], Some(u256_token(1))), + case("if_statement_with_block_declaration.fe", vec![], Some(u256_token(1))), case("call_statement_without_args.fe", vec![], Some(u256_token(100))), case("call_statement_with_args.fe", vec![], Some(u256_token(100))), case("call_statement_with_args_2.fe", vec![], Some(u256_token(100))), diff --git a/semantics/src/traversal/functions.rs b/semantics/src/traversal/functions.rs index 1e3788718c..6d17789039 100644 --- a/semantics/src/traversal/functions.rs +++ b/semantics/src/traversal/functions.rs @@ -83,9 +83,7 @@ pub fn func_def( context.borrow_mut().add_function(def, attributes); - for stmt in body.iter() { - func_stmt(Rc::clone(&function_scope), Rc::clone(&context), stmt)? - } + traverse_statements(function_scope.clone(), context, body)?; return Ok(()); } @@ -93,6 +91,17 @@ pub fn func_def( unreachable!() } +fn traverse_statements( + scope: Shared, + context: Shared, + body: &[Spanned], +) -> Result<(), SemanticError> { + for stmt in body.iter() { + func_stmt(Rc::clone(&scope), Rc::clone(&context), stmt)? + } + Ok(()) +} + fn validate_all_paths_return_or_revert( block: &[Spanned], ) -> Result<(), SemanticError> { @@ -183,9 +192,13 @@ fn if_statement( match &stmt.node { fe::FuncStmt::If { test, - body: _, - or_else: _, - } => verify_is_boolean(scope, context, test), + body, + or_else, + } => { + traverse_statements(scope.clone(), context.clone(), body)?; + traverse_statements(scope.clone(), context.clone(), or_else)?; + verify_is_boolean(scope, context, test) + } _ => unreachable!(), } } @@ -198,12 +211,13 @@ fn while_loop( match &stmt.node { fe::FuncStmt::While { test, - body: _, + body, or_else, } => { if !or_else.is_empty() { unimplemented!(); } + traverse_statements(scope.clone(), context.clone(), body)?; verify_is_boolean(scope, context, test) } _ => unreachable!(),