Skip to content

Expr-depth-iterator: support iterating over mutated expressions #4385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

smowton
Copy link
Contributor

@smowton smowton commented Mar 14, 2019

Expr-iterator has always had a mutate() function to enable editing part of an expression tree, and a "next_sibling_or_parent" method to skip walking over the changed expression. However as it turns out using the latter with the former was effectively mandatory because when an expression was replaced wholesale (e.g. it.mutate() = symbol_exprt("something_different", ...)), then a stale iterator referring to the replaced expr's operands vector led to a segfault on the next operator++.

This takes the simple approach to fixing that: use integer indices instead of iterators. I also add some basic unit tests, including one that exhibits the crash in question.

Copy link
Collaborator

@tautschnig tautschnig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest that @LAJW also takes a look, please?

operands_iteratort it,
operands_iteratort end):
expr(expr), it(it), end(end) { }
inline depth_iterator_expr_statet(const exprt &expr) : expr(expr), op_idx(0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing explicit (and you can get rid of the inline, which is actually implicit...).

// Get iterators into the operands of the new expr corresponding to the
// ones into the operands of the old expr
const auto it = operands.end() - (state.end - state.it);
(void)expr->operands();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe that should be (void)expr->write(); instead of a somewhat random function (operands)?

@smowton smowton force-pushed the smowton/fix/expr-iterator-mutated branch 2 times, most recently from 04d1223 to fc35a18 Compare March 14, 2019 15:56
Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️
Passed Diffblue compatibility checks (cbmc commit: fc35a18).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/104448724

expr = &*it;
}
if(!(state == m_stack.back()))
expr = &const_cast<exprt &>(state.expr.get().operands()[state.op_idx]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Why is another const_cast necessary here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, replaced with the synonym *expr

smowton added 2 commits March 14, 2019 18:09
The iterators are appealing, but are invalidated when an expression is replaced via mutate(),
preventing iteration from continuing over the newly altered node.
@smowton smowton force-pushed the smowton/fix/expr-iterator-mutated branch from fc35a18 to 17bee52 Compare March 14, 2019 18:09
Copy link
Contributor

@allredj allredj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️
Passed Diffblue compatibility checks (cbmc commit: 17bee52).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/104465585

@tautschnig tautschnig merged commit 4fa790b into diffblue:develop Mar 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants