This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/67194] New: Missed jump thread and false positive from -Wuninitialized


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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]