]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Add separate instruction for uninitialized variable declaration
authorOndrej Zajicek <santiago@crfreenet.org>
Fri, 25 Aug 2023 21:14:36 +0000 (23:14 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Fri, 25 Aug 2023 21:14:36 +0000 (23:14 +0200)
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.

filter/config.Y
filter/f-inst.c
filter/test.conf

index 2a298843fd192a302f21267585c3b37d6b13a910..e02af182db3f8ff5da9e1e7c3c240a4936c4c72d 100644 (file)
@@ -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)); }
index 8a2f474e1a46aaa40c61c1e3b43ab36cc6d3c29a..b63fc1f48b1d33d6c6abaacb8fbb6d9675bf192a 100644 (file)
     RESULT(T_BOOL, i, ipa_is_ip4(v1.val.ip));
   }
 
+  /* Add initialized variable */
   INST(FI_VAR_INIT, 1, 0) {
     NEVER_CONSTANT;
     ARG_ANY(1);
     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;
index c014dadd52c872b95c4e1de0181e9ad0897c5647..c74c269143faf0bcca30243fe0c6380f29c04dc4 100644 (file)
@@ -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)");