-
Notifications
You must be signed in to change notification settings - Fork 602
Description
This issue addresses case JJJ mentioned in #23889 (comment). It requires some background. Let's go back in time to November/December 2022.
v5.37.6
Suppose I checkout v5.37.6, and then, for debugging purposes, mangle one of the exception messages in pp_ctl.c.
$ git status
HEAD detached at v5.37.6
...
$ git diff
diff --git a/pp_ctl.c b/pp_ctl.c
index d0b5d8d013..defc89fd6e 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2928,7 +2928,7 @@ PP(pp_goto)
for(ix = cxstack_ix; ix > cxix; ix--) {
if(CxTYPE(&cxstack[ix]) == CXt_DEFER)
/* diag_listed_as: Can't "%s" out of a "defer" block */
- Perl_croak(aTHX_ "Can't \"%s\" out of a \"%s\" block",
+ Perl_croak(aTHX_ "Can't \"%s\" JJJ:out of a \"%s\" block",
"goto", S_defer_blockname(&cxstack[ix]));
}
Running make test_harness at this point reveals a failure in t/op/defer.t (also porting/bench.t, but I think that's a separate concern). When I run t/op/defer.t, I get:
$ cd t;./perl harness -v op/defer.t; cd -
ok 1 - defer block is invoked
ok 2 - defer block can contain multiple statements
...
ok 25 - Cannot goto out of defer block
ok 26 - Cannot goto into defer block
not ok 27 - Cannot goto &SUB out of a "defer" block
ok 28 - Cannot last out of defer block
...
# Failed test 27 - Cannot goto &SUB out of a "defer" block at op/defer.t line 303
# got 'Can\'t \"goto\" JJJ:out of a \"defer\" block at op/defer.t line 298.\n'
# expected /(?^:^Can't "goto" out of a "defer" block at )/
Failed 1/30 subtests
Test Summary Report
-------------------
op/defer.t (Wstat: 0 Tests: 30 Failed: 1)
Failed test: 27
Files=1, Tests=30, 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
I get one test failure which merely reflects the mangled message, but that does indicate that this section of pp_ctl.c is exercised (covered) by the test suite.
v5.37.7
Now suppose I checkout v5.37.7, then cherry-pick the same one-line exception message revision I did for v5.37.6. If I then run t/op/defer.t, I do not get any test failures. But that's misleading, because there are 4 fewer unit tests in that file, and test Cannot goto &SUB out of a "defer" block is one of the ones that no longer appears. The 4 tests were essentially transferred to t/lib/croak/op in abf573d. (When I run make test_harness the only failures I get are, once again, in t/porting/bench.t.)
Now suppose I mangle one more exception message, this time in op.c:
$ git diff
diff --git a/op.c b/op.c
index 887f2fc7ad..cdfd9be19c 100644
--- a/op.c
+++ b/op.c
@@ -5176,7 +5176,7 @@ static void walk_ops_forbid(pTHX_ OP *o, U32 flags, HV *permittedloops, const ch
forbid:
/* diag_listed_as: Can't "%s" out of a "defer" block */
/* diag_listed_as: Can't "%s" out of a "finally" block */
- croak("Can't \"%s\" out of %s", PL_op_name[o->op_type], blockname);
+ croak("Can't \"%s\" ZZZ:out of %s", PL_op_name[o->op_type], blockname);
default:
break;
This change leads to 6 test failures in t/lib/croak.t and demonstrates that the croak statement with ZZZ: in it is the source of the failures. This is not really surprising; the commit message for abf573d:
commit abf573d1658ed41e29b6dae390645908838b313b
Author: Paul Evans <leonerd@leonerd.org.uk>
Date: Wed Dec 14 12:24:09 2022 +0000
Detect forbidden flow at compiletime of `defer` or `finally`
Using the new `forbid_outofblock_ops()`, many kinds of forbidden control
flow out of a `defer` or `finally` block can be detected statically with
this function by analysing the optree, rather than leaving it until
runtime when the attempt is actually made.
Inference:
We have a block of code in pp_ctl.c that can no longer be reached. It can be removed without causing any test failures. Pull request forthcoming.