summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2023-08-25 23:14:36 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2023-08-25 23:14:36 +0200
commitcce48c6cdd9484c606879ea76d4c633fce12ba36 (patch)
treee5c0591e6464999dc06d291d5d026873312349a1
parent116285f2b000a4b78044f1bcf1eb1d6655f1d2fe (diff)
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 <green@qrator.net> for the bugreport.
-rw-r--r--filter/config.Y16
-rw-r--r--filter/f-inst.c12
-rw-r--r--filter/test.conf4
3 files changed, 22 insertions, 10 deletions
diff --git a/filter/config.Y b/filter/config.Y
index 2a298843..e02af182 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -324,7 +324,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
%nonassoc ELSE
%type <xp> cmds_int cmd_prep
-%type <x> 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 <x> 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 <fda> dynamic_attr
%type <fsa> static_attr
%type <f> 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 8a2f474e..b63fc1f4 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 c014dadd..c74c2691 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)");