Hi,

while compiling a kernel with a newer clang version it stumbled upon
the following code starting line 1020 in sys/scsi/st.c:

        struct scsi_rw_tape *cmd;

        ...

        /*
         * Handle "fixed-block-mode" tape drives by using the
         * block count instead of the length.
         */
        if (st->flags & ST_FIXEDBLOCKS) {
                cmd->byte2 |= SRW_FIXED;
                _lto3b(bp->b_bcount / st->blksize, cmd->len);
        } else
                _lto3b(bp->b_bcount, cmd->len);

        if (st->media_blkno != -1) {
                /* Update block count now, errors will set it to -1. */
                if (st->flags & ST_FIXEDBLOCKS)
                        st->media_blkno += _3btol(cmd->len);
                else if (cmd->len != 0)
                        st->media_blkno++;
        }

The interesting bit it complains about is the "if (cmd->len != 0)".

If cmd->len was an integer, that wouldn't be bad, but it somehow is not:

struct scsi_rw_tape {
        u_int8_t opcode;
        u_int8_t byte2;
#define SRW_FIXED               0x01
        u_int8_t len[3];
        u_int8_t control;
};

So, cmd->len is an array embedded in a struct, not an integer or
a pointer to something else.

I really do wonder if GCC is doing the right thing there.
It's probably better to just use bp->b_count from a few lines
above instead of accessing cmd->len like that.

\Patrick

Reply via email to