Commit d9a81cdb by Ian Lance Taylor

compiler: do order_evaluations before remove_shortcuts

    
    In remove_shortcuts, the shortcut expressions (&&, ||) are
    rewritten to if statements, which are lifted out before the
    statement containing the shortcut expression. If the containing
    statement has other (sub)expressions that should be evaluated
    before the shortcut expression, which has not been lifted out,
    this will result in wrong evaluation order.
    
    For example, F() + G(A() && B()), the evaluation order per spec
    is F, A, B (if A returns true), G. If we lift A() and B() out
    first, they will be called before F, which is wrong.
    
    To fix this, we split order_evaluations to two phases. The first
    phase, which runs before remove_shortcuts, skips shortcut
    expressions' components. So it won't lift out subexpressions that
    are evaluated conditionally. The shortcut expression itself is
    ordered, since it may have side effects. Then we run
    remove_shortcuts. At this point the subexpressions that should be
    evaluated before the shortcut expression are already lifted out.
    remove_shortcuts also runs the second phase of order_evaluations
    to order the components of shortcut expressions, which were
    skipped during the first phase.
    
    Reorder the code blocks of remove_shortcuts and order_evaluations,
    since remove_shortcuts now calls Order_eval.
    
    Fixes golang/go#26495.
    
    Reviewed-on: https://go-review.googlesource.com/125299

From-SVN: r262908
parent 523a59ff
38850073f25f9de4f3daa33d799def3a33c942ab 39d4d755db7d71b5e770ca435a8b1d1f08f53185
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -143,12 +143,12 @@ go_parse_input_files(const char** filenames, unsigned int filename_count, ...@@ -143,12 +143,12 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
// Export global identifiers as appropriate. // Export global identifiers as appropriate.
::gogo->do_exports(); ::gogo->do_exports();
// Turn short-cut operators (&&, ||) into explicit if statements.
::gogo->remove_shortcuts();
// Use temporary variables to force order of evaluation. // Use temporary variables to force order of evaluation.
::gogo->order_evaluations(); ::gogo->order_evaluations();
// Turn short-cut operators (&&, ||) into explicit if statements.
::gogo->remove_shortcuts();
// Convert named types to backend representation. // Convert named types to backend representation.
::gogo->convert_named_types(); ::gogo->convert_named_types();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment