mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 09:38:19 +00:00
Fix memory leak in vector slice assignment
Two parts to this: * Only allow vector slice assignment in statement contexts, not in arbitrary assignment expressions. E.g. it's not clear what the resulting value of `(v[1:2] = vector(1))` is for further expression chaining. For reference, Python doesn't allow it either. * Add a subclass of AssignExpr to specialize the behavior for index slice assignments (because its behavior regarding expression chaining is different per the previous point) and Unref the RHS of things like `v[1:2] = vector(1)` after IndexExpr::Assign is finished inserting it (since no one else takes ownership of it). Instead of using an Expr subclass, IndexSliceAssignExpr, we could use a proper Stmt, since that's the only context we currently use it for, but if we did ever to decide on allowing its use in arbitrary expression contexts, then I expect we'll need it this way anyway (just with a different IndexSliceAssignExpr::Eval implementation).
This commit is contained in:
parent
91835752b7
commit
385f500497
5 changed files with 140 additions and 21 deletions
48
src/parse.y
48
src/parse.y
|
@ -5,7 +5,7 @@
|
|||
// Switching parser table type fixes ambiguity problems.
|
||||
%define lr.type ielr
|
||||
|
||||
%expect 103
|
||||
%expect 104
|
||||
|
||||
%token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ANY
|
||||
%token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF
|
||||
|
@ -57,7 +57,7 @@
|
|||
%type <ic> init_class
|
||||
%type <expr> opt_init
|
||||
%type <val> TOK_CONSTANT
|
||||
%type <expr> expr opt_expr init anonymous_function
|
||||
%type <expr> expr opt_expr init anonymous_function index_slice
|
||||
%type <event_expr> event
|
||||
%type <stmt> stmt stmt_list func_body for_head
|
||||
%type <type> type opt_type enum_body
|
||||
|
@ -464,6 +464,12 @@ expr:
|
|||
| expr '=' expr
|
||||
{
|
||||
set_location(@1, @3);
|
||||
|
||||
if ( $1->Tag() == EXPR_INDEX && $1->AsIndexExpr()->IsSlice() )
|
||||
reporter->Error("index slice assignment may not be used"
|
||||
" in arbitrary expression contexts, only"
|
||||
" as a statement");
|
||||
|
||||
$$ = get_assign_expr($1, $3, in_init);
|
||||
}
|
||||
|
||||
|
@ -479,19 +485,7 @@ expr:
|
|||
$$ = new IndexExpr($1, $3);
|
||||
}
|
||||
|
||||
| expr '[' opt_expr ':' opt_expr ']'
|
||||
{
|
||||
set_location(@1, @6);
|
||||
Expr* low = $3 ? $3 : new ConstExpr(val_mgr->GetCount(0));
|
||||
Expr* high = $5 ? $5 : new SizeExpr($1);
|
||||
|
||||
if ( ! IsIntegral(low->Type()->Tag()) || ! IsIntegral(high->Type()->Tag()) )
|
||||
reporter->Error("slice notation must have integral values as indexes");
|
||||
|
||||
ListExpr* le = new ListExpr(low);
|
||||
le->Append(high);
|
||||
$$ = new IndexExpr($1, le, true);
|
||||
}
|
||||
| index_slice
|
||||
|
||||
| expr '$' TOK_ID
|
||||
{
|
||||
|
@ -1271,6 +1265,21 @@ init:
|
|||
| expr
|
||||
;
|
||||
|
||||
index_slice:
|
||||
expr '[' opt_expr ':' opt_expr ']'
|
||||
{
|
||||
set_location(@1, @6);
|
||||
Expr* low = $3 ? $3 : new ConstExpr(val_mgr->GetCount(0));
|
||||
Expr* high = $5 ? $5 : new SizeExpr($1);
|
||||
|
||||
if ( ! IsIntegral(low->Type()->Tag()) || ! IsIntegral(high->Type()->Tag()) )
|
||||
reporter->Error("slice notation must have integral values as indexes");
|
||||
|
||||
ListExpr* le = new ListExpr(low);
|
||||
le->Append(high);
|
||||
$$ = new IndexExpr($1, le, true);
|
||||
}
|
||||
|
||||
opt_attr:
|
||||
attr_list
|
||||
|
|
||||
|
@ -1474,6 +1483,15 @@ stmt:
|
|||
brofiler.DecIgnoreDepth();
|
||||
}
|
||||
|
||||
| index_slice '=' expr ';' opt_no_test
|
||||
{
|
||||
set_location(@1, @4);
|
||||
$$ = new ExprStmt(get_assign_expr($1, $3, in_init));
|
||||
|
||||
if ( ! $5 )
|
||||
brofiler.AddStmt($$);
|
||||
}
|
||||
|
||||
| expr ';' opt_no_test
|
||||
{
|
||||
set_location(@1, @2);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue