Skip to content

Fix argprefix: destruct temporary args if last throwing arg throws#4885

Closed
kinke wants to merge 3 commits intodlang:masterfrom
kinke:argprefix
Closed

Fix argprefix: destruct temporary args if last throwing arg throws#4885
kinke wants to merge 3 commits intodlang:masterfrom
kinke:argprefix

Conversation

@kinke
Copy link
Contributor

@kinke kinke commented Aug 14, 2015

Fixes one aspect of https://issues.dlang.org/show_bug.cgi?id=14903.
Doesn't tackle the exception chaining aspect regarding throwing destructors of temporaries, that's back-end stuff.

Previously, if the last potentially throwing argument expression's
`type->baseElemOf()` yielded a struct type, the arg would incorrectly
NOT be added to `eprefix`.
This led to the destructor gate being set to true (disabling all dtors)
right BEFORE evluating the last potentially throwing argument. So in
case it threw, no dtors would be triggered.
@kinke kinke force-pushed the argprefix branch 2 times, most recently from da15ebd to 98e1205 Compare August 14, 2015 17:58
@dnadlinger
Copy link
Contributor

Needs a test case :)

Reduce code duplication, simplify and clarify some points.
The only functional changes are additional asserts and the name of
temporaries with no dtor in the middle of `eprefix` now beginning
with `pfy` instead of `pfx`.
Note that previously, `appendToPrefix` would be set by the first
arg with dtor (if there may be subsequent throws), and only reset
when processing the last throwing arg (i == lastthrow). So all
non-reference args inbetween are added to `eprefix`, even args
without dtor before the first throwing arg (i < firstthrow).
@kinke
Copy link
Contributor Author

kinke commented Aug 14, 2015

Of course, but there's still stuff to be fixed here. The evaluation order seems horribly broken to me. Consider this:

void foo(int a, int b, StructWithDtor c, int d, int e, ref int f, int g, int h);

foo(1, 2, StructWithDtor(), 4, mayThrow(), getIntRef(), mayThrow(), 8):
    firstthrow = e, lastthrow = g
    left-to-right: [prefix] c, d, e, g [/prefix], a, b, f, h
    right-to-left: [prefix] c, d, e, g [/prefix], h, f, b, a

Wouldn't it just make much more sense to put all args into eprefix if there are any temporaries to be destructed on a throw, to keep a sane evaluation order? And for right-to-left calls (array ops), additionally reverse eprefix + fix first and last declaration (left-most arg doesn't need dtor anymore, but right-most one does).
An optimization for direct VarExp args without dtor probably wouldn't hurt either, so as to avoid creating an unnecessary temporary copy of a plain variable, which is just more work for the optimizer to get rid of. (edit: potential side effects of subsequent args...)

@ibuclaw
Copy link
Member

ibuclaw commented Aug 15, 2015

Arrayops is a sensitive topic that probably is best to leave out of this PR. :)

@kinke kinke force-pushed the argprefix branch 2 times, most recently from ee4e8a5 to 3441f57 Compare August 15, 2015 14:03
* If argprefix is required, make sure it covers the very first argument
  up to and including the last potentially throwing argument. Only
  evaluate subsequent arguments directly.
  This also includes ref and out params, but not lazy ones.
* Prepare for right-to-left arguments evaluation order (array ops).
@kinke
Copy link
Contributor Author

kinke commented Aug 15, 2015

Now includes test cases and fixes the evaluation order too. Doesn't make any assumptions about right-to-left order yet, but is prepared to handle that. An open question mark is how to deal with lazy args in argprefix. Currently, they are excluded from argprefix (as in upstream).

@dnadlinger
Copy link
Contributor

LGTM, but ideally @9rnsr would also have a quick look at this.

@ibuclaw
Copy link
Member

ibuclaw commented Aug 15, 2015

Doesn't make any assumptions about right-to-left order yet, but is prepared to handle that.

Everything LTR!

An open question mark is how to deal with lazy args in argprefix

Lazy args should be skipped.

@kinke
Copy link
Contributor Author

kinke commented Aug 15, 2015

Everything LTR!

Well, at least in LDC we explicitly evaluate the arrayops args from right-to-left: https://github.com/ldc-developers/ldc/blob/merge-2.067/gen/tocall.cpp#L403. Is that incorrect by now?

@ibuclaw
Copy link
Member

ibuclaw commented Aug 16, 2015

Is that incorrect by now?

We've reached an impasse between us and Walter. #4035

I think the only way we are going to move forward is to a fork between arrayops on x86 vs. every other platform.

@kinke
Copy link
Contributor Author

kinke commented Oct 1, 2015

Superseded by a DDMD port #5151.

@kinke kinke closed this Oct 1, 2015
@kinke kinke deleted the argprefix branch January 31, 2016 20:49
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.

3 participants