Document the strerror_r / g++ / threads bug
[p5sagit/p5-mst-13.2.git] / gv.c
diff --git a/gv.c b/gv.c
index 23c4e9f..88e9993 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -575,6 +575,17 @@ S_gv_get_super_pkg(pTHX_ const char* name, I32 namelen)
     return stash;
 }
 
+/* FIXME. If changing this function note the comment in pp_hot's
+   S_method_common:
+
+   This code tries to figure out just what went wrong with
+   gv_fetchmethod.  It therefore needs to duplicate a lot of
+   the internals of that function. ...
+
+   I'd guess that with one more flag bit that could all be moved inside
+   here.
+*/
+
 GV *
 Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
 {
@@ -875,6 +886,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
     const I32 add = flags & ~GV_NOADD_MASK;
     const char *const name_end = nambeg + full_len;
     const char *const name_em1 = name_end - 1;
+    U32 faking_it;
 
     if (flags & GV_NOTQUAL) {
        /* Caller promised that there is no stash, so we can skip the check. */
@@ -1071,12 +1083,19 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
        return gv;
     }
 
-    /* Adding a new symbol */
+    /* Adding a new symbol.
+       Unless of course there was already something non-GV here, in which case
+       we want to behave as if there was always a GV here, containing some sort
+       of subroutine.
+       Otherwise we run the risk of creating things like GvIO, which can cause
+       subtle bugs. eg the one that tripped up SQL::Translator  */
+
+    faking_it = SvOK(gv);
 
     if (add & GV_ADDWARN && ckWARN_d(WARN_INTERNAL))
        Perl_warner(aTHX_ packWARN(WARN_INTERNAL), "Had to create %s unexpectedly", nambeg);
     gv_init(gv, stash, name, len, add & GV_ADDMULTI);
-    gv_init_sv(gv, sv_type);
+    gv_init_sv(gv, faking_it ? SVt_PVCV : sv_type);
 
     if (isALPHA(name[0]) && ! (isLEXWARN_on ? ckWARN(WARN_ONCE)
                                            : (PL_dowarn & G_WARN_ON ) ) )