This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
sprinkle NOTREACHED and FALLTHROUGH
authorDavid Mitchell <davem@iabyn.com>
Thu, 5 Mar 2015 11:44:37 +0000 (11:44 +0000)
committerDavid Mitchell <davem@iabyn.com>
Thu, 5 Mar 2015 11:51:17 +0000 (11:51 +0000)
Coverity complains bitterly about many switch statements in lots of files.

Many of these are of the form:

    case FOO:
        ...
        goto baz;
    case BAR:
        ....

and something as smart as Coverity shouldn't really be complaining about
a missing 'break' when the last statement of the previous branch is an
unconditional goto/return/continue. But I've shoved in a bunch of
'NOTREACHED' to hopefully shut it up.

Missing 'FALLTHROUGH' comments were more reasonable, and I've added them
where appropriate.

The only confusing one was cx_dup(), where the various CXt_LOOP_ branches
all fell through to the next one, and it took a while to figure out that
those weren't bugs.

dump.c
ext/B/B.pm
ext/B/B.xs
op.c
perl.c
sv.c

diff --git a/dump.c b/dump.c
index 8d2f95b..33bd527 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -2359,38 +2359,48 @@ Perl_multideref_stringify(pTHX_ const OP *o, CV *cv)
         case MDEREF_reload:
             actions = (++items)->uv;
             continue;
+            NOT_REACHED; /* NOTREACHED */
 
         case MDEREF_HV_padhv_helem:
             is_hash = TRUE;
+            /* FALLTHROUGH */
         case MDEREF_AV_padav_aelem:
             derefs = 1;
             S_append_padvar(aTHX_ (++items)->pad_offset, cv, out, 1, 0, 1);
             goto do_elem;
+            NOT_REACHED; /* NOTREACHED */
 
         case MDEREF_HV_gvhv_helem:
             is_hash = TRUE;
+            /* FALLTHROUGH */
         case MDEREF_AV_gvav_aelem:
             derefs = 1;
             sv = ITEM_SV(++items);
             S_append_gv_name(aTHX_ (GV*)sv, out);
             goto do_elem;
+            NOT_REACHED; /* NOTREACHED */
 
         case MDEREF_HV_gvsv_vivify_rv2hv_helem:
             is_hash = TRUE;
+            /* FALLTHROUGH */
         case MDEREF_AV_gvsv_vivify_rv2av_aelem:
             sv = ITEM_SV(++items);
             S_append_gv_name(aTHX_ (GV*)sv, out);
             goto do_vivify_rv2xv_elem;
+            NOT_REACHED; /* NOTREACHED */
 
         case MDEREF_HV_padsv_vivify_rv2hv_helem:
             is_hash = TRUE;
+            /* FALLTHROUGH */
         case MDEREF_AV_padsv_vivify_rv2av_aelem:
             S_append_padvar(aTHX_ (++items)->pad_offset, cv, out, 1, 0, 1);
             goto do_vivify_rv2xv_elem;
+            NOT_REACHED; /* NOTREACHED */
 
         case MDEREF_HV_pop_rv2hv_helem:
         case MDEREF_HV_vivify_rv2hv_helem:
             is_hash = TRUE;
+            /* FALLTHROUGH */
         do_vivify_rv2xv_elem:
         case MDEREF_AV_pop_rv2av_aelem:
         case MDEREF_AV_vivify_rv2av_aelem:
