fixed incorrect ZAM optimization of expressions seen in single-statement inlined functions

This commit is contained in:
Vern Paxson 2025-04-29 14:29:07 -07:00
parent 8054547712
commit d2762fb247
3 changed files with 43 additions and 4 deletions

View file

@ -92,11 +92,18 @@ TraversalCode GenIDDefs::PreStmt(const Stmt* s) {
st->Traverse(this); st->Traverse(this);
} }
} }
else else {
// If there's just a single statement then there are no // If there's just a single statement then there are two
// expressions computed subsequent to it that we need to // possibilities. If the statement is atomic (no sub-statements)
// worry about, so just do ordinary traversal. // then given that it's in reduced form, it's not going to have
// any expressions that we can leverage. OTOH, if it's compound
// (if/for/while/switch) then there's no safe re-using of
// expressions within it since they may-or-may-not wind up
// being computed. So we should always start a new block.
StartConfluenceBlock(s);
did_confluence = true;
block->Traverse(this); block->Traverse(this);
}
if ( did_confluence ) if ( did_confluence )
EndConfluenceBlock(); EndConfluenceBlock();

View file

@ -0,0 +1,2 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
T, [field1=3], 3

View file

@ -0,0 +1,30 @@
# @TEST-DOC: Regression test for incorrect reuse of temporaries when inlining
# @TEST-REQUIRES: test "${ZEEK_USE_CPP}" != "1"
# @TEST-EXEC: zeek -b -O ZAM %INPUT >output
# @TEST-EXEC: btest-diff output
type R: record {
field1: count;
};
global yes = T;
function pred(my_R: R): bool
{
# In the following, my_R$field1 will never be evaluated ...
if ( yes || my_R$field1 == 4 )
return T;
else
return F;
}
event zeek_init()
{
local my_R = R($field1=3);
# ... prior to the regression, the third argument in this print
# was taken from the temporary in pred() that *would* have held
# my_R$field1 had that ever been evaluated, but instead it holds
# the default ZVal value of 0.
print pred(my_R), my_R, my_R$field1;
}