From cce48c6cdd9484c606879ea76d4c633fce12ba36 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 25 Aug 2023 23:14:36 +0200 Subject: [PATCH] Filter: Add separate instruction for uninitialized variable declaration The previous approach (use VOID constant for variable initialization) failed due to dynamic type check failure. Thanks to Alexander Zubkov for the bugreport. --- filter/config.Y | 16 ++++++++-------- filter/f-inst.c | 12 ++++++++++++ filter/test.conf | 4 ++-- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/filter/config.Y b/filter/config.Y index 2a298843f..e02af182d 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -324,7 +324,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, %nonassoc ELSE %type cmds_int cmd_prep -%type term term_bs cmd cmd_var cmds cmds_scoped constant constructor print_list var var_init var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail +%type term term_bs cmd cmd_var cmds cmds_scoped constant constructor print_list var var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail %type dynamic_attr %type static_attr %type filter where_filter @@ -895,16 +895,16 @@ print_list: /* EMPTY */ { $$ = NULL; } } ; -var_init: - /* empty */ { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { }); } - | '=' term { $$ = $2; } - ; - var: - type symbol var_init ';' { + type symbol '=' term ';' { struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); - $$ = f_new_inst(FI_VAR_INIT, $3, sym); + $$ = f_new_inst(FI_VAR_INIT, $4, sym); } + | type symbol ';' { + struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); + $$ = f_new_inst(FI_VAR_INIT0, sym); + } + ; for_var: type symbol { $$ = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); } diff --git a/filter/f-inst.c b/filter/f-inst.c index 8a2f474e1..b63fc1f48 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -506,6 +506,7 @@ RESULT(T_BOOL, i, ipa_is_ip4(v1.val.ip)); } + /* Add initialized variable */ INST(FI_VAR_INIT, 1, 0) { NEVER_CONSTANT; ARG_ANY(1); @@ -518,6 +519,17 @@ fstk->vcnt = pos + 1; } + /* Add uninitialized variable */ + INST(FI_VAR_INIT0, 0, 0) { + NEVER_CONSTANT; + SYMBOL; + + /* New variable is always the last on stack */ + uint pos = curline.vbase + sym->offset; + fstk->vstk[pos] = (struct f_val) { }; + fstk->vcnt = pos + 1; + } + /* Set to indirect value prepared in v1 */ INST(FI_VAR_SET, 1, 0) { NEVER_CONSTANT; diff --git a/filter/test.conf b/filter/test.conf index c014dadd5..c74c26914 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -630,8 +630,8 @@ bt_test_suite(t_prefix_set, "Testing prefix sets"); */ function t_prefix6() -prefix px; { + prefix px; px = 1020::/18; bt_assert(format(px) = "1020::/18"); bt_assert(1020:3040:5060:: ~ 1020:3040:5000::/40); @@ -976,8 +976,8 @@ bt_test_suite(t_clist, "Testing lists of communities"); */ function t_ec() -ec cc; { + ec cc; cc = (rt, 12345, 200000); bt_assert(format(cc) = "(rt, 12345, 200000)"); -- 2.39.2