index 5deaa2c..e8c45ee 100644 (file)
@@ -15,7 +15,7 @@ require Exporter;
 # walkoptree comes from B.xs
 
 BEGIN {
-    $B::VERSION = '1.56';
+    $B::VERSION = '1.57';
     @B::EXPORT_OK = ();
 
     # Our BOOT code needs $VERSION set, and will append to @EXPORT_OK.
index 41518d8..b9885c3 100644 (file)
@@ -1418,36 +1418,46 @@ aux_list(o, cv)
                         actions = (++items)->uv;
                         PUSHs(sv_2mortal(newSVuv(actions)));
                         continue;
+                        NOT_REACHED; /* NOTREACHED */
 
                     case MDEREF_HV_padhv_helem:
                         is_hash = TRUE;
+                        /* FALLTHROUGH */
                     case MDEREF_AV_padav_aelem:
                         PUSHs(sv_2mortal(newSVuv((++items)->pad_offset)));
                         goto do_elem;
+                        NOT_REACHED; /* NOTREACHED */
 
                     case MDEREF_HV_gvhv_helem:
                         is_hash = TRUE;
+                        /* FALLTHROUGH */
                     case MDEREF_AV_gvav_aelem:
                         sv = ITEM_SV(++items);
                         PUSHs(make_sv_object(aTHX_ sv));
                         goto do_elem;
+                        NOT_REACHED; /* NOTREACHED */
 
                     case MDEREF_HV_gvsv_vivify_rv2hv_helem:
                         is_hash = TRUE;
+                        /* FALLTHROUGH */
                     case MDEREF_AV_gvsv_vivify_rv2av_aelem:
                         sv = ITEM_SV(++items);
                         PUSHs(make_sv_object(aTHX_ sv));
                         goto do_vivify_rv2xv_elem;
+                        NOT_REACHED; /* NOTREACHED */
 
                     case MDEREF_HV_padsv_vivify_rv2hv_helem:
                         is_hash = TRUE;
+                        /* FALLTHROUGH */
                     case MDEREF_AV_padsv_vivify_rv2av_aelem:
                         PUSHs(sv_2mortal(newSVuv((++items)->pad_offset)));
                         goto do_vivify_rv2xv_elem;
+                        NOT_REACHED; /* NOTREACHED */
 
                     case MDEREF_HV_pop_rv2hv_helem:
                     case MDEREF_HV_vivify_rv2hv_helem:
                         is_hash = TRUE;
+                        /* FALLTHROUGH */
                     do_vivify_rv2xv_elem:
                     case MDEREF_AV_pop_rv2av_aelem:
                     case MDEREF_AV_vivify_rv2av_aelem:
diff --git a/op.c b/op.c
index 5f25121..9ddfb9b 100644 (file)
--- a/op.c
+++ b/op.c
@@ -10650,8 +10650,10 @@ Perl_ck_refassign(pTHX_ OP *o)
     case OP_RV2AV:
        o->op_private |= OPpLVREF_AV;
        goto checkgv;
+        NOT_REACHED; /* NOTREACHED */
     case OP_RV2HV:
        o->op_private |= OPpLVREF_HV;
+        /* FALLTHROUGH */
     case OP_RV2SV:
       checkgv:
        if (cUNOPx(varop)->op_first->op_type != OP_GV) goto bad;
diff --git a/perl.c b/perl.c
index d41ebed..1a603ae 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -3206,9 +3206,12 @@ Perl_moreswitches(pTHX_ const char *s)
        for (s++; isWORDCHAR(*s); s++) ;
 #endif
        return s;
+        NOT_REACHED; /* NOTREACHED */
     }  
     case 'h':
        usage();
+        NOT_REACHED; /* NOTREACHED */
+
     case 'i':
        Safefree(PL_inplace);
 #if defined(__CYGWIN__) /* do backup extension automagically */
diff --git a/sv.c b/sv.c
index 4b797fe..de01831 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1425,6 +1425,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type)
           no route from NV to PVIV, NOK can never be true  */
        assert(!SvNOKp(sv));
        assert(!SvNOK(sv));
+        /* FALLTHROUGH */
     case SVt_PVIO:
     case SVt_PVFM:
     case SVt_PVGV:
@@ -6675,6 +6676,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
            else if (LvTYPE(sv) != 't') /* unless tie: unrefcnted fake SV**  */
                SvREFCNT_dec(LvTARG(sv));
            if (isREGEXP(sv)) goto freeregexp;
+            /* FALLTHROUGH */
        case SVt_PVGV:
            if (isGV_with_GP(sv)) {
                if(GvCVu((const GV *)sv) && (stash = GvSTASH(MUTABLE_GV(sv)))
@@ -6699,6 +6701,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
                PL_statgv = NULL;
             else if ((const GV *)sv == PL_stderrgv)
                 PL_stderrgv = NULL;
+            /* FALLTHROUGH */
        case SVt_PVMG:
        case SVt_PVNV:
        case SVt_PVIV:
@@ -13880,17 +13883,22 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param)
            case CXt_LOOP_LAZYSV:
                ncx->blk_loop.state_u.lazysv.end
                    = sv_dup_inc(ncx->blk_loop.state_u.lazysv.end, param);
-               /* We are taking advantage of av_dup_inc and sv_dup_inc
-                  actually being the same function, and order equivalence of
-                  the two unions.
+                /* Fallthrough: duplicate lazysv.cur by using the ary.ary
+                   duplication code instead.
+                   We are taking advantage of (1) av_dup_inc and sv_dup_inc
+                   actually being the same function, and (2) order
+                   equivalence of the two unions.
                   We can assert the later [but only at run time :-(]  */
                assert ((void *) &ncx->blk_loop.state_u.ary.ary ==
                        (void *) &ncx->blk_loop.state_u.lazysv.cur);
+                /* FALLTHROUGH */
            case CXt_LOOP_FOR:
                ncx->blk_loop.state_u.ary.ary
                    = av_dup_inc(ncx->blk_loop.state_u.ary.ary, param);
+                /* FALLTHROUGH */
            case CXt_LOOP_LAZYIV:
            case CXt_LOOP_PLAIN:
+                /* code common to all CXt_LOOP_* types */
                if (CxPADLOOP(ncx)) {
                    ncx->blk_loop.itervar_u.oldcomppad
                        = (PAD*)ptr_table_fetch(PL_ptr_table,