From 9970f45ecbd7f8f77bc5d8a81784f4f6442c5a52 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Sat, 25 Dec 2021 16:03:53 -0800 Subject: [PATCH 1/3] deprecation warning on use of out-of-scope local --- src/parse.y | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/parse.y b/src/parse.y index cf60ff58ac..ea3d617d7a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -142,6 +142,10 @@ bool resolving_global_ID = false; bool defining_global_ID = false; std::vector saved_in_init; +std::vector> locals_at_this_scope; +static std::unordered_set out_of_scope_locals; +static std::unordered_set warned_about_locals; + static Location func_hdr_location; static int func_hdr_cond_epoch = 0; EnumType* cur_enum_type = nullptr; @@ -557,6 +561,8 @@ expr: | TOK_LOCAL local_id '=' expr { set_location(@2, @4); + if ( ! locals_at_this_scope.empty() ) + locals_at_this_scope.back().insert($2); $$ = add_and_assign_local({AdoptRef{}, $2}, {AdoptRef{}, $4}, val_mgr->True()).release(); } @@ -797,6 +803,13 @@ expr: } else { + if ( out_of_scope_locals.count(id.get()) > 0 && + warned_about_locals.count(id.get()) == 0 ) + { + reporter->Warning("use of out-of-scope local %s deprecated; move declaration to outer scope", id->Name()); + warned_about_locals.insert(id.get()); + } + $$ = new NameExpr(std::move(id)); } } @@ -1298,6 +1311,10 @@ func_body: { saved_in_init.push_back(in_init); in_init = 0; + + locals_at_this_scope.clear(); + out_of_scope_locals.clear(); + warned_about_locals.clear(); } stmt_list @@ -1573,11 +1590,20 @@ attr: ; stmt: - '{' opt_no_test_block stmt_list '}' + '{' { - set_location(@1, @4); - $$ = $3; - if ( $2 ) + std::set id_set; + locals_at_this_scope.emplace_back(id_set); + } + opt_no_test_block stmt_list '}' + { + auto& scope_locals = locals_at_this_scope.back(); + out_of_scope_locals.insert(scope_locals.begin(), scope_locals.end()); + locals_at_this_scope.pop_back(); + + set_location(@1, @5); + $$ = $4; + if ( $3 ) script_coverage_mgr.DecIgnoreDepth(); } @@ -1684,6 +1710,8 @@ stmt: | TOK_LOCAL local_id opt_type init_class opt_init opt_attr ';' opt_no_test { set_location(@1, @7); + if ( ! locals_at_this_scope.empty() ) + locals_at_this_scope.back().insert($2); $$ = build_local($2, $3, $4, $5, $6, VAR_REGULAR, ! $8).release(); } From 38c6c8f073aa9c62e0e9df6e80e97e3328424bb8 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Sat, 25 Dec 2021 16:04:08 -0800 Subject: [PATCH 2/3] test suite update --- testing/btest/Baseline/language.uninitialized-local2/err | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/btest/Baseline/language.uninitialized-local2/err b/testing/btest/Baseline/language.uninitialized-local2/err index b7c6377f7b..ad64116f3d 100644 --- a/testing/btest/Baseline/language.uninitialized-local2/err +++ b/testing/btest/Baseline/language.uninitialized-local2/err @@ -1,2 +1,3 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +warning in <...>/uninitialized-local2.zeek, line 23: use of out-of-scope local var_b deprecated; move declaration to outer scope expression error in <...>/uninitialized-local2.zeek, line 23: value used but not set (var_b) From aee333cc6244c30f4473ad82728b5b33c070bbef Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Mon, 3 Jan 2022 11:24:18 -0800 Subject: [PATCH 3/3] added notice of deprecation to NEWS --- NEWS | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/NEWS b/NEWS index 06c03755ca..7be70ac69b 100644 --- a/NEWS +++ b/NEWS @@ -159,6 +159,27 @@ Deprecated Functionality replaced by ``analyzer_confirmation`` and ``analyzer_violation`` which can also now be implemented in packet analyzers. +- Declaring a local variable in an inner scope and then accessing it in an + outer scope is now deprecated. For example, + + if ( foo() ) + { + local a = 5; + ... + } + print a; + + is deprecated. You can address the issue by hoisting the declaration + to the outer scope, such as: + + local a: count; + if ( foo() ) + { + a = 5; + ... + } + print a; + Zeek 4.1.0 ==========