Skip to content

Commit 71c8f9c

Browse files
arndbmiquelraynal
authored andcommitted
mtd: spi-nor: avoid holes in struct spi_mem_op
gcc gets confused when -ftrivial-auto-var-init=pattern is used on sparse bit fields such as 'struct spi_mem_op', which caused the previous false positive warning about an uninitialized variable: drivers/mtd/spi-nor/spansion.c: error: 'op' is used uninitialized [-Werror=uninitialized] In fact, the variable is fully initialized and gcc does not see it being used, so the warning is entirely bogus. The problem appears to be a misoptimization in the initialization of single bit fields when the rest of the bytes are not initialized. A previous workaround added another initialization, which ended up shutting up the warning in spansion.c, though it apparently still happens in other files as reported by Peter Foley in the gcc bugzilla. The workaround of adding a fake initialization seems particularly bad because it would set values that can never be correct but prevent the compiler from warning about actually missing initializations. Revert the broken workaround and instead pad the structure to only have bitfields that add up to full bytes, which should avoid this behavior in all drivers. I also filed a new bug against gcc with what I found, so this can hopefully be addressed in future gcc releases. At the moment, only gcc-12 and gcc-13 are affected. Cc: Peter Foley <pefoley2@pefoley.com> Cc: Pedro Falcato <pedro.falcato@gmail.com> Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110743 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108402 Link: https://godbolt.org/z/efMMsG1Kx Fixes: 420c449 ("mtd: spi-nor: spansion: make sure local struct does not contain garbage") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Mark Brown <broonie@kernel.org> Acked-by: Tudor Ambarus <tudor.ambarus@linaro.org> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20230719190045.4007391-1-arnd@kernel.org
1 parent d3053b4 commit 71c8f9c

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

drivers/mtd/spi-nor/spansion.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ static int cypress_nor_determine_addr_mode_by_sr1(struct spi_nor *nor,
361361
*/
362362
static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor)
363363
{
364-
struct spi_mem_op op = {};
364+
struct spi_mem_op op;
365365
u8 addr_mode;
366366
int ret;
367367

@@ -492,7 +492,7 @@ s25fs256t_post_bfpt_fixup(struct spi_nor *nor,
492492
const struct sfdp_parameter_header *bfpt_header,
493493
const struct sfdp_bfpt *bfpt)
494494
{
495-
struct spi_mem_op op = {};
495+
struct spi_mem_op op;
496496
int ret;
497497

498498
ret = cypress_nor_set_addr_mode_nbytes(nor);

include/linux/spi/spi-mem.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,26 +101,30 @@ struct spi_mem_op {
101101
u8 nbytes;
102102
u8 buswidth;
103103
u8 dtr : 1;
104+
u8 __pad : 7;
104105
u16 opcode;
105106
} cmd;
106107

107108
struct {
108109
u8 nbytes;
109110
u8 buswidth;
110111
u8 dtr : 1;
112+
u8 __pad : 7;
111113
u64 val;
112114
} addr;
113115

114116
struct {
115117
u8 nbytes;
116118
u8 buswidth;
117119
u8 dtr : 1;
120+
u8 __pad : 7;
118121
} dummy;
119122

120123
struct {
121124
u8 buswidth;
122125
u8 dtr : 1;
123126
u8 ecc : 1;
127+
u8 __pad : 6;
124128
enum spi_mem_data_dir dir;
125129
unsigned int nbytes;
126130
union {

0 commit comments

Comments
 (0)