diff --git a/CHANGES b/CHANGES index 67b08d4647..08b4f961a1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +6.2.0-dev.515 | 2024-02-06 11:22:26 +0100 + + * Obj: Implement with_location_of() as template (Arne Welzel, Corelight) + + * fixes & enhancements to location information associated w/ AST nodes & ZAM optimization (Vern Paxson, Corelight) + 6.2.0-dev.512 | 2024-02-06 09:55:48 +0100 * Do not default PoolSpec topics to the empty string. (Christian Kreibich, Corelight) diff --git a/VERSION b/VERSION index f2b4e0c7a2..bf1918b9c5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.2.0-dev.512 +6.2.0-dev.515 diff --git a/src/Expr.cc b/src/Expr.cc index ed78f9750f..348b34356a 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -446,7 +446,7 @@ ExprPtr NameExpr::MakeLvalue() { if ( id->IsOption() && ! in_const_init ) ExprError("option is not a modifiable lvalue"); - return make_intrusive(ThisPtr()); + return with_location_of(make_intrusive(ThisPtr()), this); } void NameExpr::Assign(Frame* f, ValPtr v) { @@ -1038,9 +1038,9 @@ void BinaryExpr::PromoteOps(TypeTag t) { bt2 = op2->GetType()->AsVectorType()->Yield()->Tag(); if ( bt1 != t ) - op1 = make_intrusive(op1, t); + op1 = with_location_of(make_intrusive(op1, t), op1); if ( bt2 != t ) - op2 = make_intrusive(op2, t); + op2 = with_location_of(make_intrusive(op2, t), op2); } void BinaryExpr::PromoteType(TypeTag t, bool is_vector) { @@ -1059,7 +1059,7 @@ void BinaryExpr::PromoteForInterval(ExprPtr& op) { SetType(base_type(TYPE_INTERVAL)); if ( op->GetType()->Tag() != TYPE_DOUBLE ) - op = make_intrusive(op, TYPE_DOUBLE); + op = with_location_of(make_intrusive(op, TYPE_DOUBLE), op); } bool BinaryExpr::CheckForRHSList() { @@ -1078,7 +1078,7 @@ bool BinaryExpr::CheckForRHSList() { for ( auto i = 1U; i < rhs_exprs.size(); ++i ) { ExprPtr re_i = {NewRef{}, rhs_exprs[i]}; - op2 = make_intrusive(EXPR_OR, op2, re_i); + op2 = with_location_of(make_intrusive(EXPR_OR, op2, re_i), op2); } SetType(op1->GetType()); @@ -1098,9 +1098,9 @@ bool BinaryExpr::CheckForRHSList() { } if ( lhs_t->IsTable() ) - op2 = make_intrusive(rhs, nullptr, lhs_t); + op2 = with_location_of(make_intrusive(rhs, nullptr, lhs_t), op2); else - op2 = make_intrusive(rhs, nullptr, lhs_t); + op2 = with_location_of(make_intrusive(rhs, nullptr, lhs_t), op2); } else if ( lhs_t->Tag() == TYPE_VECTOR ) { @@ -1109,7 +1109,7 @@ bool BinaryExpr::CheckForRHSList() { return false; } - op2 = make_intrusive(rhs, lhs_t); + op2 = with_location_of(make_intrusive(rhs, lhs_t), op2); } else { @@ -1422,7 +1422,7 @@ AddToExpr::AddToExpr(ExprPtr arg_op1, ExprPtr arg_op2) if ( IsArithmetic(bt1) ) { if ( IsArithmetic(bt2) ) { if ( bt2 != bt1 ) - op2 = make_intrusive(std::move(op2), bt1); + op2 = with_location_of(make_intrusive(op2, bt1), op2); SetType(t1); } @@ -2007,9 +2007,9 @@ CondExpr::CondExpr(ExprPtr arg_op1, ExprPtr arg_op2, ExprPtr arg_op3) if ( BothArithmetic(bt2, bt3) ) { TypeTag t = max_type(bt2, bt3); if ( bt2 != t ) - op2 = make_intrusive(std::move(op2), t); + op2 = with_location_of(make_intrusive(op2, t), op2); if ( bt3 != t ) - op3 = make_intrusive(std::move(op3), t); + op3 = with_location_of(make_intrusive(op3, t), op3); if ( is_vector(op1) ) SetType(make_intrusive(base_type(t))); @@ -2031,9 +2031,11 @@ CondExpr::CondExpr(ExprPtr arg_op1, ExprPtr arg_op2, ExprPtr arg_op3) auto tt3 = op3->GetType(); if ( tt2->IsUnspecifiedTable() ) - op2 = make_intrusive(std::move(op2), std::move(tt3)); + op2 = with_location_of(make_intrusive(op2, std::move(tt3)), op2); + else if ( tt3->IsUnspecifiedTable() ) - op3 = make_intrusive(std::move(op3), std::move(tt2)); + op3 = with_location_of(make_intrusive(op3, std::move(tt2)), op3); + else if ( ! same_type(op2->GetType(), op3->GetType()) ) ExprError("operands must be of the same type"); } @@ -2042,9 +2044,9 @@ CondExpr::CondExpr(ExprPtr arg_op1, ExprPtr arg_op2, ExprPtr arg_op3) auto vt3 = op3->GetType(); if ( vt2->IsUnspecifiedVector() ) - op2 = make_intrusive(std::move(op2), std::move(vt3)); + op2 = with_location_of(make_intrusive(op2, std::move(vt3)), op2); else if ( vt3->IsUnspecifiedVector() ) - op3 = make_intrusive(std::move(op3), std::move(vt2)); + op3 = with_location_of(make_intrusive(op3, std::move(vt2)), op3); else if ( ! same_type(op2->GetType(), op3->GetType()) ) ExprError("operands must be of the same type"); } @@ -2199,23 +2201,24 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) { return TypeCheckArithmetics(bt1, bt2); if ( bt1 == TYPE_TIME && IsArithmetic(bt2) && op2->IsZero() ) { // Allow assignments to zero as a special case. - op2 = make_intrusive(std::move(op2), bt1); + op2 = with_location_of(make_intrusive(op2, bt1), op2); return true; } if ( bt1 == TYPE_TABLE && bt2 == bt1 && op2->GetType()->AsTableType()->IsUnspecifiedTable() ) { - op2 = make_intrusive(std::move(op2), op1->GetType()); + op2 = with_location_of(make_intrusive(op2, op1->GetType()), op2); return true; } if ( bt1 == TYPE_VECTOR ) { if ( bt2 == bt1 && op2->GetType()->AsVectorType()->IsUnspecifiedVector() ) { - op2 = make_intrusive(std::move(op2), op1->GetType()); + op2 = with_location_of(make_intrusive(op2, op1->GetType()), op2); return true; } if ( op2->Tag() == EXPR_LIST ) { - op2 = make_intrusive(cast_intrusive(op2), op1->GetType()); + op2 = with_location_of(make_intrusive(cast_intrusive(op2), op1->GetType()), + op2); return true; } } @@ -2225,7 +2228,7 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) { return true; // Need to coerce. - op2 = make_intrusive(std::move(op2), op1->GetType()); + op2 = with_location_of(make_intrusive(op2, op1->GetType()), op2); return true; } @@ -2249,7 +2252,9 @@ bool AssignExpr::TypeCheck(const AttributesPtr& attrs) { } int errors_before = reporter->Errors(); - op2 = make_intrusive(ctor_list, std::move(attr_copy), op1->GetType()); + op2 = with_location_of(make_intrusive(ctor_list, std::move(attr_copy), + op1->GetType()), + op2); int errors_after = reporter->Errors(); if ( errors_after > errors_before ) { @@ -2282,7 +2287,7 @@ bool AssignExpr::TypeCheckArithmetics(TypeTag bt1, TypeTag bt2) { if ( bt2 == TYPE_DOUBLE ) { Warn("dangerous assignment of double to integral"); - op2 = make_intrusive(std::move(op2), bt1); + op2 = with_location_of(make_intrusive(op2, bt1), op2); bt2 = op2->GetType()->Tag(); } @@ -2291,7 +2296,7 @@ bool AssignExpr::TypeCheckArithmetics(TypeTag bt1, TypeTag bt2) { else { if ( bt2 == TYPE_INT ) { Warn("dangerous assignment of integer to count"); - op2 = make_intrusive(std::move(op2), bt1); + op2 = with_location_of(make_intrusive(op2, bt1), op2); } // Assignment of count to counter or vice @@ -2483,7 +2488,7 @@ ExprPtr IndexExpr::MakeLvalue() { if ( IsString(op1->GetType()->Tag()) ) ExprError("cannot assign to string index expression"); - return make_intrusive(ThisPtr()); + return with_location_of(make_intrusive(ThisPtr()), this); } ValPtr IndexExpr::Eval(Frame* f) const { @@ -2689,7 +2694,7 @@ FieldExpr::FieldExpr(ExprPtr arg_op, const char* arg_field_name) FieldExpr::~FieldExpr() { delete[] field_name; } -ExprPtr FieldExpr::MakeLvalue() { return make_intrusive(ThisPtr()); } +ExprPtr FieldExpr::MakeLvalue() { return with_location_of(make_intrusive(ThisPtr()), this); } bool FieldExpr::CanDel() const { return td->GetAttr(ATTR_DEFAULT) || td->GetAttr(ATTR_OPTIONAL); } @@ -2924,7 +2929,7 @@ TraversalCode RecordConstructorExpr::Traverse(TraversalCallback* cb) const { } static ExprPtr expand_one_elem(const ExprPList& index_exprs, ExprPtr yield, ExprPtr elem, int elem_offset) { - auto expanded_elem = make_intrusive(); + auto expanded_elem = with_location_of(make_intrusive(), elem); for ( int i = 0; i < index_exprs.length(); ++i ) if ( i == elem_offset ) @@ -2933,7 +2938,7 @@ static ExprPtr expand_one_elem(const ExprPList& index_exprs, ExprPtr yield, Expr expanded_elem->Append({NewRef{}, index_exprs[i]}); if ( yield ) - return make_intrusive(expanded_elem, yield, true); + return with_location_of(make_intrusive(expanded_elem, yield, true), elem); else return expanded_elem; } @@ -3012,7 +3017,7 @@ static bool expand_op_elem(ListExprPtr elems, ExprPtr elem, TypePtr t) { } for ( auto& s_elem : v->AsTableVal()->ToMap() ) { - auto c_elem = make_intrusive(s_elem.first); + auto c_elem = with_location_of(make_intrusive(s_elem.first), elem); elems->Append(expand_one_elem(index_exprs, yield, c_elem, set_offset)); } @@ -3035,7 +3040,7 @@ static bool expand_op_elem(ListExprPtr elems, ExprPtr elem, TypePtr t) { } ListExprPtr expand_op(ListExprPtr op, const TypePtr& t) { - auto new_list = make_intrusive(); + auto new_list = with_location_of(make_intrusive(), op); bool did_expansion = false; for ( auto e : op->Exprs() ) { @@ -3828,7 +3833,7 @@ InExpr::InExpr(ExprPtr arg_op1, ExprPtr arg_op2) : BinaryExpr(EXPR_IN, std::move } if ( op1->Tag() != EXPR_LIST ) - op1 = make_intrusive(std::move(op1)); + op1 = with_location_of(make_intrusive(op1), op1); ListExpr* lop1 = op1->AsListExpr(); @@ -4497,7 +4502,7 @@ ExprPtr ListExpr::MakeLvalue() { if ( expr->Tag() != EXPR_NAME ) ExprError("can only assign to list of identifiers"); - return make_intrusive(ThisPtr()); + return with_location_of(make_intrusive(ThisPtr()), this); } void ListExpr::Assign(Frame* f, ValPtr v) { @@ -4541,8 +4546,9 @@ RecordAssignExpr::RecordAssignExpr(const ExprPtr& record, const ExprPtr& init_li int field = lhs->FieldOffset(field_name); if ( field >= 0 && same_type(lhs->GetFieldType(field), t->GetFieldType(j)) ) { - auto fe_lhs = make_intrusive(record, field_name); - auto fe_rhs = make_intrusive(IntrusivePtr{NewRef{}, init}, field_name); + auto fe_lhs = with_location_of(make_intrusive(record, field_name), init_list); + auto fe_rhs = with_location_of(make_intrusive(IntrusivePtr{NewRef{}, init}, field_name), + init_list); Append(get_assign_expr(std::move(fe_lhs), std::move(fe_rhs), is_init)); } } @@ -4554,7 +4560,7 @@ RecordAssignExpr::RecordAssignExpr(const ExprPtr& record, const ExprPtr& init_li const char* field_name = ""; // rf->FieldName(); if ( lhs->HasField(field_name) ) { - auto fe_lhs = make_intrusive(record, field_name); + auto fe_lhs = with_location_of(make_intrusive(record, field_name), init_list); ExprPtr fe_rhs = {NewRef{}, rf->Op()}; Append(get_assign_expr(std::move(fe_lhs), std::move(fe_rhs), is_init)); } @@ -4637,14 +4643,19 @@ void IsExpr::ExprDescribe(ODesc* d) const { } ExprPtr get_assign_expr(ExprPtr op1, ExprPtr op2, bool is_init) { + ExprPtr e; + if ( op1->GetType()->Tag() == TYPE_RECORD && op2->GetType()->Tag() == TYPE_LIST ) - return make_intrusive(std::move(op1), std::move(op2), is_init); + e = make_intrusive(op1, std::move(op2), is_init); else if ( op1->Tag() == EXPR_INDEX && op1->AsIndexExpr()->IsSlice() ) - return make_intrusive(std::move(op1), std::move(op2), is_init); + e = make_intrusive(op1, std::move(op2), is_init); else - return make_intrusive(std::move(op1), std::move(op2), is_init); + e = make_intrusive(op1, std::move(op2), is_init); + + e->SetLocationInfo(op1->GetLocationInfo()); + return e; } ExprPtr check_and_promote_expr(ExprPtr e, TypePtr t) { @@ -4654,13 +4665,13 @@ ExprPtr check_and_promote_expr(ExprPtr e, TypePtr t) { if ( t_tag == TYPE_ANY ) { if ( e_tag != TYPE_ANY ) - return make_intrusive(e); + return with_location_of(make_intrusive(e), e); return e; } if ( e_tag == TYPE_ANY ) - return make_intrusive(e, t); + return with_location_of(make_intrusive(e, t), e); if ( EitherArithmetic(t_tag, e_tag) ) { if ( e_tag == t_tag ) @@ -4677,7 +4688,7 @@ ExprPtr check_and_promote_expr(ExprPtr e, TypePtr t) { return nullptr; } - return make_intrusive(e, t_tag); + return with_location_of(make_intrusive(e, t_tag), e); } if ( t->Tag() == TYPE_RECORD && et->Tag() == TYPE_RECORD ) { @@ -4688,7 +4699,7 @@ ExprPtr check_and_promote_expr(ExprPtr e, TypePtr t) { return e; if ( record_promotion_compatible(t_r, et_r) ) - return make_intrusive(e, IntrusivePtr{NewRef{}, t_r}); + return with_location_of(make_intrusive(e, IntrusivePtr{NewRef{}, t_r}), e); t->Error("incompatible record types", e.get()); return nullptr; @@ -4718,11 +4729,12 @@ ExprPtr check_and_promote_expr(ExprPtr e, TypePtr t) { } } - return make_intrusive(e, IntrusivePtr{NewRef{}, t->AsTableType()}, false); + return with_location_of(make_intrusive(e, IntrusivePtr{NewRef{}, t->AsTableType()}, false), + e); } if ( t->Tag() == TYPE_VECTOR && et->Tag() == TYPE_VECTOR && et->AsVectorType()->IsUnspecifiedVector() ) - return make_intrusive(e, IntrusivePtr{NewRef{}, t->AsVectorType()}); + return with_location_of(make_intrusive(e, IntrusivePtr{NewRef{}, t->AsVectorType()}), e); if ( t->Tag() != TYPE_ERROR && et->Tag() != TYPE_ERROR ) t->Error("type clash", e.get()); diff --git a/src/Expr.h b/src/Expr.h index 1a56cddea3..524cd1440d 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -365,17 +365,6 @@ public: // Helper function to reduce boring code runs. StmtPtr MergeStmts(StmtPtr s1, StmtPtr s2, StmtPtr s3 = nullptr) const; - // Access to the original expression from which this one is derived, - // or this one if we don't have an original. Returns a bare pointer - // rather than an ExprPtr to emphasize that the access is read-only. - const Expr* Original() const { return original ? original->Original() : this; } - - // Designate the given Expr node as the original for this one. - void SetOriginal(ExprPtr _orig) { - if ( ! original ) - original = std::move(_orig); - } - // A convenience function for taking a newly-created Expr, // making it point to us as the successor, and returning it. // @@ -384,19 +373,12 @@ public: // call, as a convenient side effect, transforms that bare pointer // into an ExprPtr. virtual ExprPtr SetSucc(Expr* succ) { - succ->SetOriginal(ThisPtr()); + succ->SetLocationInfo(GetLocationInfo()); if ( IsParen() ) succ->MarkParen(); return {AdoptRef{}, succ}; } - const detail::Location* GetLocationInfo() const override { - if ( original ) - return original->GetLocationInfo(); - else - return Obj::GetLocationInfo(); - } - // Access script optimization information associated with // this statement. ExprOptInfo* GetOptInfo() const { return opt_info; } @@ -434,11 +416,6 @@ protected: bool paren; TypePtr type; - // The original expression from which this statement was - // derived, if any. Used as an aid for generating meaningful - // and correctly-localized error messages. - ExprPtr original = nullptr; - // Information associated with the Expr for purposes of // script optimization. ExprOptInfo* opt_info; @@ -1593,11 +1570,12 @@ private: class InlineExpr : public Expr { public: - InlineExpr(ListExprPtr arg_args, std::vector params, std::vector param_is_modified, StmtPtr body, - int frame_offset, TypePtr ret_type); + InlineExpr(ScriptFuncPtr sf, ListExprPtr arg_args, std::vector params, std::vector param_is_modified, + StmtPtr body, int frame_offset, TypePtr ret_type); bool IsPure() const override; + const ScriptFuncPtr& Func() const { return sf; } ListExprPtr Args() const { return args; } StmtPtr Body() const { return body; } @@ -1618,6 +1596,7 @@ protected: std::vector params; std::vector param_is_modified; int frame_offset; + ScriptFuncPtr sf; ListExprPtr args; StmtPtr body; }; diff --git a/src/Func.cc b/src/Func.cc index 817f57fa6c..fcf0373f86 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -680,8 +680,10 @@ StmtPtr ScriptFunc::AddInits(StmtPtr body, const std::vector& inits) { if ( inits.empty() ) return body; - auto stmt_series = make_intrusive(); - stmt_series->Stmts().push_back(make_intrusive(inits)); + auto stmt_series = with_location_of(make_intrusive(), body); + auto init = with_location_of(make_intrusive(inits), body); + + stmt_series->Stmts().push_back(std::move(init)); stmt_series->Stmts().push_back(std::move(body)); return stmt_series; diff --git a/src/Obj.h b/src/Obj.h index fda839d6f0..492679cf3e 100644 --- a/src/Obj.h +++ b/src/Obj.h @@ -49,6 +49,13 @@ inline void set_location(const Location start, const Location end) { end_location = end; } +// Helper for updating e's location to the one used by o, returning e. +template +T with_location_of(T e, const U& o) { + e->SetLocationInfo(o->GetLocationInfo()); + return e; +} + } // namespace detail class Obj { diff --git a/src/Stmt.cc b/src/Stmt.cc index a0747b6757..cf455c44ed 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -1896,17 +1896,28 @@ void WhenInfo::Build(StmtPtr ws) { lambda = make_intrusive(std::move(ingredients), std::move(outer_ids), "", ws); lambda->SetPrivateCaptures(when_new_locals); + auto cl = cond->GetLocationInfo(); + + for ( const auto& e : std::vector{true_const, param, one_test, two_test, lambda} ) + e->SetLocationInfo(cl); + + for ( const auto& s : + std::vector{empty, test_cond, do_test, else_branch, do_bodies, dummy_return, shebang} ) + s->SetLocationInfo(cl); + analyze_when_lambda(lambda.get()); } void WhenInfo::Instantiate(Frame* f) { Instantiate(lambda->Eval(f)); } -void WhenInfo::Instantiate(ValPtr func) { curr_lambda = make_intrusive(std::move(func)); } +void WhenInfo::Instantiate(ValPtr func) { + curr_lambda = with_location_of(make_intrusive(std::move(func)), cond); +} -ExprPtr WhenInfo::Cond() { return make_intrusive(curr_lambda, invoke_cond); } +ExprPtr WhenInfo::Cond() { return with_location_of(make_intrusive(curr_lambda, invoke_cond), cond); } StmtPtr WhenInfo::WhenBody() { - auto invoke = make_intrusive(curr_lambda, invoke_s); + auto invoke = with_location_of(make_intrusive(curr_lambda, invoke_s), s); return make_intrusive(invoke, true); } @@ -1922,6 +1933,8 @@ double WhenInfo::TimeoutVal(Frame* f) { StmtPtr WhenInfo::TimeoutStmt() { auto invoke = make_intrusive(curr_lambda, invoke_timeout); + if ( timeout_s ) + invoke->SetLocationInfo(timeout_s->GetLocationInfo()); return make_intrusive(invoke, true); } @@ -1933,6 +1946,12 @@ void WhenInfo::BuildInvokeElems() { invoke_cond = make_intrusive(one_const); invoke_s = make_intrusive(two_const); invoke_timeout = make_intrusive(three_const); + + auto cl = cond->GetLocationInfo(); + + for ( const auto& e : + std::vector{one_const, two_const, three_const, invoke_cond, invoke_s, invoke_timeout} ) + e->SetLocationInfo(cl); } WhenStmt::WhenStmt(std::shared_ptr arg_wi) : Stmt(STMT_WHEN), wi(std::move(arg_wi)) { diff --git a/src/Stmt.h b/src/Stmt.h index 2a439ccaa8..054bf263eb 100644 --- a/src/Stmt.h +++ b/src/Stmt.h @@ -658,7 +658,7 @@ private: // The current instance of the lambda. Created by Instantiate(), // for immediate use via calls to Cond() etc. - ConstExprPtr curr_lambda; + ExprPtr curr_lambda; // Arguments to use when calling the lambda to either evaluate // the conditional, or execute the body or the timeout statement. @@ -712,8 +712,9 @@ private: // an already-reduced state. class CatchReturnStmt : public Stmt { public: - explicit CatchReturnStmt(StmtPtr block, NameExprPtr ret_var); + explicit CatchReturnStmt(ScriptFuncPtr sf, StmtPtr block, NameExprPtr ret_var); + const ScriptFuncPtr& Func() const { return sf; } StmtPtr Block() const { return block; } // This returns a bare pointer rather than a NameExprPtr only @@ -743,6 +744,9 @@ public: TraversalCode Traverse(TraversalCallback* cb) const override; protected: + // The inlined function. + ScriptFuncPtr sf; + // The inlined function body. StmtPtr block; diff --git a/src/StmtBase.h b/src/StmtBase.h index db47926c6f..81d8874b69 100644 --- a/src/StmtBase.h +++ b/src/StmtBase.h @@ -144,17 +144,6 @@ public: // hook body. virtual bool CouldReturn(bool ignore_break) const { return false; } - // Access to the original statement from which this one is derived, - // or this one if we don't have an original. Returns a bare pointer - // rather than a StmtPtr to emphasize that the access is read-only. - const Stmt* Original() const { return original ? original->Original() : this; } - - // Designate the given Stmt node as the original for this one. - void SetOriginal(StmtPtr _orig) { - if ( ! original ) - original = std::move(_orig); - } - // A convenience function for taking a newly-created Stmt, // making it point to us as the successor, and returning it. // @@ -163,17 +152,10 @@ public: // call, as a convenient side effect, transforms that bare pointer // into a StmtPtr. virtual StmtPtr SetSucc(Stmt* succ) { - succ->SetOriginal(ThisPtr()); + succ->SetLocationInfo(GetLocationInfo()); return {AdoptRef{}, succ}; } - const detail::Location* GetLocationInfo() const override { - if ( original ) - return original->GetLocationInfo(); - else - return Obj::GetLocationInfo(); - } - // Access script optimization information associated with // this statement. StmtOptInfo* GetOptInfo() const { return opt_info; } @@ -202,11 +184,6 @@ protected: mutable double last_access; // time of last execution mutable uint32_t access_count; // number of executions - // The original statement from which this statement was - // derived, if any. Used as an aid for generating meaningful - // and correctly-localized error messages. - StmtPtr original = nullptr; - // Information associated with the Stmt for purposes of // script optimization. StmtOptInfo* opt_info; diff --git a/src/script_opt/Expr.cc b/src/script_opt/Expr.cc index ec69f0fe0c..fe6e789dc2 100644 --- a/src/script_opt/Expr.cc +++ b/src/script_opt/Expr.cc @@ -348,10 +348,10 @@ ExprPtr Expr::AssignToTemporary(ExprPtr e, Reducer* c, StmtPtr& red_stmt) { auto result_tmp = c->GenTemporaryExpr(GetType(), e); auto a_e = make_intrusive(result_tmp->MakeLvalue(), e, false, nullptr, nullptr, false); + a_e->SetLocationInfo(GetLocationInfo()); a_e->SetIsTemp(); - a_e->SetOriginal(ThisPtr()); - auto a_e_s = make_intrusive(a_e); + auto a_e_s = with_location_of(make_intrusive(a_e), this); red_stmt = MergeStmts(red_stmt, a_e_s); // Important: our result is not result_tmp, but a duplicate of it. @@ -366,7 +366,7 @@ ExprPtr Expr::TransformMe(ExprPtr new_me, Reducer* c, StmtPtr& red_stmt) { if ( new_me == this ) return new_me; - new_me->SetOriginal(ThisPtr()); + new_me->SetLocationInfo(GetLocationInfo()); // Unlike for Stmt's, we assume that new_me has already // been reduced, so no need to do so further. @@ -377,7 +377,7 @@ StmtPtr Expr::MergeStmts(StmtPtr s1, StmtPtr s2, StmtPtr s3) const { int nums = (s1 != nullptr) + (s2 != nullptr) + (s3 != nullptr); if ( nums > 1 ) - return make_intrusive(s1, s2, s3); + return with_location_of(make_intrusive(s1, s2, s3), this); else if ( s1 ) return s1; else if ( s2 ) @@ -402,7 +402,11 @@ ValPtr Expr::MakeZero(TypeTag t) const { } } -ConstExprPtr Expr::MakeZeroExpr(TypeTag t) const { return make_intrusive(MakeZero(t)); } +ConstExprPtr Expr::MakeZeroExpr(TypeTag t) const { + auto z = make_intrusive(MakeZero(t)); + z->SetLocationInfo(GetLocationInfo()); + return z; +} ExprPtr NameExpr::Duplicate() { return SetSucc(new NameExpr(id, in_const_init)); } @@ -569,17 +573,15 @@ ExprPtr IncrExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { StmtPtr target_stmt; target = target->ReduceToSingleton(c, target_stmt); - auto incr_const = make_intrusive(val_mgr->Count(1)); - incr_const->SetOriginal(ThisPtr()); + auto incr_const = with_location_of(make_intrusive(val_mgr->Count(1)), this); ExprPtr incr_expr; if ( Tag() == EXPR_INCR ) - incr_expr = make_intrusive(target, incr_const); + incr_expr = with_location_of(make_intrusive(target, incr_const), this); else - incr_expr = make_intrusive(target, incr_const); + incr_expr = with_location_of(make_intrusive(target, incr_const), this); - incr_expr->SetOriginal(ThisPtr()); StmtPtr incr_stmt; auto incr_expr2 = incr_expr->Reduce(c, incr_stmt); @@ -594,21 +596,19 @@ ExprPtr IncrExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { auto dup1 = orig_target->GetOp1()->Duplicate(); auto dup2 = orig_target->GetOp2()->Duplicate(); auto index = dup2->AsListExprPtr(); - orig_target = make_intrusive(dup1, index); + orig_target = with_location_of(make_intrusive(dup1, index), this); } else if ( orig_target->Tag() == EXPR_FIELD ) { auto dup1 = orig_target->GetOp1()->Duplicate(); auto field_name = orig_target->AsFieldExpr()->FieldName(); - orig_target = make_intrusive(dup1, field_name); + orig_target = with_location_of(make_intrusive(dup1, field_name), this); } else reporter->InternalError("confused in IncrExpr::Reduce"); - auto assign = make_intrusive(orig_target, rhs, false, nullptr, nullptr, false); - - orig_target->SetOriginal(ThisPtr()); + auto assign = with_location_of(make_intrusive(orig_target, rhs, false, nullptr, nullptr, false), this); // First reduce it regularly, so it can transform into $= or // such as needed. Then reduce that to a singleton to provide @@ -628,7 +628,7 @@ ExprPtr IncrExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) { if ( target->Tag() == EXPR_NAME && IsIntegral(target->GetType()->Tag()) ) { ExprPtr incr_expr = Duplicate(); - red_stmt = make_intrusive(incr_expr)->Reduce(c); + red_stmt = with_location_of(make_intrusive(incr_expr), this)->Reduce(c); StmtPtr targ_red_stmt; auto targ_red = target->Reduce(c, targ_red_stmt); @@ -719,9 +719,7 @@ ExprPtr AddExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { ExprPtr AddExpr::BuildSub(const ExprPtr& op1, const ExprPtr& op2) { auto rhs = op2->GetOp1(); - auto sub = make_intrusive(op1, rhs); - sub->SetOriginal(ThisPtr()); - return sub; + return with_location_of(make_intrusive(op1, rhs), this); } ExprPtr AddToExpr::Duplicate() { @@ -767,10 +765,8 @@ ExprPtr AddToExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { red_stmt = MergeStmts(red_stmt1, red_stmt2); if ( tag == TYPE_VECTOR && (! IsVector(op2->GetType()->Tag()) || ! same_type(t, op2->GetType())) ) { - auto append = make_intrusive(op1->Duplicate(), op2); - append->SetOriginal(ThisPtr()); - - auto append_stmt = make_intrusive(append); + auto append = with_location_of(make_intrusive(op1->Duplicate(), op2), this); + auto append_stmt = with_location_of(make_intrusive(append), this); red_stmt = MergeStmts(red_stmt, append_stmt); @@ -782,8 +778,9 @@ ExprPtr AddToExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { default: { auto rhs = op1->AsRefExprPtr()->GetOp1(); - auto do_incr = make_intrusive(rhs->Duplicate(), op2); - auto assign = make_intrusive(op1, do_incr, false, nullptr, nullptr, false); + auto do_incr = with_location_of(make_intrusive(rhs->Duplicate(), op2), this); + auto assign = + with_location_of(make_intrusive(op1, do_incr, false, nullptr, nullptr, false), this); return assign->ReduceToSingleton(c, red_stmt); } @@ -791,7 +788,7 @@ ExprPtr AddToExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { } ExprPtr AddToExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) { - auto at_stmt = make_intrusive(Duplicate()); + auto at_stmt = with_location_of(make_intrusive(Duplicate()), this); red_stmt = at_stmt->Reduce(c); return op1; } @@ -814,8 +811,7 @@ ExprPtr SubExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( op2->Tag() == EXPR_NEGATE ) { auto rhs = op2->GetOp1(); - auto add = make_intrusive(op1, rhs); - add->SetOriginal(ThisPtr()); + auto add = with_location_of(make_intrusive(op1, rhs), this); return add->Reduce(c, red_stmt); } @@ -864,14 +860,14 @@ ExprPtr RemoveFromExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { } auto lhs = op1->AsRefExprPtr()->GetOp1(); - auto do_decr = make_intrusive(lhs->Duplicate(), op2); - auto assign = make_intrusive(op1, do_decr, false, nullptr, nullptr, false); + auto do_decr = with_location_of(make_intrusive(lhs->Duplicate(), op2), this); + auto assign = with_location_of(make_intrusive(op1, do_decr, false, nullptr, nullptr, false), this); return assign->Reduce(c, red_stmt); } ExprPtr RemoveFromExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) { - auto rf_stmt = make_intrusive(Duplicate()); + auto rf_stmt = with_location_of(make_intrusive(Duplicate()), this); red_stmt = rf_stmt->Reduce(c); return op1; } @@ -970,13 +966,13 @@ static bool is_pattern_cascade(const ExprPtr& e, IDPtr& id, std::vector& patterns) { +static ExprPtr build_disjunction(std::vector& patterns, const Obj* obj) { ASSERT(patterns.size() > 1); ExprPtr e = patterns[0]; for ( auto& p : patterns ) - e = make_intrusive(EXPR_OR, e, p); + e = with_location_of(make_intrusive(EXPR_OR, e, p), obj); return e; } @@ -1005,9 +1001,9 @@ ExprPtr BoolExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { IDPtr common_id = nullptr; std::vector patterns; if ( tag == EXPR_OR_OR && is_pattern_cascade(ThisPtr(), common_id, patterns) ) { - auto new_pat = build_disjunction(patterns); - auto new_id = make_intrusive(common_id); - auto new_node = make_intrusive(new_pat, new_id); + auto new_pat = build_disjunction(patterns, this); + auto new_id = with_location_of(make_intrusive(common_id), this); + auto new_node = with_location_of(make_intrusive(new_pat, new_id), this); return new_node->Reduce(c, red_stmt); } @@ -1052,16 +1048,15 @@ ExprPtr BoolExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { } auto else_val = is_and ? val_mgr->False() : val_mgr->True(); - ExprPtr else_e = make_intrusive(else_val); + ExprPtr else_e = with_location_of(make_intrusive(else_val), this); ExprPtr cond; if ( is_and ) - cond = make_intrusive(op1, op2, else_e); + cond = with_location_of(make_intrusive(op1, op2, else_e), this); else - cond = make_intrusive(op1, else_e, op2); + cond = with_location_of(make_intrusive(op1, else_e, op2), this); auto cond_red = cond->ReduceToSingleton(c, red_stmt); - return TransformMe(cond_red, c, red_stmt); } @@ -1118,8 +1113,7 @@ ExprPtr BitExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { auto n = op1->AsNameExpr(); if ( Tag() == EXPR_XOR ) { - auto zero = make_intrusive(val_mgr->Count(0)); - zero->SetOriginal(ThisPtr()); + auto zero = with_location_of(make_intrusive(val_mgr->Count(0)), this); return zero->Reduce(c, red_stmt); } @@ -1141,8 +1135,7 @@ bool EqExpr::WillTransform(Reducer* c) const { return GetType()->Tag() == TYPE_B ExprPtr EqExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( GetType()->Tag() == TYPE_BOOL && same_singletons(op1, op2) ) { bool t = Tag() == EXPR_EQ; - auto res = make_intrusive(val_mgr->Bool(t)); - res->SetOriginal(ThisPtr()); + auto res = with_location_of(make_intrusive(val_mgr->Bool(t)), this); return res->Reduce(c, red_stmt); } @@ -1161,8 +1154,7 @@ ExprPtr RelExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( GetType()->Tag() == TYPE_BOOL ) { if ( same_singletons(op1, op2) ) { bool t = Tag() == EXPR_GE || Tag() == EXPR_LE; - auto res = make_intrusive(val_mgr->Bool(t)); - res->SetOriginal(ThisPtr()); + auto res = with_location_of(make_intrusive(val_mgr->Bool(t)), this); return res->Reduce(c, red_stmt); } @@ -1248,7 +1240,7 @@ ExprPtr CondExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { return op1; // Instead we have "var ? F : T". - return make_intrusive(op1); + return TransformMe(make_intrusive(op1), c, red_stmt); } if ( c->Optimizing() ) @@ -1288,11 +1280,12 @@ StmtPtr CondExpr::ReduceToSingletons(Reducer* c) { if ( red2_stmt || red3_stmt ) { if ( ! red2_stmt ) - red2_stmt = make_intrusive(); + red2_stmt = with_location_of(make_intrusive(), this); if ( ! red3_stmt ) - red3_stmt = make_intrusive(); + red3_stmt = with_location_of(make_intrusive(), this); - if_else = make_intrusive(op1->Duplicate(), std::move(red2_stmt), std::move(red3_stmt)); + if_else = with_location_of(make_intrusive(op1->Duplicate(), std::move(red2_stmt), std::move(red3_stmt)), + this); } return MergeStmts(red1_stmt, if_else); @@ -1343,7 +1336,7 @@ StmtPtr RefExpr::ReduceToLHS(Reducer* c) { } auto red_stmt1 = op->ReduceToSingletons(c); - auto op_ref = make_intrusive(op); + auto op_ref = with_location_of(make_intrusive(op), this); StmtPtr red_stmt2; op = AssignToTemporary(op_ref, c, red_stmt2); @@ -1428,9 +1421,9 @@ ExprPtr AssignExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( val ) { // These are reduced to the assignment followed by // the assignment value. - auto assign_val = make_intrusive(val); + auto assign_val = with_location_of(make_intrusive(val), this); val = nullptr; - red_stmt = make_intrusive(ThisPtr()); + red_stmt = with_location_of(make_intrusive(ThisPtr()), this); return assign_val; } @@ -1443,6 +1436,8 @@ ExprPtr AssignExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { StmtPtr rhs_reduce; if ( lhs_is_any != rhs_is_any ) { + auto op2_orig = op2; + ExprPtr red_rhs = op2->ReduceToSingleton(c, rhs_reduce); if ( lhs_is_any ) { @@ -1453,11 +1448,13 @@ ExprPtr AssignExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { } else op2 = make_intrusive(red_rhs, t1); + + op2->SetLocationInfo(op2_orig->GetLocationInfo()); } if ( t1->Tag() == TYPE_VECTOR && t1->Yield()->Tag() != TYPE_ANY && t2->Yield() && t2->Yield()->Tag() == TYPE_ANY ) { ExprPtr red_rhs = op2->ReduceToSingleton(c, rhs_reduce); - op2 = make_intrusive(red_rhs, t1); + op2 = with_location_of(make_intrusive(red_rhs, t1), op2); } auto lhs_ref = op1->AsRefExprPtr(); @@ -1511,10 +1508,12 @@ ExprPtr AssignExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { loop_over_list(lhs_list, i) { auto rhs_dup = rhs_e->Duplicate(); - auto rhs = make_intrusive(rhs_dup, i); + auto rhs = with_location_of(make_intrusive(rhs_dup, i), this); auto lhs = lhs_list[i]->ThisPtr(); + lhs->SetLocationInfo(GetLocationInfo()); auto assign = make_intrusive(lhs, rhs, false, nullptr, nullptr, false); - auto assign_stmt = make_intrusive(assign); + + auto assign_stmt = with_location_of(make_intrusive(assign), this); red_stmt = MergeStmts(red_stmt, assign_stmt); } @@ -1562,11 +1561,11 @@ ExprPtr AssignExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) { Internal("Confusion in AssignExpr::ReduceToSingleton"); ExprPtr assign_expr = Duplicate(); - auto ae_stmt = make_intrusive(assign_expr); + auto ae_stmt = with_location_of(make_intrusive(assign_expr), this); red_stmt = ae_stmt->Reduce(c); if ( val ) - return make_intrusive(val); + return TransformMe(make_intrusive(val), c, red_stmt); auto lhs = op1->AsRefExprPtr()->GetOp1(); StmtPtr lhs_stmt; @@ -1884,7 +1883,7 @@ ExprPtr ArithCoerceExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( IsArithmetic(t->Tag()) || IsArithmetic(ct->Tag()) ) { if ( auto v = FoldSingleVal(cv, t) ) - return make_intrusive(v); + return TransformMe(make_intrusive(v), c, red_stmt); // else there was a coercion error, fall through } } @@ -1926,7 +1925,7 @@ ExprPtr RecordCoerceExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( WillTransform(c) ) { auto rt = cast_intrusive(type); auto rc_op = op->AsRecordConstructorExpr(); - auto known_constr = make_intrusive(rt, rc_op->Op()); + auto known_constr = with_location_of(make_intrusive(rt, rc_op->Op()), this); auto red_e = known_constr->Reduce(c, red_stmt); return TransformMe(std::move(red_e), c, red_stmt); } @@ -1960,7 +1959,7 @@ ExprPtr VectorCoerceExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { auto op1_list = op->GetOp1(); ASSERT(op1_list->Tag() == EXPR_LIST); auto empty_list = cast_intrusive(op1_list); - auto new_me = make_intrusive(empty_list, type); + auto new_me = with_location_of(make_intrusive(empty_list, type), this); auto red_e = new_me->Reduce(c, red_stmt); return TransformMe(std::move(red_e), c, red_stmt); } @@ -2039,7 +2038,7 @@ bool InExpr::HasReducedOps(Reducer* c) const { return op1->HasReducedOps(c) && o ExprPtr InExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { if ( op2->Tag() == EXPR_SET_CONSTRUCTOR && op2->GetOp1()->AsListExpr()->HasConstantOps() ) - op2 = make_intrusive(op2->Eval(nullptr)); + op2 = with_location_of(make_intrusive(op2->Eval(nullptr)), this); return BinaryExpr::Reduce(c, red_stmt); } @@ -2290,9 +2289,9 @@ ExprPtr CastExpr::Duplicate() { return SetSucc(new CastExpr(op->Duplicate(), typ ExprPtr IsExpr::Duplicate() { return SetSucc(new IsExpr(op->Duplicate(), t)); } -InlineExpr::InlineExpr(ListExprPtr arg_args, std::vector arg_params, std ::vector arg_param_is_modified, - StmtPtr arg_body, int _frame_offset, TypePtr ret_type) - : Expr(EXPR_INLINE), args(std::move(arg_args)), body(std::move(arg_body)) { +InlineExpr::InlineExpr(ScriptFuncPtr arg_sf, ListExprPtr arg_args, std::vector arg_params, + std ::vector arg_param_is_modified, StmtPtr arg_body, int _frame_offset, TypePtr ret_type) + : Expr(EXPR_INLINE), sf(std::move(arg_sf)), args(std::move(arg_args)), body(std::move(arg_body)) { params = std::move(arg_params); param_is_modified = std::move(arg_param_is_modified); frame_offset = _frame_offset; @@ -2335,7 +2334,7 @@ ValPtr InlineExpr::Eval(Frame* f) const { ExprPtr InlineExpr::Duplicate() { auto args_d = args->Duplicate()->AsListExprPtr(); auto body_d = body->Duplicate(); - return SetSucc(new InlineExpr(args_d, params, param_is_modified, body_d, frame_offset, type)); + return SetSucc(new InlineExpr(sf, args_d, params, param_is_modified, body_d, frame_offset, type)); } bool InlineExpr::IsReduced(Reducer* c) const { return NonReduced(this); } @@ -2349,18 +2348,20 @@ ExprPtr InlineExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { auto args_list = args->Exprs(); auto ret_val = c->PushInlineBlock(type); + if ( ret_val ) + ret_val->SetLocationInfo(GetLocationInfo()); loop_over_list(args_list, i) { StmtPtr arg_red_stmt; auto red_i = args_list[i]->Reduce(c, arg_red_stmt); - auto assign_stmt = c->GenParam(params[i], red_i, param_is_modified[i]); + auto assign_stmt = with_location_of(c->GenParam(params[i], red_i, param_is_modified[i]), this); red_stmt = MergeStmts(red_stmt, arg_red_stmt, assign_stmt); } body = body->Reduce(c); c->PopInlineBlock(); - auto catch_ret = make_intrusive(body, ret_val); + auto catch_ret = with_location_of(make_intrusive(sf, body, ret_val), this); red_stmt = MergeStmts(red_stmt, catch_ret); @@ -2448,7 +2449,7 @@ ExprPtr AppendToExpr::Reduce(Reducer* c, StmtPtr& red_stmt) { } ExprPtr AppendToExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) { - auto at_stmt = make_intrusive(Duplicate()); + auto at_stmt = with_location_of(make_intrusive(Duplicate()), this); red_stmt = at_stmt->Reduce(c); return op1->AsRefExprPtr()->GetOp1(); } @@ -2496,10 +2497,10 @@ ExprPtr IndexAssignExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) { StmtPtr op1_red_stmt; op1 = op1->Reduce(c, op1_red_stmt); - auto assign_stmt = make_intrusive(Duplicate()); + auto assign_stmt = with_location_of(make_intrusive(Duplicate()), this); auto index = op2->AsListExprPtr(); - auto res = make_intrusive(GetOp1(), index, false); + auto res = with_location_of(make_intrusive(GetOp1(), index, false), this); auto final_res = res->ReduceToSingleton(c, red_stmt); red_stmt = MergeStmts(op1_red_stmt, assign_stmt, red_stmt); @@ -2597,9 +2598,9 @@ ExprPtr FieldLHSAssignExpr::ReduceToSingleton(Reducer* c, StmtPtr& red_stmt) { StmtPtr op1_red_stmt; op1 = op1->Reduce(c, op1_red_stmt); - auto assign_stmt = make_intrusive(Duplicate()); + auto assign_stmt = with_location_of(make_intrusive(Duplicate()), this); - auto field_res = make_intrusive(op1, field_name); + auto field_res = with_location_of(make_intrusive(op1, field_name), this); StmtPtr field_res_stmt; auto res = field_res->ReduceToSingleton(c, field_res_stmt); diff --git a/src/script_opt/Inline.cc b/src/script_opt/Inline.cc index 56d71ba366..f6ef4d1fb5 100644 --- a/src/script_opt/Inline.cc +++ b/src/script_opt/Inline.cc @@ -217,7 +217,9 @@ void Inliner::CoalesceEventHandlers() { void Inliner::CoalesceEventHandlers(ScriptFuncPtr func, const std::vector& bodies, const BodyInfo& body_to_info) { - auto merged_body = make_intrusive(); + // We pattern the new (alternate) body off of the first body. + auto& b0 = func->GetBodies()[0].stmts; + auto merged_body = with_location_of(make_intrusive(), b0); auto oi = merged_body->GetOptInfo(); auto& params = func->GetType()->Params(); @@ -226,8 +228,6 @@ void Inliner::CoalesceEventHandlers(ScriptFuncPtr func, const std::vectorGetBodies()[0].stmts; auto b0_info = body_to_info.find(b0.get()); ASSERT(b0_info != body_to_info.end()); auto& info0 = funcs[b0_info->second]; @@ -254,9 +254,9 @@ void Inliner::CoalesceEventHandlers(ScriptFuncPtr func, const std::vector(); + auto args = with_location_of(make_intrusive(), b0); for ( auto& p : param_ids ) - args->Append(make_intrusive(p)); + args->Append(with_location_of(make_intrusive(p), b0)); for ( auto& b : bodies ) { auto bp = b.stmts; @@ -272,7 +272,8 @@ void Inliner::CoalesceEventHandlers(ScriptFuncPtr func, const std::vectorStmts().push_back(make_intrusive(ie)); + auto ie_s = with_location_of(make_intrusive(ie), bp); + merged_body->Stmts().push_back(std::move(ie_s)); } auto inlined_func = make_intrusive(merged_body, new_scope, func); @@ -370,7 +371,7 @@ ExprPtr Inliner::CheckForInlining(CallExprPtr c) { auto ie = DoInline(func_vf, body, c->ArgsPtr(), scope, ia->second); if ( ie ) { - ie->SetOriginal(c); + ie->SetLocationInfo(c->GetLocationInfo()); did_inline.insert(func_vf.get()); } @@ -438,7 +439,9 @@ ExprPtr Inliner::DoInline(ScriptFuncPtr sf, StmtPtr body, ListExprPtr args, Scop auto t = scope->GetReturnType(); ASSERT(params.size() == args->Exprs().size()); - return make_intrusive(args, params, param_is_modified, body_dup, curr_frame_size, t); + return with_location_of(make_intrusive(sf, args, params, param_is_modified, body_dup, curr_frame_size, + t), + body); } } // namespace zeek::detail diff --git a/src/script_opt/Reduce.cc b/src/script_opt/Reduce.cc index 7f63a978b7..648a6393da 100644 --- a/src/script_opt/Reduce.cc +++ b/src/script_opt/Reduce.cc @@ -38,13 +38,7 @@ StmtPtr Reducer::Reduce(StmtPtr s) { } ExprPtr Reducer::GenTemporaryExpr(const TypePtr& t, ExprPtr rhs) { - auto e = make_intrusive(GenTemporary(t, rhs)); - e->SetLocationInfo(rhs->GetLocationInfo()); - - // No need to associate with current statement, since these - // are not generated during optimization. - - return e; + return with_location_of(make_intrusive(GenTemporary(t, rhs)), rhs); } NameExprPtr Reducer::UpdateName(NameExprPtr n) { @@ -117,6 +111,7 @@ bool Reducer::ID_IsReduced(const ID* id) const { StmtPtr Reducer::GenParam(const IDPtr& id, ExprPtr rhs, bool is_modified) { auto param = GenInlineBlockName(id); + param->SetLocationInfo(rhs->GetLocationInfo()); auto rhs_id = rhs->Tag() == EXPR_NAME ? rhs->AsNameExpr()->IdPtr() : nullptr; if ( rhs_id && pf->Locals().count(rhs_id.get()) == 0 && ! rhs_id->IsConst() ) @@ -145,9 +140,10 @@ StmtPtr Reducer::GenParam(const IDPtr& id, ExprPtr rhs, bool is_modified) { param_temps.insert(param_id.get()); param = make_intrusive(param_id); + param->SetLocationInfo(rhs->GetLocationInfo()); } - auto assign = make_intrusive(param, rhs, false, nullptr, nullptr, false); + auto assign = with_location_of(make_intrusive(param, rhs, false, nullptr, nullptr, false), rhs); return make_intrusive(assign); } @@ -209,9 +205,15 @@ ExprPtr Reducer::NewVarUsage(IDPtr var, const Expr* orig) { return var_usage; } -void Reducer::BindExprToCurrStmt(const ExprPtr& e) { e->GetOptInfo()->stmt_num = curr_stmt->GetOptInfo()->stmt_num; } +void Reducer::BindExprToCurrStmt(const ExprPtr& e) { + e->GetOptInfo()->stmt_num = curr_stmt->GetOptInfo()->stmt_num; + e->SetLocationInfo(curr_stmt->GetLocationInfo()); +} -void Reducer::BindStmtToCurrStmt(const StmtPtr& s) { s->GetOptInfo()->stmt_num = curr_stmt->GetOptInfo()->stmt_num; } +void Reducer::BindStmtToCurrStmt(const StmtPtr& s) { + s->GetOptInfo()->stmt_num = curr_stmt->GetOptInfo()->stmt_num; + s->SetLocationInfo(curr_stmt->GetLocationInfo()); +} bool Reducer::SameOp(const Expr* op1, const Expr* op2) { if ( op1 == op2 ) @@ -597,6 +599,7 @@ ConstExprPtr Reducer::Fold(ExprPtr e) { } void Reducer::FoldedTo(ExprPtr e, ConstExprPtr c) { + c->SetLocationInfo(e->GetLocationInfo()); om.AddObj(e.get()); constant_exprs[e.get()] = std::move(c); folded_exprs.push_back(std::move(e)); @@ -638,14 +641,14 @@ ExprPtr Reducer::UpdateExpr(ExprPtr e) { // about it being assigned but not used (though // we can still omit the assignment). constant_vars.insert(id); - return make_intrusive(is_const->ValuePtr()); + return with_location_of(make_intrusive(is_const->ValuePtr()), e); } return e; } if ( tmp_var->Const() ) - return make_intrusive(tmp_var->Const()->ValuePtr()); + return with_location_of(make_intrusive(tmp_var->Const()->ValuePtr()), e); auto alias = tmp_var->Alias(); if ( alias ) { @@ -667,7 +670,7 @@ ExprPtr Reducer::UpdateExpr(ExprPtr e) { return e; auto c = rhs->AsConstExpr(); - return make_intrusive(c->ValuePtr()); + return with_location_of(make_intrusive(c->ValuePtr()), e); } StmtPtr Reducer::MergeStmts(const NameExpr* lhs, ExprPtr rhs, const StmtPtr& succ_stmt) { @@ -720,7 +723,7 @@ StmtPtr Reducer::MergeStmts(const NameExpr* lhs, ExprPtr rhs, const StmtPtr& suc // Got it. Mark the original temporary as no longer relevant. lhs_tmp->Deactivate(); - auto merge_e = make_intrusive(a_lhs_deref, rhs, false, nullptr, nullptr, false); + auto merge_e = with_location_of(make_intrusive(a_lhs_deref, rhs, false, nullptr, nullptr, false), lhs); auto merge_e_stmt = make_intrusive(merge_e); // Update the associated stmt_num's. For strict correctness, we diff --git a/src/script_opt/Stmt.cc b/src/script_opt/Stmt.cc index 7524eb4549..78605e78d0 100644 --- a/src/script_opt/Stmt.cc +++ b/src/script_opt/Stmt.cc @@ -23,11 +23,8 @@ StmtPtr Stmt::Reduce(Reducer* c) { if ( repl ) return repl; - if ( c->ShouldOmitStmt(this) ) { - auto null = make_intrusive(); - null->SetOriginal(this_ptr); - return null; - } + if ( c->ShouldOmitStmt(this) ) + return with_location_of(make_intrusive(), this); c->SetCurrStmt(this); @@ -39,7 +36,7 @@ StmtPtr Stmt::TransformMe(StmtPtr new_me, Reducer* c) { // Set the original prior to reduction, to support "original chains" // to ultimately resolve back to the source statement. - new_me->SetOriginal(ThisPtr()); + new_me->SetLocationInfo(GetLocationInfo()); return new_me->Reduce(c); } @@ -62,8 +59,8 @@ StmtPtr ExprListStmt::DoReduce(Reducer* c) { if ( ! c->Optimizing() && IsReduced(c) ) return ThisPtr(); - auto new_l = make_intrusive(); - auto s = make_intrusive(); + auto new_l = with_location_of(make_intrusive(), this); + auto s = with_location_of(make_intrusive(), this); ExprPList& e = l->Exprs(); for ( auto& expr : e ) { @@ -97,9 +94,7 @@ StmtPtr ExprListStmt::DoReduce(Reducer* c) { StmtPtr PrintStmt::Duplicate() { return SetSucc(new PrintStmt(l->Duplicate()->AsListExprPtr())); } StmtPtr PrintStmt::DoSubclassReduce(ListExprPtr singletons, Reducer* c) { - auto new_me = make_intrusive(singletons); - new_me->SetOriginal(ThisPtr()); - return new_me; + return with_location_of(make_intrusive(singletons), this); } StmtPtr ExprStmt::Duplicate() { return SetSucc(new ExprStmt(e ? e->Duplicate() : nullptr)); } @@ -201,7 +196,7 @@ StmtPtr IfStmt::DoReduce(Reducer* c) { auto b = e->GetOp2(); auto s1_dup = s1 ? s1->Duplicate() : nullptr; - s2 = make_intrusive(b, s1_dup, s2); + s2 = with_location_of(make_intrusive(b, s1_dup, s2), s2); e = a; auto res = DoReduce(c); @@ -218,7 +213,7 @@ StmtPtr IfStmt::DoReduce(Reducer* c) { auto b = e->GetOp2(); auto s2_dup = s2 ? s2->Duplicate() : nullptr; - s1 = make_intrusive(b, s1, s2_dup); + s1 = with_location_of(make_intrusive(b, s1, s2_dup), s1); e = a; auto res = DoReduce(c); @@ -239,11 +234,13 @@ StmtPtr IfStmt::DoReduce(Reducer* c) { e = e->ReduceToConditional(c, cond_red_stmt); if ( red_e_stmt && cond_red_stmt ) - red_e_stmt = make_intrusive(red_e_stmt, cond_red_stmt); + red_e_stmt = with_location_of(make_intrusive(red_e_stmt, cond_red_stmt), this); else if ( cond_red_stmt ) red_e_stmt = cond_red_stmt; } + StmtPtr sl; + if ( e->IsConst() ) { auto c_e = e->AsConstExprPtr(); auto t = c_e->Value()->AsBool(); @@ -251,14 +248,14 @@ StmtPtr IfStmt::DoReduce(Reducer* c) { if ( c->Optimizing() ) return t ? s1 : s2; - if ( t ) - return TransformMe(make_intrusive(red_e_stmt, s1), c); - else - return TransformMe(make_intrusive(red_e_stmt, s2), c); + sl = make_intrusive(red_e_stmt, t ? s1 : s2); } - if ( red_e_stmt ) - return TransformMe(make_intrusive(red_e_stmt, ThisPtr()), c); + else if ( red_e_stmt ) + sl = make_intrusive(red_e_stmt, ThisPtr()); + + if ( sl ) + return TransformMe(sl, c); return ThisPtr(); } @@ -339,9 +336,9 @@ bool SwitchStmt::IsReduced(Reducer* r) const { StmtPtr SwitchStmt::DoReduce(Reducer* rc) { if ( cases->length() == 0 ) // Degenerate. - return make_intrusive(); + return TransformMe(make_intrusive(), rc); - auto s = make_intrusive(); + auto s = with_location_of(make_intrusive(), this); StmtPtr red_e_stmt; if ( rc->Optimizing() ) @@ -381,11 +378,8 @@ StmtPtr SwitchStmt::DoReduce(Reducer* rc) { c->UpdateBody(c->Body()->Reduce(rc)); } - if ( ! s->Stmts().empty() ) { - StmtPtr me = ThisPtr(); - auto pre_and_me = make_intrusive(s, me); - return TransformMe(pre_and_me, rc); - } + if ( ! s->Stmts().empty() ) + return TransformMe(make_intrusive(s, ThisPtr()), rc); return ThisPtr(); } @@ -429,10 +423,8 @@ StmtPtr AddDelStmt::DoReduce(Reducer* c) { auto red_e_stmt = e->ReduceToSingletons(c); - if ( red_e_stmt ) { - auto s = make_intrusive(red_e_stmt, ThisPtr()); - return TransformMe(s, c); - } + if ( red_e_stmt ) + return TransformMe(make_intrusive(red_e_stmt, ThisPtr()), c); else return ThisPtr(); @@ -457,10 +449,8 @@ StmtPtr EventStmt::DoReduce(Reducer* c) { event_expr = ee_red->AsEventExprPtr(); e = event_expr; - if ( red_e_stmt ) { - auto s = make_intrusive(red_e_stmt, ThisPtr()); - return TransformMe(s, c); - } + if ( red_e_stmt ) + return TransformMe(make_intrusive(red_e_stmt, ThisPtr()), c); } return ThisPtr(); @@ -490,7 +480,7 @@ StmtPtr WhileStmt::DoReduce(Reducer* c) { if ( ! c->IsPruning() ) { // See comment below for the particulars // of this constructor. - stmt_loop_condition = make_intrusive(STMT_EXPR, loop_condition); + stmt_loop_condition = with_location_of(make_intrusive(STMT_EXPR, loop_condition), this); return ThisPtr(); } } @@ -503,7 +493,7 @@ StmtPtr WhileStmt::DoReduce(Reducer* c) { // We use the more involved ExprStmt constructor here to bypass // its check for whether the expression is being ignored, since // we're not actually creating an ExprStmt for execution. - stmt_loop_condition = make_intrusive(STMT_EXPR, loop_condition); + stmt_loop_condition = with_location_of(make_intrusive(STMT_EXPR, loop_condition), this); if ( loop_cond_pred_stmt ) loop_cond_pred_stmt = loop_cond_pred_stmt->Reduce(c); @@ -606,10 +596,8 @@ StmtPtr ReturnStmt::DoReduce(Reducer* c) { StmtPtr red_e_stmt; e = e->ReduceToSingleton(c, red_e_stmt); - if ( red_e_stmt ) { - auto s = make_intrusive(red_e_stmt, ThisPtr()); - return TransformMe(s, c); - } + if ( red_e_stmt ) + return TransformMe(make_intrusive(red_e_stmt, ThisPtr()), c); } return ThisPtr(); @@ -829,7 +817,7 @@ StmtPtr AssertStmt::Duplicate() { return SetSucc(new AssertStmt(cond->Duplicate( bool AssertStmt::IsReduced(Reducer* c) const { return false; } -StmtPtr AssertStmt::DoReduce(Reducer* c) { return make_intrusive(); } +StmtPtr AssertStmt::DoReduce(Reducer* c) { return TransformMe(make_intrusive(), c); } bool WhenInfo::HasUnreducedIDs(Reducer* c) const { for ( auto& cp : *cl ) { @@ -891,18 +879,17 @@ StmtPtr WhenStmt::DoReduce(Reducer* c) { auto new_e = e->ReduceToSingleton(c, red_e_stmt); wi->SetTimeoutExpr(new_e); - if ( red_e_stmt ) { - auto s = make_intrusive(red_e_stmt, ThisPtr()); - return TransformMe(std::move(s), c); - } + if ( red_e_stmt ) + return TransformMe(make_intrusive(red_e_stmt, ThisPtr()), c); } return ThisPtr(); } -CatchReturnStmt::CatchReturnStmt(StmtPtr _block, NameExprPtr _ret_var) : Stmt(STMT_CATCH_RETURN) { - block = _block; - ret_var = _ret_var; +CatchReturnStmt::CatchReturnStmt(ScriptFuncPtr _sf, StmtPtr _block, NameExprPtr _ret_var) : Stmt(STMT_CATCH_RETURN) { + sf = std::move(_sf); + block = std::move(_block); + ret_var = std::move(_ret_var); } ValPtr CatchReturnStmt::Exec(Frame* f, StmtFlowType& flow) { @@ -929,7 +916,7 @@ bool CatchReturnStmt::IsPure() const { StmtPtr CatchReturnStmt::Duplicate() { auto rv_dup = ret_var->Duplicate(); auto rv_dup_ptr = rv_dup->AsNameExprPtr(); - return SetSucc(new CatchReturnStmt(block->Duplicate(), rv_dup_ptr)); + return SetSucc(new CatchReturnStmt(sf, block->Duplicate(), rv_dup_ptr)); } StmtPtr CatchReturnStmt::DoReduce(Reducer* c) { @@ -945,14 +932,14 @@ StmtPtr CatchReturnStmt::DoReduce(Reducer* c) { if ( ret_var ) reporter->InternalError("inlining inconsistency: no return value"); - return make_intrusive(); + return TransformMe(make_intrusive(), c); } auto rv_dup = ret_var->Duplicate(); auto ret_e_dup = ret_e->Duplicate(); - auto assign = make_intrusive(rv_dup, ret_e_dup, false); - assign_stmt = make_intrusive(assign); + auto assign = with_location_of(make_intrusive(rv_dup, ret_e_dup, false), this); + assign_stmt = with_location_of(make_intrusive(assign), this); if ( ret_e_dup->Tag() == EXPR_CONST ) { auto ce = ret_e_dup->AsConstExpr(); diff --git a/src/script_opt/UseDefs.cc b/src/script_opt/UseDefs.cc index 306c15c274..1e786c9403 100644 --- a/src/script_opt/UseDefs.cc +++ b/src/script_opt/UseDefs.cc @@ -87,7 +87,7 @@ bool UseDefs::RemoveUnused(int iter) { // with one that only includes the actually // used identifiers. - auto new_init = make_intrusive(used_ids); + auto new_init = with_location_of(make_intrusive(used_ids), s); rc->AddStmtToReplace(s, std::move(new_init)); } diff --git a/src/script_opt/ZAM/Expr.cc b/src/script_opt/ZAM/Expr.cc index 5afd2f82cf..7f81b10ee1 100644 --- a/src/script_opt/ZAM/Expr.cc +++ b/src/script_opt/ZAM/Expr.cc @@ -870,21 +870,30 @@ const ZAMStmt ZAMCompiler::AssignTableElem(const Expr* e) { } const ZAMStmt ZAMCompiler::Call(const ExprStmt* e) { - if ( IsZAM_BuiltIn(e->StmtExpr()) ) - return LastInst(); + auto c = cast_intrusive(e->StmtExprPtr()); + + if ( IsZAM_BuiltIn(c.get()) ) { + auto ret = LastInst(); + insts1.back()->call_expr = c; + return ret; + } return DoCall(e->StmtExpr()->AsCallExpr(), nullptr); } const ZAMStmt ZAMCompiler::AssignToCall(const ExprStmt* e) { - if ( IsZAM_BuiltIn(e->StmtExpr()) ) - return LastInst(); - auto assign = e->StmtExpr()->AsAssignExpr(); - auto n = assign->GetOp1()->AsRefExpr()->GetOp1()->AsNameExpr(); - auto call = assign->GetOp2()->AsCallExpr(); + auto call = cast_intrusive(assign->GetOp2()); - return DoCall(call, n); + if ( IsZAM_BuiltIn(e->StmtExpr()) ) { + auto ret = LastInst(); + insts1.back()->call_expr = call; + return ret; + } + + auto n = assign->GetOp1()->AsRefExpr()->GetOp1()->AsNameExpr(); + + return DoCall(call.get(), n); } const ZAMStmt ZAMCompiler::DoCall(const CallExpr* c, const NameExpr* n) { diff --git a/src/script_opt/ZAM/Stmt.cc b/src/script_opt/ZAM/Stmt.cc index 44a816c87a..9c802afb54 100644 --- a/src/script_opt/ZAM/Stmt.cc +++ b/src/script_opt/ZAM/Stmt.cc @@ -11,6 +11,7 @@ namespace zeek::detail { const ZAMStmt ZAMCompiler::CompileStmt(const Stmt* s) { curr_stmt = const_cast(s)->ThisPtr(); + ASSERT(curr_stmt->Tag() == STMT_NULL || curr_stmt->GetLocationInfo()->first_line != 0); switch ( s->Tag() ) { case STMT_PRINT: return CompilePrint(static_cast(s)); diff --git a/src/script_opt/ZAM/ZBody.cc b/src/script_opt/ZAM/ZBody.cc index 1b40902155..b2f20fa225 100644 --- a/src/script_opt/ZAM/ZBody.cc +++ b/src/script_opt/ZAM/ZBody.cc @@ -195,7 +195,7 @@ void ZBody::SetInsts(vector& instsI) { auto& iI = *instsI[i]; insts_copy[i] = iI; if ( iI.stmt ) { - auto l = iI.stmt->Original()->GetLocationInfo(); + auto l = iI.stmt->GetLocationInfo(); if ( l != &no_location ) insts_copy[i].loc = std::make_shared(l->filename, l->first_line, l->last_line, l->first_column, l->last_column);