summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1999-07-23 00:01:29 +0000
committerGurusamy Sarathy <gsar@cpan.org>1999-07-23 00:01:29 +0000
commit76cd736e66383afee2dc798500e6d884d1cd0922 (patch)
treee10b3f1216e6189914de2cabd40f9ea8f7627a71
parent921cb7f07252a906fe2594b618ceb15ee9bd370e (diff)
downloadperl-76cd736e66383afee2dc798500e6d884d1cd0922.tar.gz
emit warning about function calls that were encountered too early
to enforce their prototype p4raw-id: //depot/perl@3723
-rw-r--r--op.c19
-rw-r--r--op.h2
-rw-r--r--pod/perldiag.pod10
3 files changed, 29 insertions, 2 deletions
diff --git a/op.c b/op.c
index b605e669ab..e284d4b2f3 100644
--- a/op.c
+++ b/op.c
@@ -4707,6 +4707,7 @@ Perl_ck_rvconst(pTHX_ register OP *o)
kid->op_type = OP_GV;
SvREFCNT_dec(kid->op_sv);
kid->op_sv = SvREFCNT_inc(gv);
+ kid->op_ppaddr = PL_ppaddr[OP_GV];
}
}
return o;
@@ -5451,9 +5452,11 @@ Perl_ck_subr(pTHX_ OP *o)
o->op_private |= (cvop->op_private & OPpENTERSUB_AMPER);
null(cvop); /* disable rv2cv */
tmpop = (SVOP*)((UNOP*)cvop)->op_first;
- if (tmpop->op_type == OP_GV) {
+ if (tmpop->op_type == OP_GV && !(o->op_private & OPpENTERSUB_AMPER)) {
cv = GvCVu(tmpop->op_sv);
- if (cv && SvPOK(cv) && !(o->op_private & OPpENTERSUB_AMPER)) {
+ if (!cv)
+ tmpop->op_private |= OPpEARLY_CV;
+ else if (SvPOK(cv)) {
namegv = CvANON(cv) ? (GV*)tmpop->op_sv : CvGV(cv);
proto = SvPV((SV*)cv, n_a);
}
@@ -5738,6 +5741,18 @@ Perl_peep(pTHX_ register OP *o)
GvAVn(((GVOP*)o)->op_gv);
}
}
+ else if ((o->op_private & OPpEARLY_CV) && ckWARN(WARN_UNSAFE)) {
+ GV *gv = cGVOPo->op_gv;
+ if (SvTYPE(gv) == SVt_PVGV && GvCV(gv) && SvPVX(GvCV(gv))) {
+ /* XXX could check prototype here instead of just carping */
+ SV *sv = sv_newmortal();
+ gv_efullname3(sv, gv, Nullch);
+ Perl_warner(aTHX_ WARN_UNSAFE,
+ "%s() called too early to check prototype",
+ SvPV_nolen(sv));
+ }
+ }
+
o->op_seq = PL_op_seqmax++;
break;
diff --git a/op.h b/op.h
index 4de46478d3..dd6307c479 100644
--- a/op.h
+++ b/op.h
@@ -127,6 +127,8 @@ typedef U32 PADOFFSET;
/* OP_RV2CV only */
#define OPpENTERSUB_AMPER 8 /* Used & form to call. */
#define OPpENTERSUB_NOPAREN 128 /* bare sub call (without parens) */
+ /* OP_GV only */
+#define OPpEARLY_CV 32 /* foo() called before sub foo was parsed */
/* OP_?ELEM only */
#define OPpLVAL_DEFER 16 /* Defer creation of array/hash elem */
/* for OP_RV2?V, lower bits carry hints */
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index f5717c5a7b..b3265ffb74 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -74,6 +74,16 @@ C<'>-delimited regular expression.
by parentheses turns into a function, with all the list operators arguments
found inside the parentheses. See L<perlop/Terms and List Operators (Leftward)>.
+=item %s() called too early to check prototype
+
+(W) You've called a function that has a prototype before the parser saw a
+definition or declaration for it, and Perl could not check that the call
+conforms to the prototype. You need to either add an early prototype
+declaration for the subroutine in question, or move the subroutine
+definition ahead of the call to get proper prototype checking. Alternatively,
+if you are certain that you're calling the function correctly, you may put
+an ampersand before the name to avoid the warning. See L<perlsub>.
+
=item %s argument is not a HASH element
(F) The argument to exists() must be a hash element, such as