CV* const cv = MUTABLE_CV(*location);
if (cv) {
if (!GvCVGEN((const GV *)dstr) &&
- (CvROOT(cv) || CvXSUB(cv)))
+ (CvROOT(cv) || CvXSUB(cv)) &&
+ /* redundant check that avoids creating the extra SV
+ most of the time: */
+ (CvCONST(cv) || ckWARN(WARN_REDEFINE)))
{
- /* Redefining a sub - warning is mandatory if
- it was a const and its value changed. */
- if (CvCONST(cv) && CvCONST((const CV *)sref)
- && cv_const_sv(cv)
- == cv_const_sv((const CV *)sref)) {
- NOOP;
- /* They are 2 constant subroutines generated from
- the same constant. This probably means that
- they are really the "same" proxy subroutine
- instantiated in 2 places. Most likely this is
- when a constant is exported twice. Don't warn.
- */
- }
- else if (ckWARN(WARN_REDEFINE)
- || (CvCONST(cv)
- && (!CvCONST((const CV *)sref)
- || sv_cmp(cv_const_sv(cv),
- cv_const_sv((const CV *)
- sref))))) {
- Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
- (const char *)
- (CvCONST(cv)
- ? "Constant subroutine %"HEKf
- "::%"HEKf" redefined"
- : "Subroutine %"HEKf"::%"HEKf
- " redefined"),
+ SV * const new_const_sv =
+ CvCONST((const CV *)sref)
+ ? cv_const_sv((const CV *)sref)
+ : NULL;
+ report_redefined_cv(
+ sv_2mortal(Perl_newSVpvf(aTHX_
+ "%"HEKf"::%"HEKf,
HEKfARG(
HvNAME_HEK(GvSTASH((const GV *)dstr))
),
- HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr))));
- }
+ HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr)))
+ )),
+ cv,
+ CvCONST((const CV *)sref) ? &new_const_sv : NULL
+ );
}
if (!intro)
cv_ckproto_len_flags(cv, (const GV *)dstr,
=for apidoc sv_insert_flags
-Same as C<sv_insert>, but the extra C<flags> are passed the C<SvPV_force_flags> that applies to C<bigstr>.
+Same as C<sv_insert>, but the extra C<flags> are passed to the
+C<SvPV_force_flags> that applies to C<bigstr>.
=cut
*/
/* A constant subroutine can have no side effects, so
don't bother calling it. */
&& !CvCONST(destructor)
- /* Don't bother calling an empty destructor */
+ /* Don't bother calling an empty destructor or one that
+ returns immediately. */
&& (CvISXSUB(destructor)
|| (CvSTART(destructor)
&& (CvSTART(destructor)->op_next->op_type
- != OP_LEAVESUB))))
+ != OP_LEAVESUB)
+ && (CvSTART(destructor)->op_next->op_type
+ != OP_PUSHMARK
+ || CvSTART(destructor)->op_next->op_next->op_type
+ != OP_RETURN
+ )
+ ))
+ )
{
SV* const tmpref = newRV(sv);
SvREADONLY_on(tmpref); /* DESTROY() could be naughty */
if (SvROK(sv)) {
if (SvAMAGIC(sv))
sv = amagic_deref_call(sv, to_cv_amg);
- /* At this point I'd like to do SPAGAIN, but really I need to
- force it upon my callers. Hmmm. This is a mess... */
sv = SvRV(sv);
if (SvTYPE(sv) == SVt_PVCV) {
Get a sensible string out of the SV somehow.
A private implementation of the C<SvPV_force> macro for compilers which
-can't cope with complex macro expressions. Always use the macro instead.
+can't cope with complex macro expressions. Always use the macro instead.
=for apidoc sv_pvn_force_flags
PERL_ARGS_ASSERT_SV_PVN_FORCE_FLAGS;
+ if (flags & SV_GMAGIC) SvGETMAGIC(sv);
if (SvTHINKFIRST(sv) && !SvROK(sv))
sv_force_normal_flags(sv, 0);
/* diag_listed_as: Can't coerce %s to %s in %s */
Perl_croak(aTHX_ "Can't coerce %s to string in %s", sv_reftype(sv,0),
OP_DESC(PL_op));
- s = sv_2pv_flags(sv, &len, flags);
+ s = sv_2pv_flags(sv, &len, flags &~ SV_GMAGIC);
if (lp)
*lp = len;
* back into v-string notation and then let the
* vectorize happen normally
*/
- if (sv_derived_from(vecsv, "version")) {
+ if (sv_derived_from(vecsv, "version") && SvROK(vecsv)) {
char *version = savesvpv(vecsv);
if ( hv_exists(MUTABLE_HV(SvRV(vecsv)), "alpha", 5 ) ) {
Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
break;
sv = hash ? MUTABLE_SV(GvHV(gv)): MUTABLE_SV(GvAV(gv));
}
- else /* @{expr}, %{expr} */
+ else if (obase == PL_op) /* @{expr}, %{expr} */
return find_uninit_var(cUNOPx(obase)->op_first,
uninit_sv, match);
+ else /* @{expr}, %{expr} as a sub-expression */
+ return NULL;
}
/* attempt to find a match within the aggregate */
if ( (type == OP_CONST && SvOK(cSVOPx_sv(kid)))
|| (type == OP_NULL && ! (kid->op_flags & OPf_KIDS))
|| (type == OP_PUSHMARK)
- || (
- /* @$a and %$a, but not @a or %a */
- (type == OP_RV2AV || type == OP_RV2HV)
- && cUNOPx(kid)->op_first
- && cUNOPx(kid)->op_first->op_type != OP_GV
- )
)
continue;
}