warn on C<my($foo,$foo)>
[p5sagit/p5-mst-13.2.git] / op.c
diff --git a/op.c b/op.c
index f64a59e..9b2284d 100644 (file)
--- a/op.c
+++ b/op.c
@@ -131,12 +131,11 @@ pad_allocmy(char *name)
        for (off = AvFILLp(PL_comppad_name); off > PL_comppad_name_floor; off--) {
            if ((sv = svp[off])
                && sv != &PL_sv_undef
-               && SvIVX(sv) == 999999999       /* var is in open scope */
                && strEQ(name, SvPVX(sv)))
            {
                warner(WARN_UNSAFE,
-                       "\"my\" variable %s masks earlier declaration in same scope", 
-                       name);
+                       "\"my\" variable %s masks earlier declaration in same %s", 
+                       name, (SvIVX(sv) == 999999999 ? "scope" : "statement"));
                break;
            }
        }
@@ -694,15 +693,16 @@ scalarkids(OP *o)
 STATIC OP *
 scalarboolean(OP *o)
 {
-    if (ckWARN(WARN_SYNTAX) &&
-       o->op_type == OP_SASSIGN && cBINOPo->op_first->op_type == OP_CONST) {
+    if (o->op_type == OP_SASSIGN && cBINOPo->op_first->op_type == OP_CONST) {
        dTHR;
-       line_t oldline = PL_curcop->cop_line;
+       if (ckWARN(WARN_SYNTAX)) {
+           line_t oldline = PL_curcop->cop_line;
 
-       if (PL_copline != NOLINE)
-           PL_curcop->cop_line = PL_copline;
-       warner(WARN_SYNTAX, "Found = in conditional, should be ==");
-       PL_curcop->cop_line = oldline;
+           if (PL_copline != NOLINE)
+               PL_curcop->cop_line = PL_copline;
+           warner(WARN_SYNTAX, "Found = in conditional, should be ==");
+           PL_curcop->cop_line = oldline;
+       }
     }
     return scalar(o);
 }
@@ -889,15 +889,18 @@ scalarvoid(OP *o)
 
     case OP_CONST:
        sv = cSVOPo->op_sv;
-       if (ckWARN(WARN_VOID)) {
-           useless = "a constant";
-           if (SvNIOK(sv) && (SvNV(sv) == 0.0 || SvNV(sv) == 1.0))
-               useless = 0;
-           else if (SvPOK(sv)) {
-               if (strnEQ(SvPVX(sv), "di", 2) ||
-                   strnEQ(SvPVX(sv), "ds", 2) ||
-                   strnEQ(SvPVX(sv), "ig", 2))
-                       useless = 0;
+       {
+           dTHR;
+           if (ckWARN(WARN_VOID)) {
+               useless = "a constant";
+               if (SvNIOK(sv) && (SvNV(sv) == 0.0 || SvNV(sv) == 1.0))
+                   useless = 0;
+               else if (SvPOK(sv)) {
+                   if (strnEQ(SvPVX(sv), "di", 2) ||
+                       strnEQ(SvPVX(sv), "ds", 2) ||
+                       strnEQ(SvPVX(sv), "ig", 2))
+                           useless = 0;
+               }
            }
        }
        null(o);                /* don't execute a constant */
@@ -956,8 +959,11 @@ scalarvoid(OP *o)
        }
        break;
     }
-    if (useless && ckWARN(WARN_VOID))
-       warner(WARN_VOID, "Useless use of %s in void context", useless);
+    if (useless) {
+       dTHR;
+       if (ckWARN(WARN_VOID))
+           warner(WARN_VOID, "Useless use of %s in void context", useless);
+    }
     return o;
 }
 
@@ -1128,7 +1134,8 @@ mod(OP *o, I32 type)
        if (type == OP_GREPSTART || type == OP_ENTERSUB || type == OP_REFGEN)
            break;
        yyerror(form("Can't modify %s in %s",
-                    op_desc[o->op_type],
+                    (o->op_type == OP_NULL && (o->op_flags & OPf_SPECIAL)
+                     ? "do block" : op_desc[o->op_type]),
                     type ? op_desc[type] : "local"));
        return o;
 
@@ -1257,7 +1264,9 @@ mod(OP *o, I32 type)
        break;
 
     case OP_NULL:
-       if (!(o->op_flags & OPf_KIDS))
+       if (o->op_flags & OPf_SPECIAL)          /* do BLOCK */
+           goto nomod;
+       else if (!(o->op_flags & OPf_KIDS))
            break;
        if (o->op_targ != OP_LIST) {
            mod(cBINOPo->op_first, type);
@@ -1465,6 +1474,7 @@ sawparens(OP *o)
 OP *
 bind_match(I32 type, OP *left, OP *right)
 {
+    dTHR;
     OP *o;
 
     if (ckWARN(WARN_UNSAFE) &&
@@ -1648,6 +1658,7 @@ localize(OP *o, I32 lex)
     if (o->op_flags & OPf_PARENS)
        list(o);
     else {
+       dTHR;
        if (ckWARN(WARN_PARENTHESIS) && PL_bufptr > PL_oldbufptr && PL_bufptr[-1] == ',') {
            char *s;
            for (s = PL_bufptr; *s && (isALNUM(*s) || strchr("@$%, ",*s)); s++) ;
@@ -2124,11 +2135,11 @@ pmtrans(OP *o, OP *expr, OP *repl)
                diff = val - nextmin;
                if (diff > 0) {
                    t = uv_to_utf8(tmpbuf,nextmin);
-                   sv_catpvn(transv, tmpbuf, t - tmpbuf);
+                   sv_catpvn(transv, (char*)tmpbuf, t - tmpbuf);
                    if (diff > 1) {
                        t = uv_to_utf8(tmpbuf, val - 1);
                        sv_catpvn(transv, "\377", 1);
-                       sv_catpvn(transv, tmpbuf, t - tmpbuf);
+                       sv_catpvn(transv, (char*)tmpbuf, t - tmpbuf);
                    }
                }
                if (*s == 0xff)
@@ -2137,18 +2148,27 @@ pmtrans(OP *o, OP *expr, OP *repl)
                    nextmin = val + 1;
            }
            t = uv_to_utf8(tmpbuf,nextmin);
-           sv_catpvn(transv, tmpbuf, t - tmpbuf);
+           sv_catpvn(transv, (char*)tmpbuf, t - tmpbuf);
            t = uv_to_utf8(tmpbuf, 0x7fffffff);
            sv_catpvn(transv, "\377", 1);
-           sv_catpvn(transv, tmpbuf, t - tmpbuf);
-           t = SvPVX(transv);
+           sv_catpvn(transv, (char*)tmpbuf, t - tmpbuf);
+           t = (U8*)SvPVX(transv);
            tlen = SvCUR(transv);
            tend = t + tlen;
        }
        else if (!rlen && !del) {
            r = t; rlen = tlen; rend = tend;
-           if (!squash && to_utf && from_utf)
-               o->op_private |= OPpTRANS_COUNTONLY;
+       }
+       if (!squash) {
+           if (to_utf && from_utf) {   /* only counting characters */
+               if (t == r || (tlen == rlen && memEQ(t, r, tlen)))
+                   o->op_private |= OPpTRANS_IDENTICAL;
+           }
+           else {      /* straight latin-1 translation */
+               if (tlen == 4 && memEQ(t, "\0\377\303\277", 4) &&
+                   rlen == 4 && memEQ(r, "\0\377\303\277", 4))
+                   o->op_private |= OPpTRANS_IDENTICAL;
+           }
        }
 
        while (t < tend || tfirst <= tlast) {
@@ -2277,7 +2297,7 @@ pmtrans(OP *o, OP *expr, OP *repl)
        if (!rlen && !del) {
            r = t; rlen = tlen;
            if (!squash)
-               o->op_private |= OPpTRANS_COUNTONLY;
+               o->op_private |= OPpTRANS_IDENTICAL;
        }
        for (i = 0; i < 256; i++)
            tbl[i] = -1;
@@ -4001,6 +4021,7 @@ newXS(char *name, void (*subaddr) (CV * _CPERLproto), char *filename)
            if (!PL_initav)
                PL_initav = newAV();
            av_push(PL_initav, (SV *)cv);
+           GvCV(gv) = 0;
        }
     }
     else
@@ -4677,6 +4698,8 @@ ck_index(OP *o)
 {
     if (o->op_flags & OPf_KIDS) {
        OP *kid = cLISTOPo->op_first->op_sibling;       /* get past pushmark */
+       if (kid)
+           kid = kid->op_sibling;                      /* get past "big" */
        if (kid && kid->op_type == OP_CONST)
            fbm_compile(((SVOP*)kid)->op_sv, 0);
     }