1
0
mirror of https://gitlab.labs.nic.cz/labs/bird.git synced 2024-05-11 16:54:54 +00:00

Filter: Change linearization of branches in switch instruction

Most branching instructions (FI_CONDITION, FI_AND, FI_OR) linearize its
branches in a recursive way, while FI_SWITCH branches are linearized
from parser even before the switch instruction is allocated.

Change linearization of FI_SWITCH branches to make it similar to other
branching instructions. This also fixes an issue with constant
switch evaluation, where linearized branch is mistaken for
non-linearized during switch construction.

Thanks to Jiten Kumar Pathy for the bugreport.
This commit is contained in:
Ondrej Zajicek
2023-01-07 20:18:44 +01:00
parent d1cd5e5a63
commit e20bef69cc
4 changed files with 46 additions and 7 deletions

View File

@@ -1285,14 +1285,33 @@
FID_MEMBER(struct f_tree *, tree, [[!same_tree(f1->tree, f2->tree)]], "tree %p", item->tree);
FID_LINEARIZE_BODY()
/* Linearize all branches in switch */
struct f_inst *last_inst = NULL;
struct f_line *last_line = NULL;
for (struct f_tree *t = whati->tree; t; t = t->left)
{
if (t->data != last_inst)
{
last_inst = t->data;
last_line = f_linearize(t->data, 0);
}
t->data = last_line;
}
/* Balance the tree */
item->tree = build_tree(whati->tree);
FID_ITERATE_BODY()
tree_walk(whati->tree, f_add_tree_lines, fit);
tree_walk(whati->tree, f_add_tree_lines, fit);
FID_INTERPRET_BODY()
const struct f_tree *t = find_tree(tree, &v1);
/* In parse-time use find_tree_linear(), in runtime use find_tree() */
const struct f_tree *t = FID_HIC(,find_tree,find_tree_linear)(tree, &v1);
if (!t) {
v1.type = T_VOID;
t = find_tree(tree, &v1);
t = FID_HIC(,find_tree,find_tree_linear)(tree, &v1);
if (!t) {
debug( "No else statement?\n");
FID_HIC(,break,return NULL);