-
Notifications
You must be signed in to change notification settings - Fork 599
Force OPf_PARENS on "if/elsif/unless" optree branches #23850
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
base: blead
Are you sure you want to change the base?
Conversation
Previously, only `else {}` branches would have the OPf_PARAMS flag set. `Perl_op_scope` uses this flag to determine whether its optree argument (`o`) should be wrapped in an `ENTER/LEAVE` pair or only get a `SCOPE` OP, which is typically optimized away (nulled out) before runtime. This has at least two consequences visible for Perl users: 1. Differing lifetimes for things depending upon whether they occur in an `if` block or an `else` block. This could cause bugs that cannot be understood from Perl source code alone. For example, consider a `Foo` class that has a `DESTROY` sub. In the following code, `$object2` goes out of scope at the completion of the `else {}` block and the `DESTROY` sub fires. In contrast, `$object1` does NOT go out of scope at the completion of the `if {}` block - because _there is no scope_ - and the `DESTROY` sub won't fire until some later time. ``` if ($_) { my $object1 = Foo->new(); } else { my $object2 = Foo->new(); } ``` 2. The `NEXTSTATE` OP immediately following a `SCOPE` OP is typically nulled out before runtime, but the first `NEXTSTATE` after an `ENTER` OP is not. `NEXTSTATE` OPs update the interpreter with the line number associated with the currently executing statement. (`PL_curcop`.) The interpreter outputs this in warnings or fatal error messages. Not having the first `NEXTSTATE` present in `if` blocks means that error messages triggered by the first line of code will typically report an incorrect line number. This commit addresses the above two concerns, but with the downside that `if`/`elsif`/`unless` blocks now have the same OP overhead as `else` blocks. (The `ENTER`, first `NEXTSTATE`, and `LEAVE` OPs.)
Line number problems could also be fixed by not nulling out Something that we could do if this PR is merged and we fix the above is to teach
|
It might be easier than I suggested above. 😆 Will look into that sometime this month. |
Hmmm, a better fix for the
That does nothing for the line number warnings though - actually means lines from the start of |
"Force OPf_PARAMS..." in subject, commit message. but you force |
D'oh. Too much thinking about parameters recently. Thanks for spotting it. I'm going to see if the alternative route works without breaking B, before continuing with this PR. |
I like fixes, but I am worried it will silently change lifetimes and break downstream code. Though it should really only depend on destruction side effects, code that depends on the object really needs its own reference will be prevent any early destruction. |
Yeah, that's definitely a potential downside. Any such code is already brittle; any minor refactoring that moves logic out of an |
Previously, only
else {}
branches would have the OPf_PARAMS flag set.Perl_op_scope
uses this flag to determine whether its optree argument (o
)should be wrapped in an
ENTER/LEAVE
pair or only get aSCOPE
OP, whichis typically optimized away (nulled out) before runtime.
This has at least two consequences visible for Perl users:
Differing lifetimes for things depending upon whether they occur in an
if
block or anelse
block. This could cause bugs that cannot beunderstood from Perl source code alone.
For example, consider a
Foo
class that has aDESTROY
sub. In thefollowing code,
$object2
goes out of scope at the completion of theelse {}
block and theDESTROY
sub fires. In contrast,$object1
does NOT go out of scope at the completion of the
if {}
block -because there is no scope - and the
DESTROY
sub won't fire untilsome later time.
The
NEXTSTATE
OP immediately following aSCOPE
OP is typicallynulled out before runtime, but the first
NEXTSTATE
after anENTER
OP is not.NEXTSTATE
OPs update the interpreter with the line number associatedwith the currently executing statement. (
PL_curcop
.) The interpreteroutputs this in warnings or fatal error messages. Not having the first
NEXTSTATE
present inif
blocks means that error messages triggeredby the first line of code will typically report an incorrect line
number.
This PR addresses the above two concerns, but with the downside
that
if
/elsif
/unless
blocks now have the same OP overhead aselse
blocks. (TheENTER
, firstNEXTSTATE
, andLEAVE
OPs.)