]> git.vpit.fr Git - perl/modules/autovivification.git/blobdiff - autovivification.xs
Make sure a_defined() calls get magic before testing for definedness
[perl/modules/autovivification.git] / autovivification.xs
index cb81c0f95bfe27cc60ac3e5a0e85bb4ca2b21317..7e7c1f34cd32fbb5a684c6d21695537bdd327fa1 100644 (file)
@@ -94,7 +94,18 @@ STATIC UV a_detag(pTHX_ const SV *hint) {
 #else /* A_WORKAROUND_REQUIRE_PROPAGATION */
 
 #define a_tag(B)   newSVuv(B)
-#define a_detag(H) (((H) && SvOK(H)) ? SvUVX(H) : 0)
+/* PVs fetched from the hints chain have their SvLEN set to zero, so get the UV
+ * from a copy. */
+#define a_detag(H) \
+ ((H)              \
+  ? (SvIOK(H)      \
+     ? SvUVX(H)    \
+     : (SvPOK(H)   \
+        ? sv_2uv(SvLEN(H) ? (H) : sv_mortalcopy(H)) \
+       : 0        \
+       )           \
+     )             \
+  : 0)
 
 #endif /* !A_WORKAROUND_REQUIRE_PROPAGATION */
 
@@ -367,7 +378,9 @@ STATIC bool a_defined(pTHX_ SV *sv) {
     defined = TRUE;
    break;
   default:
-   defined = SvOK(sv);
+   SvGETMAGIC(sv);
+   if (SvOK(sv))
+    defined = TRUE;
  }
 
  return defined;
@@ -392,7 +405,7 @@ STATIC OP *a_pp_rv2av(pTHX) {
  flags = oi.flags;
 
  if (flags & A_HINT_DEREF) {
-  if (!SvOK(TOPs)) {
+  if (!a_defined(TOPs)) {
    /* We always need to push an empty array to fool the pp_aelem() that comes
     * later. */
    SV *av;
@@ -419,7 +432,7 @@ STATIC OP *a_pp_rv2hv_simple(pTHX) {
  flags = oi.flags;
 
  if (flags & A_HINT_DEREF) {
-  if (!SvOK(TOPs))
+  if (!a_defined(TOPs))
    RETURN;
  } else {
   PL_op->op_ppaddr = oi.old_pp;
@@ -437,7 +450,7 @@ STATIC OP *a_pp_rv2hv(pTHX) {
  flags = oi.flags;
 
  if (flags & A_HINT_DEREF) {
-  if (!SvOK(TOPs)) {
+  if (!a_defined(TOPs)) {
    SV *hv;
    POPs;
    hv = sv_2mortal((SV *) newHV());
@@ -473,7 +486,7 @@ deref:
 
   if (flags & (A_HINT_NOTIFY|A_HINT_STORE)) {
    SPAGAIN;
-   if (!SvOK(TOPs)) {
+   if (!a_defined(TOPs)) {
     if (flags & A_HINT_STRICT)
      croak("Reference vivification forbidden");
     else if (flags & A_HINT_WARN)