Fix gcc array subscript above bounds warning
authorNed Bass <bass6@llnl.gov>
Wed, 26 Dec 2012 22:56:41 +0000 (14:56 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 7 Jan 2013 19:21:52 +0000 (11:21 -0800)
In a debug build, certain GCC versions flag an array bounds warning in
the below code from dnode_sync.c

    } else {
            int i;
            ASSERT(dn->dn_next_nblkptr[txgoff] < dnp->dn_nblkptr);
            /* the blkptrs we are losing better be unallocated */
            for (i = dn->dn_next_nblkptr[txgoff];
                i < dnp->dn_nblkptr; i++)
                    ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[i]));

This usage is in fact safe, since the ASSERT ensures the index does
not exceed to maximum possible number of block pointers. However gcc
can't determine that the assignment 'i = dn->dn_next_nblkptr[txgoff];'
falls within the array bounds so it issues a warning.  To avoid this,
initialize i to zero to make gcc happy but skip the elements before
dn->dn_next_nblkptr[txgoff] in the loop body.  Since a dnode contains
at most 3 block pointers this overhead should be negligible.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #950

module/zfs/dnode_sync.c

index af636dc..f2dda86 100644 (file)
@@ -666,9 +666,10 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx)
                        int i;
                        ASSERT(dn->dn_next_nblkptr[txgoff] < dnp->dn_nblkptr);
                        /* the blkptrs we are losing better be unallocated */
-                       for (i = dn->dn_next_nblkptr[txgoff];
-                           i < dnp->dn_nblkptr; i++)
-                               ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[i]));
+                       for (i = 0; i < dnp->dn_nblkptr; i++) {
+                               if (i >= dn->dn_next_nblkptr[txgoff])
+                                       ASSERT(BP_IS_HOLE(&dnp->dn_blkptr[i]));
+                       }
 #endif
                }
                mutex_enter(&dn->dn_mtx);