mirror of
https://github.com/zeek/zeek.git
synced 2025-10-12 03:28:19 +00:00
factoring + record constructors
This commit is contained in:
parent
ed70fefd34
commit
ba9781d83e
2 changed files with 27 additions and 37 deletions
|
@ -988,15 +988,15 @@ TraversalCode CSE_ValidityChecker::PreExpr(const Expr* e) {
|
||||||
// so we don't want to traverse them.
|
// so we don't want to traverse them.
|
||||||
return TC_ABORTSTMT;
|
return TC_ABORTSTMT;
|
||||||
|
|
||||||
|
case EXPR_RECORD_COERCE:
|
||||||
case EXPR_RECORD_CONSTRUCTOR:
|
case EXPR_RECORD_CONSTRUCTOR:
|
||||||
// If these have initializations done at construction
|
// Note, record coercion behaves like constructors in terms of
|
||||||
// time, those can include function calls.
|
// potentially executing &default functions. In either case,
|
||||||
if ( have_sensitive_IDs ) {
|
// the type of the expression reflects the type we want to analyze
|
||||||
auto& et = e->GetType();
|
// for side effects.
|
||||||
if ( et->Tag() == TYPE_RECORD && ! et->AsRecordType()->IdempotentCreation() ) {
|
if ( CheckRecordConstructor(e->GetType()) ) {
|
||||||
is_valid = false;
|
is_valid = false;
|
||||||
return TC_ABORTALL;
|
return TC_ABORTALL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1078,6 +1078,13 @@ bool CSE_ValidityChecker::CheckAggrMod(const TypePtr& t) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSE_ValidityChecker::CheckRecordConstructor(const TypePtr& t) const {
|
||||||
|
if ( t->Tag() != TYPE_RECORD )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return CheckSideEffects(SideEffectsOp::CONSTRUCTION, t);
|
||||||
|
}
|
||||||
|
|
||||||
bool CSE_ValidityChecker::CheckTableMod(const TypePtr& t) const {
|
bool CSE_ValidityChecker::CheckTableMod(const TypePtr& t) const {
|
||||||
if ( ! CheckAggrMod(t) )
|
if ( ! CheckAggrMod(t) )
|
||||||
return false;
|
return false;
|
||||||
|
@ -1085,54 +1092,35 @@ bool CSE_ValidityChecker::CheckTableMod(const TypePtr& t) const {
|
||||||
if ( t->Tag() != TYPE_TABLE )
|
if ( t->Tag() != TYPE_TABLE )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Note, the following will almost always remain empty.
|
return CheckSideEffects(SideEffectsOp::WRITE, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSE_ValidityChecker::CheckTableRef(const TypePtr& t) const {
|
||||||
|
return CheckSideEffects(SideEffectsOp::READ, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSE_ValidityChecker::CheckSideEffects(SideEffectsOp::AccessType access, const TypePtr& t) const {
|
||||||
IDSet non_local_ids;
|
IDSet non_local_ids;
|
||||||
std::unordered_set<const Type*> aggrs;
|
std::unordered_set<const Type*> aggrs;
|
||||||
|
|
||||||
if ( pfs.GetSideEffects(SideEffectsOp::WRITE, t.get(), non_local_ids, aggrs) )
|
if ( pfs.GetSideEffects(access, t.get(), non_local_ids, aggrs) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ( non_local_ids.empty() && aggrs.empty() )
|
if ( non_local_ids.empty() && aggrs.empty() )
|
||||||
|
// This is far and away the most common case.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for ( auto i : ids ) {
|
for ( auto i : ids ) {
|
||||||
for ( auto nli : non_local_ids )
|
for ( auto nli : non_local_ids )
|
||||||
if ( nli == i ) {
|
if ( nli == i ) {
|
||||||
// printf("non-local ID on WRITE: %s\n", i->Name());
|
// printf("non-local ID on %d: %s\n", access, i->Name());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto i_t = i->GetType();
|
auto i_t = i->GetType();
|
||||||
for ( auto a : aggrs )
|
for ( auto a : aggrs )
|
||||||
if ( same_type(a, i_t.get()) ) {
|
if ( same_type(a, i_t.get()) ) {
|
||||||
// printf("aggr type on WRITE: %s\n", i->Name());
|
// printf("aggr type on %d: %s\n", access, i->Name());
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSE_ValidityChecker::CheckTableRef(const TypePtr& t) const {
|
|
||||||
// Note, the following will almost always remain empty, so spinning
|
|
||||||
// through them in the loop below will be very quick.
|
|
||||||
IDSet non_local_ids;
|
|
||||||
std::unordered_set<const Type*> aggrs;
|
|
||||||
|
|
||||||
if ( pfs.GetSideEffects(SideEffectsOp::READ, t.get(), non_local_ids, aggrs) )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for ( auto i : ids ) {
|
|
||||||
for ( auto nli : non_local_ids )
|
|
||||||
if ( nli == i ) {
|
|
||||||
// printf("non-local ID on READ: %s\n", i->Name());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto i_t = i->GetType();
|
|
||||||
for ( auto a : aggrs )
|
|
||||||
if ( same_type(a, i_t.get()) ) {
|
|
||||||
// printf("aggr type on READ: %p %s\n", e, obj_desc(e).c_str());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,8 +352,10 @@ protected:
|
||||||
|
|
||||||
// About elements ...
|
// About elements ...
|
||||||
// ###
|
// ###
|
||||||
|
bool CheckRecordConstructor(const TypePtr& t) const;
|
||||||
bool CheckTableMod(const TypePtr& t) const;
|
bool CheckTableMod(const TypePtr& t) const;
|
||||||
bool CheckTableRef(const TypePtr& t) const;
|
bool CheckTableRef(const TypePtr& t) const;
|
||||||
|
bool CheckSideEffects(SideEffectsOp::AccessType access, const TypePtr& t) const;
|
||||||
|
|
||||||
// Profile across all script functions.
|
// Profile across all script functions.
|
||||||
ProfileFuncs& pfs;
|
ProfileFuncs& pfs;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue