Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/perl5Public

Commit73a4618

Browse files
committed
Undefined subroutine &%s called, close to label '%s'
#17839 requested a compile-timewarning for the situation whereby a single colon is accdentally typedas a package separator when calling a function. For example:```package BOOP;sub beep;package main;BOOP:beep(); # Meant to be BOOP::beep();```However, because of both Perl's syntax and the potential to populate thestash at runtime, this falls somewhere between very difficult andimpossible. As an alternative, some enhanced fatal error wording wasrequested and these commits attempt to provide that.The above example would previously die with the message:```Undefined subroutine &main::beep called at ... line 4.```Now it dies with the message:```Undefined subroutine &main::beep called, close to label 'BOOP' at ... line 4.```For some of the same reasons mentioned, distinguishing this typo fromother errors at runtime - such as the target subroutine not beingpresent at all - is also nigh on impossible. The hope is that theerror message will give some additional clue when the error is theresult of a typo, without distracting the user in all other cases.As part of these commits, some common `DIE()` calls in `pp_entersub` wereextracted into a new helper function, `S_croak_undefined_subroutine`, toavoid adding (and slightly reduce) cold code bloating in `pp_entersub`.
1 parentdf4d5e8 commit73a4618

File tree

4 files changed

+53
-9
lines changed

4 files changed

+53
-9
lines changed

‎pod/perldelta.pod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,14 @@ and L</New Warnings>
260260

261261
=item *
262262

263+
L<Undefined subroutine &%s called, close to label '%s'|perldiag/"Undefined subroutine &%s called, close to label '%s'">
264+
265+
(F) The subroutine indicated hasn't been defined, or if it was, it has
266+
since been undefined. This could also indicate a mistyped package
267+
separator, when a single colon was typed instead of two colons.
268+
269+
=item *
270+
263271
XXX L<message|perldiag/"message">
264272

265273
=back

‎pod/perldiag.pod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6820,6 +6820,12 @@ Perhaps it's in a different package? See L<perlfunc/sort>.
68206820
(F) The subroutine indicated hasn't been defined, or if it was, it has
68216821
since been undefined.
68226822

6823+
=item Undefined subroutine &%s called, close to label '%s'
6824+
6825+
(F) The subroutine indicated hasn't been defined, or if it was, it has
6826+
since been undefined. This could also indicate a mistyped package
6827+
separator, when a single colon was typed instead of two colons.
6828+
68236829
=item Undefined subroutine called
68246830

68256831
(F) The anonymous subroutine you're trying to call hasn't been defined,

‎pp_hot.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6212,6 +6212,33 @@ Perl_clear_defarray(pTHX_ AV* av, bool abandon)
62126212
}
62136213
}
62146214

6215+
/* S_croak_undefined_subroutine is a helper function for pp_entersub.
6216+
* It takes assorted DIE() logic out of that hot function.
6217+
*/
6218+
staticvoid
6219+
S_croak_undefined_subroutine(pTHX_CVconst*cv,GVconst*gv)
6220+
{
6221+
if (cv) {
6222+
if (CvLEXICAL(cv)&&CvHASGV(cv))
6223+
croak("Undefined subroutine &%"SVf" called",
6224+
SVfARG(cv_name((CV*)cv,NULL,0)));
6225+
else/* pp_entersub triggers when (CvANON(cv) || !CvHASGV(cv)) */
6226+
croak("Undefined subroutine called");
6227+
}else {/* pp_entersub triggers when (!cv) after `try_autoload` */
6228+
SV*sub_name=newSV_type_mortal(SVt_PV);
6229+
gv_efullname3(sub_name,gv,NULL);
6230+
6231+
/* Heuristic to spot BOOP:boop() typo, when the intention was
6232+
* to call BOOP::boop(). */
6233+
constchar*label=CopLABEL(PL_curcop);
6234+
if (label) {
6235+
croak("Undefined subroutine &%"SVf" called, close to label '%s'",
6236+
SVfARG(sub_name),label);
6237+
}
6238+
croak("Undefined subroutine &%"SVf" called",SVfARG(sub_name));
6239+
}
6240+
NOT_REACHED;/* NOTREACHED */
6241+
}
62156242

62166243
PP(pp_entersub)
62176244
{
@@ -6306,14 +6333,12 @@ PP(pp_entersub)
63066333
assert((void*)&CvROOT(cv)== (void*)&CvXSUB(cv));
63076334
while (UNLIKELY(!CvROOT(cv))) {
63086335
GV*autogv;
6309-
SV*sub_name;
63106336

63116337
/* anonymous or undef'd function leaves us no recourse */
63126338
if (CvLEXICAL(cv)&&CvHASGV(cv))
6313-
DIE(aTHX_"Undefined subroutine &%"SVf" called",
6314-
SVfARG(cv_name(cv,NULL,0)));
6339+
S_croak_undefined_subroutine(aTHX_cv,NULL);
63156340
if (CvANON(cv)|| !CvHASGV(cv)) {
6316-
DIE(aTHX_"Undefined subroutine called");
6341+
S_croak_undefined_subroutine(aTHX_cv,NULL);
63176342
}
63186343

63196344
/* autoloaded stub? */
@@ -6330,11 +6355,8 @@ PP(pp_entersub)
63306355
:0));
63316356
cv=autogv ?GvCV(autogv) :NULL;
63326357
}
6333-
if (!cv) {
6334-
sub_name=sv_newmortal();
6335-
gv_efullname3(sub_name,gv,NULL);
6336-
DIE(aTHX_"Undefined subroutine &%"SVf" called",SVfARG(sub_name));
6337-
}
6358+
if (!cv)
6359+
S_croak_undefined_subroutine(aTHX_NULL,gv);
63386360
}
63396361

63406362
/* unrolled "CvCLONE(cv) && ! CvCLONED(cv)" */

‎t/lib/croak/pp_hot

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ Undefined subroutine &main::foo called at - line 3.
4646
EXPECT
4747
Undefined subroutine &main::foo called at - line 2.
4848
########
49+
# NAME package separator typo, creating a label by accident
50+
package BEEP;
51+
sub boop;
52+
package main;
53+
BEEP:boop();
54+
EXPECT
55+
Undefined subroutine &main::boop called, close to label 'BEEP' at - line 4.
56+
########
4957
# NAME calling undef scalar
5058
&{+undef};
5159
EXPECT

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp