mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 10:38:20 +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
32
src/Expr.h
32
src/Expr.h
|
@ -49,7 +49,8 @@ typedef enum {
|
|||
EXPR_FLATTEN,
|
||||
EXPR_CAST,
|
||||
EXPR_IS,
|
||||
#define NUM_EXPRS (int(EXPR_IS) + 1)
|
||||
EXPR_INDEX_SLICE_ASSIGN,
|
||||
#define NUM_EXPRS (int(EXPR_INDEX_SLICE_ASSIGN) + 1)
|
||||
} BroExprTag;
|
||||
|
||||
extern const char* expr_name(BroExprTag t);
|
||||
|
@ -58,6 +59,7 @@ class Stmt;
|
|||
class Frame;
|
||||
class ListExpr;
|
||||
class NameExpr;
|
||||
class IndexExpr;
|
||||
class AssignExpr;
|
||||
class CallExpr;
|
||||
class EventExpr;
|
||||
|
@ -187,6 +189,18 @@ public:
|
|||
return (AssignExpr*) this;
|
||||
}
|
||||
|
||||
const IndexExpr* AsIndexExpr() const
|
||||
{
|
||||
CHECK_TAG(tag, EXPR_INDEX, "ExprVal::AsIndexExpr", expr_name)
|
||||
return (const IndexExpr*) this;
|
||||
}
|
||||
|
||||
IndexExpr* AsIndexExpr()
|
||||
{
|
||||
CHECK_TAG(tag, EXPR_INDEX, "ExprVal::AsIndexExpr", expr_name)
|
||||
return (IndexExpr*) this;
|
||||
}
|
||||
|
||||
void Describe(ODesc* d) const override;
|
||||
|
||||
bool Serialize(SerialInfo* info) const;
|
||||
|
@ -663,6 +677,18 @@ protected:
|
|||
Val* val; // optional
|
||||
};
|
||||
|
||||
class IndexSliceAssignExpr : public AssignExpr {
|
||||
public:
|
||||
IndexSliceAssignExpr(Expr* op1, Expr* op2, int is_init);
|
||||
Val* Eval(Frame* f) const override;
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
IndexSliceAssignExpr() {}
|
||||
|
||||
DECLARE_SERIAL(IndexSliceAssignExpr);
|
||||
};
|
||||
|
||||
class IndexExpr : public BinaryExpr {
|
||||
public:
|
||||
IndexExpr(Expr* op1, ListExpr* op2, bool is_slice = false);
|
||||
|
@ -682,6 +708,8 @@ public:
|
|||
|
||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||
|
||||
bool IsSlice() const { return is_slice; }
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
IndexExpr() { }
|
||||
|
@ -691,6 +719,8 @@ protected:
|
|||
void ExprDescribe(ODesc* d) const override;
|
||||
|
||||
DECLARE_SERIAL(IndexExpr);
|
||||
|
||||
bool is_slice;
|
||||
};
|
||||
|
||||
class FieldExpr : public UnaryExpr {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue