https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92433

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Reduced testcase that results in the warning also on x86_64-linux with -O2
-Wall:
struct S { void *p; struct S *q; };
void bar (int, ...);

void
foo (struct S *x, int n, int y)
{
  void *arg_type[3];
  for (int i = 0; i < n; i++)
    {
      arg_type[i] = x->p;
      x = x->q;
    }
  if (y)
    {
      void *t = arg_type[2]; arg_type[2] = arg_type[1]; arg_type[1] = t;
    }
  switch (n)
    {
    case 0: bar (0); break;
    case 1: bar (1, arg_type[0]); break;
    case 2: bar (2, arg_type[0], arg_type[1]); break;
    case 3: bar (3, arg_type[0], arg_type[1], arg_type[2]); break;
    }
}

Using if (n == 3 && y) makes the warning go away.
The compiler indeed doesn't know if y implies n == 3, although the caller
guarantees it.

So, we could do:
--- gcc/config/rs6000/rs6000-c.c.jj     2019-08-27 12:26:30.115019661 +0200
+++ gcc/config/rs6000/rs6000-c.c        2019-11-11 10:12:00.954282097 +0100
@@ -6076,13 +6076,13 @@ altivec_build_resolved_builtin (tree *ar
      condition (LT vs. EQ, which is recognizable by bit 1 of the first
      argument) is reversed.  Patch the arguments here before building
      the resolved CALL_EXPR.  */
-  if (desc->code == ALTIVEC_BUILTIN_VEC_VCMPGE_P
+  if (n == 3
+      && desc->code == ALTIVEC_BUILTIN_VEC_VCMPGE_P
       && desc->overloaded_code != ALTIVEC_BUILTIN_VCMPGEFP_P
       && desc->overloaded_code != VSX_BUILTIN_XVCMPGEDP_P)
     {
-      tree t;
-      t = args[2], args[2] = args[1], args[1] = t;
-      t = arg_type[2], arg_type[2] = arg_type[1], arg_type[1] = t;
+      std::swap (args[1], args[2]);
+      std::swap (arg_type[1], arg_type[2]);

       args[0] = fold_build2 (BIT_XOR_EXPR, TREE_TYPE (args[0]), args[0],
                             build_int_cst (NULL_TREE, 2));
to make it clear to the compiler that VCMPGE_P has 3 arguments and that it is
actually safe to use all of them, or of course we could clear arg_type first.

I don't find the may be used uninitialized warning wrong (at least not
completely) when the compiler sees a possible code path where it is
uninitialized (desc->code == ALTIVEC_BULTIN_VEC_VCMPGE_P with n < 3).

Reply via email to