mirror of
https://github.com/zeek/zeek.git
synced 2025-10-12 19:48:20 +00:00
fixed incorrect ZAM optimization of expressions seen in single-statement inlined functions
This commit is contained in:
parent
8054547712
commit
d2762fb247
3 changed files with 43 additions and 4 deletions
|
@ -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();
|
||||||
|
|
2
testing/btest/Baseline/opt.regress-inlining-temps/output
Normal file
2
testing/btest/Baseline/opt.regress-inlining-temps/output
Normal 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
|
30
testing/btest/opt/regress-inlining-temps.zeek
Normal file
30
testing/btest/opt/regress-inlining-temps.zeek
Normal 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;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue