mirror of
https://github.com/zeek/zeek.git
synced 2025-10-12 03:28:19 +00:00
fix for non-default_insert
This commit is contained in:
parent
eab33725f8
commit
91335a770f
4 changed files with 67 additions and 23 deletions
|
@ -985,6 +985,21 @@ void ProfileFuncs::ComputeSideEffects() {
|
||||||
auto a = ea.first;
|
auto a = ea.first;
|
||||||
auto at = a->Tag();
|
auto at = a->Tag();
|
||||||
if ( at == ATTR_DEFAULT || at == ATTR_DEFAULT_INSERT || at == ATTR_ON_CHANGE ) {
|
if ( at == ATTR_DEFAULT || at == ATTR_DEFAULT_INSERT || at == ATTR_ON_CHANGE ) {
|
||||||
|
if ( at == ATTR_DEFAULT ) {
|
||||||
|
for ( auto t : ea.second ) {
|
||||||
|
if ( t->Tag() != TYPE_TABLE )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto y = t->AsTableType()->Yield();
|
||||||
|
|
||||||
|
if ( y && IsAggr(y->Tag()) ) {
|
||||||
|
aggr_tbls_analyzed[t] = true;
|
||||||
|
for ( auto ta : type_aliases[t] )
|
||||||
|
aggr_tbls_analyzed[ta] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Weed out very-common-and-completely-safe expressions.
|
// Weed out very-common-and-completely-safe expressions.
|
||||||
if ( ! DefinitelyHasNoSideEffects(a->GetExpr()) )
|
if ( ! DefinitelyHasNoSideEffects(a->GetExpr()) )
|
||||||
candidates.insert(a);
|
candidates.insert(a);
|
||||||
|
@ -995,6 +1010,8 @@ void ProfileFuncs::ComputeSideEffects() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ###
|
||||||
|
|
||||||
std::vector<std::shared_ptr<SideEffectsOp>> side_effects;
|
std::vector<std::shared_ptr<SideEffectsOp>> side_effects;
|
||||||
|
|
||||||
while ( ! candidates.empty() ) {
|
while ( ! candidates.empty() ) {
|
||||||
|
@ -1253,6 +1270,23 @@ bool ProfileFuncs::AssessSideEffects(const SideEffectsOp* se, SideEffectsOp::Acc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProfileFuncs::IsTableWithDefaultAggr(const Type* t) {
|
||||||
|
auto analy = aggr_tbls_analyzed.find(t);
|
||||||
|
if ( analy != aggr_tbls_analyzed.end() )
|
||||||
|
return analy->second;
|
||||||
|
|
||||||
|
if ( t->AsTableType()->Yield() ) {
|
||||||
|
for ( auto& at : aggr_tbls_analyzed )
|
||||||
|
if ( same_type(at.first, t) ) {
|
||||||
|
aggr_tbls_analyzed[t] = at.second;
|
||||||
|
return at.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aggr_tbls_analyzed[t] = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool ProfileFuncs::GetSideEffects(SideEffectsOp::AccessType access, const Type* t) const {
|
bool ProfileFuncs::GetSideEffects(SideEffectsOp::AccessType access, const Type* t) const {
|
||||||
IDSet nli;
|
IDSet nli;
|
||||||
std::unordered_set<const Type*> aggrs;
|
std::unordered_set<const Type*> aggrs;
|
||||||
|
|
|
@ -228,11 +228,11 @@ protected:
|
||||||
// the same type can be seen numerous times.
|
// the same type can be seen numerous times.
|
||||||
std::unordered_set<const Type*> types;
|
std::unordered_set<const Type*> types;
|
||||||
|
|
||||||
std::unordered_map<const Type*, std::set<const Type*>> type_aliases;
|
|
||||||
|
|
||||||
// The same, but in a deterministic order, with duplicates removed.
|
// The same, but in a deterministic order, with duplicates removed.
|
||||||
std::vector<const Type*> ordered_types;
|
std::vector<const Type*> ordered_types;
|
||||||
|
|
||||||
|
std::unordered_map<const Type*, std::set<const Type*>> type_aliases;
|
||||||
|
|
||||||
// Script functions that this script calls. Includes calls made
|
// Script functions that this script calls. Includes calls made
|
||||||
// by lambdas and when bodies, as the goal is to identify recursion.
|
// by lambdas and when bodies, as the goal is to identify recursion.
|
||||||
std::unordered_set<ScriptFunc*> script_calls;
|
std::unordered_set<ScriptFunc*> script_calls;
|
||||||
|
@ -320,6 +320,8 @@ public:
|
||||||
// types.
|
// types.
|
||||||
// ### const auto& ExprAttrs() const { return expr_attrs; }
|
// ### const auto& ExprAttrs() const { return expr_attrs; }
|
||||||
|
|
||||||
|
bool IsTableWithDefaultAggr(const Type* t);
|
||||||
|
|
||||||
// ###
|
// ###
|
||||||
// true = unknown
|
// true = unknown
|
||||||
bool GetSideEffects(SideEffectsOp::AccessType access, const Type* t) const;
|
bool GetSideEffects(SideEffectsOp::AccessType access, const Type* t) const;
|
||||||
|
@ -447,6 +449,9 @@ protected:
|
||||||
// the attribute appears.
|
// the attribute appears.
|
||||||
std::unordered_map<const Attr*, std::vector<const Type*>> expr_attrs;
|
std::unordered_map<const Attr*, std::vector<const Type*>> expr_attrs;
|
||||||
|
|
||||||
|
// ###
|
||||||
|
std::unordered_map<const Type*, bool> aggr_tbls_analyzed;
|
||||||
|
|
||||||
std::unordered_map<const Attr*, std::vector<std::shared_ptr<SideEffectsOp>>> attr_side_effects;
|
std::unordered_map<const Attr*, std::vector<std::shared_ptr<SideEffectsOp>>> attr_side_effects;
|
||||||
std::unordered_map<const Attr*, std::vector<std::shared_ptr<SideEffectsOp>>> record_constr_with_side_effects;
|
std::unordered_map<const Attr*, std::vector<std::shared_ptr<SideEffectsOp>>> record_constr_with_side_effects;
|
||||||
|
|
||||||
|
|
|
@ -429,23 +429,27 @@ bool Reducer::ExprValid(const ID* id, const Expr* e1, const Expr* e2) const {
|
||||||
// If so, then it's never safe to reuse its associated identifier in lieu
|
// If so, then it's never safe to reuse its associated identifier in lieu
|
||||||
// of e2.
|
// of e2.
|
||||||
std::optional<ExprSideEffects>& e1_se = e1->GetOptInfo()->SideEffects();
|
std::optional<ExprSideEffects>& e1_se = e1->GetOptInfo()->SideEffects();
|
||||||
if ( ! e1_se )
|
if ( ! e1_se ) {
|
||||||
{
|
bool has_side_effects = false;
|
||||||
bool has_side_effects;
|
|
||||||
|
|
||||||
if ( e1->Tag() == EXPR_INDEX )
|
if ( e1->Tag() == EXPR_INDEX ) {
|
||||||
has_side_effects = pfs.GetSideEffects(SideEffectsOp::READ, e1->GetOp1()->GetType().get());
|
auto aggr = e1->GetOp1();
|
||||||
|
auto aggr_t = aggr->GetType();
|
||||||
|
|
||||||
|
if ( pfs.GetSideEffects(SideEffectsOp::READ, aggr_t.get()) )
|
||||||
|
has_side_effects = true;
|
||||||
|
|
||||||
|
else if ( aggr_t->Tag() == TYPE_TABLE && pfs.IsTableWithDefaultAggr(aggr_t.get()) )
|
||||||
|
has_side_effects = true;
|
||||||
|
}
|
||||||
|
|
||||||
else if ( e1->Tag() == EXPR_RECORD_CONSTRUCTOR || e1->Tag() == EXPR_RECORD_COERCE )
|
else if ( e1->Tag() == EXPR_RECORD_CONSTRUCTOR || e1->Tag() == EXPR_RECORD_COERCE )
|
||||||
has_side_effects = pfs.GetSideEffects(SideEffectsOp::CONSTRUCTION, e1->GetType().get());
|
has_side_effects = pfs.GetSideEffects(SideEffectsOp::CONSTRUCTION, e1->GetType().get());
|
||||||
else
|
|
||||||
has_side_effects = false;
|
|
||||||
|
|
||||||
e1_se = ExprSideEffects(has_side_effects);
|
e1_se = ExprSideEffects(has_side_effects);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( e1_se->HasSideEffects() )
|
if ( e1_se->HasSideEffects() ) {
|
||||||
{
|
|
||||||
// We already know that e2 is structurally identical to e1.
|
// We already know that e2 is structurally identical to e1.
|
||||||
e2->GetOptInfo()->SideEffects() = ExprSideEffects(true);
|
e2->GetOptInfo()->SideEffects() = ExprSideEffects(true);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1045,7 +1049,8 @@ bool CSE_ValidityChecker::CheckID(const ID* id, bool ignore_orig) const {
|
||||||
|
|
||||||
if ( id_t && same_type(id_t, i->GetType()) ) {
|
if ( id_t && same_type(id_t, i->GetType()) ) {
|
||||||
// Same-type aggregate.
|
// Same-type aggregate.
|
||||||
// if ( ! ignore_orig ) printf("identifier %s (%d), start %s, end %s\n", id->Name(), ignore_orig, obj_desc(start_e).c_str(), obj_desc(end_e).c_str());
|
// if ( ! ignore_orig ) printf("identifier %s (%d), start %s, end %s\n", id->Name(), ignore_orig,
|
||||||
|
// obj_desc(start_e).c_str(), obj_desc(end_e).c_str());
|
||||||
if ( ignore_orig )
|
if ( ignore_orig )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue