diff --git a/src/script_opt/GenIDDefs.cc b/src/script_opt/GenIDDefs.cc index fde76e9c95..6a44694c6f 100644 --- a/src/script_opt/GenIDDefs.cc +++ b/src/script_opt/GenIDDefs.cc @@ -92,11 +92,18 @@ TraversalCode GenIDDefs::PreStmt(const Stmt* s) { st->Traverse(this); } } - else - // If there's just a single statement then there are no - // expressions computed subsequent to it that we need to - // worry about, so just do ordinary traversal. + else { + // If there's just a single statement then there are two + // possibilities. If the statement is atomic (no sub-statements) + // 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); + } if ( did_confluence ) EndConfluenceBlock(); diff --git a/testing/btest/Baseline/opt.regress-inlining-temps/output b/testing/btest/Baseline/opt.regress-inlining-temps/output new file mode 100644 index 0000000000..5cfd66cc6b --- /dev/null +++ b/testing/btest/Baseline/opt.regress-inlining-temps/output @@ -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 diff --git a/testing/btest/opt/regress-inlining-temps.zeek b/testing/btest/opt/regress-inlining-temps.zeek new file mode 100644 index 0000000000..ab1e05ef6a --- /dev/null +++ b/testing/btest/opt/regress-inlining-temps.zeek @@ -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; + }