* I need help with a sparse warning
@ 2008-09-12 2:13 Larry Finger
2008-09-12 2:32 ` Steven Noonan
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Larry Finger @ 2008-09-12 2:13 UTC (permalink / raw)
To: LKML; +Cc: wireless
In file drivers/net/wireless/p54/p54common.c, the statement
priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]);
generates the sparse warning
.../p54common.c:185:29: warning: cast to restricted __le16
where bootrec->data is u32, and priv->rx_mtu is u16.
What should be done to eliminate this warning?
Thanks,
Larry
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: I need help with a sparse warning 2008-09-12 2:13 I need help with a sparse warning Larry Finger @ 2008-09-12 2:32 ` Steven Noonan 2008-09-12 2:58 ` Larry Finger 2008-09-12 2:39 ` Roland Dreier 2008-09-12 2:44 ` Alexey Dobriyan 2 siblings, 1 reply; 10+ messages in thread From: Steven Noonan @ 2008-09-12 2:32 UTC (permalink / raw) To: Larry Finger; +Cc: LKML, wireless On Thu, Sep 11, 2008 at 7:13 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote: > In file drivers/net/wireless/p54/p54common.c, the statement > > priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]); > > generates the sparse warning > > .../p54common.c:185:29: warning: cast to restricted __le16 > > where bootrec->data is u32, and priv->rx_mtu is u16. > (Whoops, didn't CC the mailing lists. Sorry about the double-message, Larry.) If priv->rx_mtu is u16, I'm surprised it doesn't get noisy about the size_t cast. Unless the machine it's being compiled on is 16-bit, that should throw a truncation warning, because size_t should be a 32-bit integer on 32-bit machines (typically). I think if you change the (__le16) cast to (__le16 __force) it will stop warning you about that particular issue. - Steven ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning 2008-09-12 2:32 ` Steven Noonan @ 2008-09-12 2:58 ` Larry Finger 2008-09-12 3:04 ` Roland Dreier 2008-09-12 15:25 ` Michael Buesch 0 siblings, 2 replies; 10+ messages in thread From: Larry Finger @ 2008-09-12 2:58 UTC (permalink / raw) To: Steven Noonan; +Cc: LKML, wireless Steven Noonan wrote: > On Thu, Sep 11, 2008 at 7:13 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote: >> In file drivers/net/wireless/p54/p54common.c, the statement >> >> priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]); >> >> generates the sparse warning >> >> .../p54common.c:185:29: warning: cast to restricted __le16 >> >> where bootrec->data is u32, and priv->rx_mtu is u16. >> > > (Whoops, didn't CC the mailing lists. Sorry about the double-message, Larry.) > > If priv->rx_mtu is u16, I'm surprised it doesn't get noisy about the > size_t cast. Unless the machine it's being compiled on is 16-bit, that > should throw a truncation warning, because size_t should be a 32-bit > integer on 32-bit machines (typically). > > I think if you change the (__le16) cast to (__le16 __force) it will > stop warning you about that particular issue. This one gets rid of the sparse warning. priv->rx_mtu = le16_to_cpu((__le16 __force) bootrec->data[10]); Thanks, Larry ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning 2008-09-12 2:58 ` Larry Finger @ 2008-09-12 3:04 ` Roland Dreier 2008-09-12 3:07 ` Larry Finger 2008-09-12 15:25 ` Michael Buesch 1 sibling, 1 reply; 10+ messages in thread From: Roland Dreier @ 2008-09-12 3:04 UTC (permalink / raw) To: Larry Finger; +Cc: Steven Noonan, LKML, wireless > This one gets rid of the sparse warning. > > priv->rx_mtu = le16_to_cpu((__le16 __force) > bootrec->data[10]); Yes but does it actually work on both big and little endian systems? (See my previous email) - R. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning 2008-09-12 3:04 ` Roland Dreier @ 2008-09-12 3:07 ` Larry Finger 0 siblings, 0 replies; 10+ messages in thread From: Larry Finger @ 2008-09-12 3:07 UTC (permalink / raw) To: Roland Dreier; +Cc: Steven Noonan, LKML, wireless Roland Dreier wrote: > > This one gets rid of the sparse warning. > > > > priv->rx_mtu = le16_to_cpu((__le16 __force) > > bootrec->data[10]); > > Yes but does it actually work on both big and little endian systems? > (See my previous email) I don't know, but as my previous email stated, the code could not possibly have worked on a big-endian system before I started the sparse cleanup. I don't have access to anything but little-endian hardware. Larry ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning 2008-09-12 2:58 ` Larry Finger 2008-09-12 3:04 ` Roland Dreier @ 2008-09-12 15:25 ` Michael Buesch 1 sibling, 0 replies; 10+ messages in thread From: Michael Buesch @ 2008-09-12 15:25 UTC (permalink / raw) To: Larry Finger; +Cc: Steven Noonan, LKML, wireless On Friday 12 September 2008, Larry Finger wrote: > Steven Noonan wrote: > > On Thu, Sep 11, 2008 at 7:13 PM, Larry Finger <Larry.Finger@lwfinger.net> wrote: > >> In file drivers/net/wireless/p54/p54common.c, the statement > >> > >> priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]); > >> > >> generates the sparse warning > >> > >> .../p54common.c:185:29: warning: cast to restricted __le16 > >> > >> where bootrec->data is u32, and priv->rx_mtu is u16. > >> > > > > (Whoops, didn't CC the mailing lists. Sorry about the double-message, Larry.) > > > > If priv->rx_mtu is u16, I'm surprised it doesn't get noisy about the > > size_t cast. Unless the machine it's being compiled on is 16-bit, that > > should throw a truncation warning, because size_t should be a 32-bit > > integer on 32-bit machines (typically). > > > > I think if you change the (__le16) cast to (__le16 __force) it will > > stop warning you about that particular issue. > > This one gets rid of the sparse warning. > > priv->rx_mtu = le16_to_cpu((__le16 __force) > bootrec->data[10]); I think you should rather fix the type of bootrec->data. If it is u32, but the data in fact is __le16, please fix the struct instead of adding dangerous casts. Note that this is especially dangerous, because you cast between different typesizes and endianesses at the same time. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning 2008-09-12 2:13 I need help with a sparse warning Larry Finger 2008-09-12 2:32 ` Steven Noonan @ 2008-09-12 2:39 ` Roland Dreier 2008-09-12 3:05 ` Larry Finger 2008-09-12 2:44 ` Alexey Dobriyan 2 siblings, 1 reply; 10+ messages in thread From: Roland Dreier @ 2008-09-12 2:39 UTC (permalink / raw) To: Larry Finger; +Cc: LKML, wireless > In file drivers/net/wireless/p54/p54common.c, the statement > > priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]); [I don't see this code in Linus's tree] > > generates the sparse warning > > .../p54common.c:185:29: warning: cast to restricted __le16 > > where bootrec->data is u32, and priv->rx_mtu is u16. > > What should be done to eliminate this warning? the code in question looks buggy to me. Since bootrec->data[10] is u32, casting it to a 16-bit type is going to take a different 2 bytes out of the 4 bytes depending on the endianness of the system the driver is built for. And I assume you are parsing some fixed-layout thing that the firmware is giving you or something like that. I would guess you want something like: priv->rx_mtu = le16_to_cpu(((__force __le16 *) bootrec->data)[20]); (__force is what shuts up sparse, and as far as I can see, the size_t cast is useless, since the result will be promoted anyway) - R. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning 2008-09-12 2:39 ` Roland Dreier @ 2008-09-12 3:05 ` Larry Finger 2008-09-12 17:12 ` Pavel Roskin 0 siblings, 1 reply; 10+ messages in thread From: Larry Finger @ 2008-09-12 3:05 UTC (permalink / raw) To: Roland Dreier; +Cc: LKML, wireless Roland Dreier wrote: > > In file drivers/net/wireless/p54/p54common.c, the statement > > > > priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]); > > [I don't see this code in Linus's tree] It is in wireless-testing. > > the code in question looks buggy to me. Since bootrec->data[10] is u32, > casting it to a 16-bit type is going to take a different 2 bytes out of > the 4 bytes depending on the endianness of the system the driver is > built for. And I assume you are parsing some fixed-layout thing that > the firmware is giving you or something like that. > > I would guess you want something like: > > priv->rx_mtu = le16_to_cpu(((__force __le16 *) bootrec->data)[20]); > > (__force is what shuts up sparse, and as far as I can see, the size_t > cast is useless, since the result will be promoted anyway) Yes, that one works. As you suspected, this section is parsing data from the firmware. When I started, there were 18 sparse warnings, and a number of them were accesses of little-endian variables without an appropriate leXX_to_cpu() conversion. Obviously, this code has never been tested on a big-endian machine. Thanks, Larry ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning 2008-09-12 3:05 ` Larry Finger @ 2008-09-12 17:12 ` Pavel Roskin 0 siblings, 0 replies; 10+ messages in thread From: Pavel Roskin @ 2008-09-12 17:12 UTC (permalink / raw) To: Larry Finger; +Cc: Roland Dreier, LKML, wireless On Thu, 2008-09-11 at 22:05 -0500, Larry Finger wrote: > > I would guess you want something like: > > > > priv->rx_mtu = le16_to_cpu(((__force __le16 *) bootrec->data)[20]); > > > > (__force is what shuts up sparse, and as far as I can see, the size_t > > cast is useless, since the result will be promoted anyway) > > Yes, that one works. As you suspected, this section is parsing data > from the firmware. I believe __force should be the last resort. If you want to read a 16-bit little endian value at the given offset, I suggest that you use le16_to_cpup(), which operates on pointers and does the cast for you. A better but more elaborate solution would be to define a structure that would have __le16 rx_mtu at the offset 40. Then you can cast bootrec to that structure and apply le16_to_cpu() to that field. -- Regards, Pavel Roskin ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: I need help with a sparse warning 2008-09-12 2:13 I need help with a sparse warning Larry Finger 2008-09-12 2:32 ` Steven Noonan 2008-09-12 2:39 ` Roland Dreier @ 2008-09-12 2:44 ` Alexey Dobriyan 2 siblings, 0 replies; 10+ messages in thread From: Alexey Dobriyan @ 2008-09-12 2:44 UTC (permalink / raw) To: Larry Finger; +Cc: LKML, wireless On Thu, Sep 11, 2008 at 09:13:20PM -0500, Larry Finger wrote: > In file drivers/net/wireless/p54/p54common.c, the statement > > priv->rx_mtu = (size_t) le16_to_cpu((__le16)bootrec->data[10]); > > generates the sparse warning > > .../p54common.c:185:29: warning: cast to restricted __le16 > > where bootrec->data is u32, and priv->rx_mtu is u16. > > What should be done to eliminate this warning? What is the intent? MTU is 2-byte little-endian starting at 40-th byte? Oh, and size_t cast is pointless. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2008-09-12 17:12 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-09-12 2:13 I need help with a sparse warning Larry Finger 2008-09-12 2:32 ` Steven Noonan 2008-09-12 2:58 ` Larry Finger 2008-09-12 3:04 ` Roland Dreier 2008-09-12 3:07 ` Larry Finger 2008-09-12 15:25 ` Michael Buesch 2008-09-12 2:39 ` Roland Dreier 2008-09-12 3:05 ` Larry Finger 2008-09-12 17:12 ` Pavel Roskin 2008-09-12 2:44 ` Alexey Dobriyan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox