You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[csetjmp.syn] CWG2361, LWG3652: Imprecise description of UB #1778
A setjmp/longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch
and throw would invoke any non-trivial destructors for any automatic objects.
It's unclear what does the document mean by "replacing". Could be something like "if ... skips stack unwinding ..."
Since "stack unwinding" is only defined in the context of exceptions [except.ctor], I don't understand what exactly the improvement is with your proposal.
I do agree that the wording is sub-optimal, but I'm not sure we can find something better that is a small enough fix to be considered editorial.
The original wording is unclear beacuse it does not exactly explain which try block after replacement would be catched. And as that try block varies it might differ whether non-trival destructors of an automatic storage objects would be invoked or not. So what about explaining the try block? Not sure if it is an editoral fix though.
If non-trivial destructors would be invoked by transferring control from point A to point B by throwing an exception at A and catching it at B, then it's undefined to transfer control from A to B by calling setjmp at B and longjmp at A.
If non-trivial destructors would be invoked by transferring control from point A to point B by throwing an exception at A and catching it at B, then it's undefined to transfer control from A to B by calling setjmp at B and longjmp at A.
in place of
A setjmp/longjmp call pair has undefined behavior if replacing the setjmp and longjmp by catch
and throw would invoke any non-trivial destructors for any automatic objects.
I still find that to have a fundamental problem: we can't throw an exception at the longjmp and catch it at the setjmp, because execution in the function containing the setjmp has by definition already got past the setjmp. Whatever rule we use needs to take into account a third point C, which is the point within the function evaluation containing the setjmp call at which longjmp is directly or indirectly invoked. And we want to consider if any local variables would be destroyed by unwinding from A to C, and also something about the relationship between B and C (something like, you can goto from C to B without destroying any local variables).
So I agree the wording is wrong. I do not agree that it can be repaired editorially. While technically library wording, this is a core language mechanism, so we probably want CWG to look at this and propose a wording change.
changed the title [-][csetjmp.syn] CWG2361: Imprecise description of UB[/-][+][csetjmp.syn] CWG2361, LWG3652: Imprecise description of UB[/+]on Dec 23, 2021
Activity
jensmaurer commentedon Oct 20, 2017
Since "stack unwinding" is only defined in the context of exceptions [except.ctor], I don't understand what exactly the improvement is with your proposal.
I do agree that the wording is sub-optimal, but I'm not sure we can find something better that is a small enough fix to be considered editorial.
gnaggnoyil commentedon Oct 20, 2017
The original wording is unclear beacuse it does not exactly explain which
tryblock after replacement would be catched. And as thattryblock varies it might differ whether non-trival destructors of an automatic storage objects would be invoked or not. So what about explaining thetryblock? Not sure if it is an editoral fix though.jwakely commentedon Oct 21, 2017
The meaning seems fairly obvious to me.
If non-trivial destructors would be invoked by transferring control from point A to point B by throwing an exception at A and catching it at B, then it's undefined to transfer control from A to B by calling
setjmpat B andlongjmpat A.lichray commentedon Oct 21, 2017
@jwakely Then why don't we put your explanation
in place of
in the standard?
zygoloid commentedon Oct 21, 2017
I still find that to have a fundamental problem: we can't throw an exception at the
longjmpand catch it at thesetjmp, because execution in the function containing thesetjmphas by definition already got past thesetjmp. Whatever rule we use needs to take into account a third point C, which is the point within the function evaluation containing thesetjmpcall at whichlongjmpis directly or indirectly invoked. And we want to consider if any local variables would be destroyed by unwinding from A to C, and also something about the relationship between B and C (something like, you cangotofrom C to B without destroying any local variables).So I agree the wording is wrong. I do not agree that it can be repaired editorially. While technically library wording, this is a core language mechanism, so we probably want CWG to look at this and propose a wording change.
lichray commentedon Oct 21, 2017
Filed a core issue.
jensmaurer commentedon Apr 10, 2018
This is CWG2361.
[-][csetjmp.syn] Imprecise description of UB[/-][+][csetjmp.syn] CWG 2361: Imprecise description of UB[/+][-][csetjmp.syn] CWG 2361: Imprecise description of UB[/-][+][csetjmp.syn] CWG2361: Imprecise description of UB[/+][-][csetjmp.syn] CWG2361: Imprecise description of UB[/-][+][csetjmp.syn] CWG2361, LWG3652: Imprecise description of UB[/+]jensmaurer commentedon Dec 23, 2021
See also LWG3652.
gnaggnoyil commentedon Dec 24, 2021
My understanding is that LWG3652 still doesn't explain how we can "throw an exception at the
longjmpand catch it at thesetjmp"jensmaurer commentedon Dec 24, 2021
Yes, that's what CWG2361 is about.
frederick-vs-ja commentedon Nov 28, 2024
It seems that such UB should be removed in the spirit of CWG2523. But there's still an issue on whether destructor is called on each of these objects.