https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67194
Bug ID: 67194 Summary: Missed jump thread and false positive from -Wuninitialized Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: law at redhat dot com Target Milestone: --- Extracted from bz55035: Reconfirmed. Nowadays (trunk@221914) also breaks all-gcc for nios2-linux-gnu. Reminds me of bug #36550 Smallish testcase: $ cat reload1.i ; echo EOF /* PR target/55035 */ /* { dg-do compile } */ /* { dg-options "-O2 -W -Wall -Werror" } */ struct rtx_def; typedef struct rtx_def *rtx; enum rtx_code { UNKNOWN, INSN, ASM_INPUT, CLOBBER }; struct rtx_def { enum rtx_code code: 4; }; class rtx_def; class rtx_insn : public rtx_def {}; struct recog_data_d { rtx operand[30]; rtx *operand_loc[30]; rtx *dup_loc[1]; char dup_num[1]; char n_operands; char n_dups; }; extern struct recog_data_d recog_data; extern int get_int(void); void elimination_costs_in_insn (rtx_insn *insn) { int icode = get_int (); int i; rtx orig_operand[30]; rtx orig_dup[30]; if (icode < 0) { if (((enum rtx_code) insn->code) == INSN) __builtin_abort(); return; } for (i = 0; i < recog_data.n_dups; i++) orig_dup[i] = *recog_data.dup_loc[i]; for (i = 0; i < recog_data.n_operands; i++) { orig_operand[i] = recog_data.operand[i]; if (orig_operand[i]->code == CLOBBER) *recog_data.operand_loc[i] = 0; } for (i = 0; i < recog_data.n_dups; i++) *recog_data.dup_loc[i] = *recog_data.operand_loc[(int) recog_data.dup_num[i]]; for (i = 0; i < recog_data.n_dups; i++) *recog_data.dup_loc[i] = orig_dup[i]; } EOF $ g++ -O2 -W -Wall -Werror -c reload1.i -o reload1.o reload1.i: In function ‘void elimination_costs_in_insn(rtx_insn*)’: reload1.i:53:41: error: ‘orig_dup[0]’ may be used uninitialized in this function [-Werror=maybe-uninitialized] *recog_data.dup_loc[i] = orig_dup[i]; ^ cc1plus: all warnings being treated as errors And a second, related testcase: typedef struct rtx_def *rtx; struct recog_data_d { rtx operand; char n_dups; }; rtx *operand_loc; rtx dup_loc; struct recog_data_d recog_data; void elimination_costs_in_insn () { rtx orig_dup; if (recog_data.n_dups) orig_dup = dup_loc; *operand_loc = 0; if (recog_data.n_dups) dup_loc = orig_dup; } A warning is issued even at -O1. If I remove "rtx operand" field from struct recog_data_d (or if I change the type of n_dups to int), then it disappears at -O2 (but still present at -O1). In both cases the -Wuninitialized warning is bogus and points to a miss jump threading opportunity.