Bug 92002 - [10/11 regression] -Wuninitialized warning in gcc/wide-int.cc
Summary: [10/11 regression] -Wuninitialized warning in gcc/wide-int.cc
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: bootstrap (show other bugs)
Version: 10.0
: P2 normal
Target Milestone: 10.3
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
: 95940 (view as bug list)
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2019-10-05 15:16 UTC by Rainer Orth
Modified: 2020-07-23 06:51 UTC (History)
6 users (show)

See Also:
Host:
Target: sparcv9-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-10-07 00:00:00


Attachments
preprocessed tree-ssanames.c (193.25 KB, application/x-bzip)
2019-11-21 10:49 UTC, Rainer Orth
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rainer Orth 2019-10-05 15:16:00 UTC
Within the last week (between 20190927 (r276175) and 20191004 (r276564)),
64-bit Solaris/SPARC bootstrap got broken in stage2:

/vol/gcc/src/hg/trunk/local/gcc/wide-int.cc: In function 'void selftest::test_ops() [with VALUE_TYPE = generic_wide_int<wide_int_storage>]':
/vol/gcc/src/hg/trunk/local/gcc/wide-int.cc:2294:25: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[1]' is used uninitialized in this function [-Werror=uninitialized]
 2294 |   return wi::shwi (i, 32);
      |                         ^
/vol/gcc/src/hg/trunk/local/gcc/wide-int.cc:2294:25: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[2]' is used uninitialized in this function [-Werror=uninitialized]
/vol/gcc/src/hg/trunk/local/gcc/wide-int.cc:2294:25: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[1]' is used uninitialized in this function [-Werror=uninitialized]
 2294 |   return wi::shwi (i, 32);
      |                         ^
/vol/gcc/src/hg/trunk/local/gcc/wide-int.cc:2294:25: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[2]' is used uninitialized in this function [-Werror=uninitialized]
/vol/gcc/src/hg/trunk/local/gcc/wide-int.cc: In function 'void selftest::test_comparisons() [with VALUE_TYPE = generic_wide_int<wide_int_storage>]':
/vol/gcc/src/hg/trunk/local/gcc/wide-int.cc:2294:25: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[1]' is used uninitialized in this function [-Werror=uninitialized]
 2294 |   return wi::shwi (i, 32);
      |                         ^
/vol/gcc/src/hg/trunk/local/gcc/wide-int.cc:2294:25: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[2]' is used uninitialized in this function [-Werror=uninitialized]
/vol/gcc/src/hg/trunk/local/gcc/wide-int.cc:2294:25: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[1]' is used uninitialized in this function [-Werror=uninitialized]
 2294 |   return wi::shwi (i, 32);
      |                       

/vol/gcc/src/hg/trunk/local/gcc/tree-ssanames.c: In function 'wide_int get_nonzero_bits(const_tree)':
/vol/gcc/src/hg/trunk/local/gcc/tree-ssanames.c:527:46: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[1]' may be used uninitialized in this function [-Werror=maybe-uninitialized]
  527 |     | (HOST_WIDE_INT) pi->misalign, precision);
      |                                              ^
/vol/gcc/src/hg/trunk/local/gcc/tree-ssanames.c:527:46: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[2]' may be used uninitialized in this function [-Werror=maybe-uninitialized]
/vol/gcc/src/hg/trunk/local/gcc/tree-ssanames.c:528:37: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[1]' may be used uninitialized in this function [-Werror=maybe-uninitialized]
  528 |       return wi::shwi (-1, precision);
      |                                     ^
/vol/gcc/src/hg/trunk/local/gcc/tree-ssanames.c:528:37: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[2]' may be used uninitialized in this function [-Werror=maybe-uninitialized]
/vol/gcc/src/hg/trunk/local/gcc/tree-ssanames.c:533:35: error: '<anonymous>.generic_wide_int<wide_int_storage>::<anonymous>.wide_int_storage::val[1]' may be used uninitialized in this function [-Werror=maybe-uninitialized]
  533 |     return wi::shwi (-1, precision);
      |                                   ^

I cannot yet make sense of this.
Comment 1 Rainer Orth 2019-10-06 11:37:10 UTC
A reghunt identified this patch as the culprit:

* cif-code.def (MAX_INLINE_INSNS_SINGLE_O2_LIMIT,
        MAX_INLINE_INSNS_AUTO_O2_LIMIT): New.
        * ipa-inline.c (inline_insns_single, inline_insns_auto): New functions.
        (can_inline_edge_by_limits_p): Use it.
        (big_speedup_p): Use PARAM_INLINE_MIN_SPEEDUP_O2.
        (want_inline_small_function_p): Use O2 bounds.
        (edge_badness): LIkewise.
        * opts.c (default_options): Add OPT_finline_functions.
        * params.def (PARAM_INLINE_MIN_SPEEDUP_O2,
        PARAM_MAX_INLINE_INSNS_SINGLE_O2, PARAM_MAX_INLINE_INSNS_AUTO_O2):
        New parameters.
Comment 2 Jan Hubicka 2019-10-06 12:19:30 UTC
It is patch enabling auto-inlining at -O2, so we have another false
positive I guess. I fixed couple of them which reproduced during x86-64
bootstrap for me.
Comment 3 Eric Botcazou 2019-10-07 07:53:12 UTC
Likewise on Linux.
Comment 4 Jakub Jelinek 2019-11-21 10:17:14 UTC
Could you please attach preprocessed source + exact g++ options that trigger it, so it can be analyzed if there is something in uninit that could help it?
Comment 5 Rainer Orth 2019-11-21 10:49:30 UTC
Created attachment 47319 [details]
preprocessed tree-ssanames.c

I'm attaching the preprocessed tree-ssanames.c; wide-int.cc is equally affected
but larger.

The cc1plus command line can be simplified to

$ cc1plus -fpreprocessed tree-ssanames.ii -quiet -mcpu=v9 -O2 -Wall -Werror -o tree-ssanames.s

while the full g++ command is

$ /var/gcc/regression/trunk/11.5-gcc-64/build/./prev-gcc/xg++ -B/var/gcc/regression/trunk/11.5-gcc-64/build/./prev-gcc/ -B/vol/gcc/sparcv9-sun-solaris2.11/bin/ -nostdinc++ -B/var/gcc/regression/trunk/11.5-gcc-64/build/prev-sparcv9-sun-solaris2.11/libstdc++-v3/src/.libs -B/var/gcc/regression/trunk/11.5-gcc-64/build/prev-sparcv9-sun-solaris2.11/libstdc++-v3/libsupc++/.libs  -I/var/gcc/regression/trunk/11.5-gcc-64/build/prev-sparcv9-sun-solaris2.11/libstdc++-v3/include/sparcv9-sun-solaris2.11  -I/var/gcc/regression/trunk/11.5-gcc-64/build/prev-sparcv9-sun-solaris2.11/libstdc++-v3/include  -I/vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++ -L/var/gcc/regression/trunk/11.5-gcc-64/build/prev-sparcv9-sun-solaris2.11/libstdc++-v3/src/.libs -L/var/gcc/regression/trunk/11.5-gcc-64/build/prev-sparcv9-sun-solaris2.11/libstdc++-v3/libsupc++/.libs -fno-PIE -c   -g -O2 -fchecking=1 -DIN_GCC     -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-error=format-diag -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -fno-common -DHAVE_CONFIG_H -I. -I. -I/vol/gcc/src/hg/trunk/local/gcc -I/vol/gcc/src/hg/trunk/local/gcc/. -I/vol/gcc/src/hg/trunk/local/gcc/../include -I/vol/gcc/src/hg/trunk/local/gcc/../libcpp/include -I/vol/gcc/include -I/vol/gcc/include -I/vol/gcc/include  -I/vol/gcc/src/hg/trunk/local/gcc/../libdecnumber -I/vol/gcc/src/hg/trunk/local/gcc/../libdecnumber/dpd -I../libdecnumber -I/vol/gcc/src/hg/trunk/local/gcc/../libbacktrace -I/vol/gcc/include  -o tree-ssanames.o -MT tree-ssanames.o -MMD -MP -MF ./.deps/tree-ssanames.TPo /vol/gcc/src/hg/trunk/local/gcc/tree-ssanames.c
Comment 6 Jakub Jelinek 2019-11-21 13:42:40 UTC
Reduced testcase:
extern void fancy_abort(const char *, int, const char *) __attribute__((__noreturn__)) __attribute__((__cold__));
typedef union tree_node *tree;
typedef const union tree_node *const_tree;
enum signop { SIGNED, };
template <typename T> class generic_wide_int;
class wide_int_storage;
typedef generic_wide_int<wide_int_storage> wide_int;
namespace wi { template <typename T> struct int_traits; }
namespace wi {
template <typename T> unsigned int get_precision(const T &);
template <typename T1, typename T2> void copy(T1 &, const T2 &);
template <typename T1, typename T2> bool eq_p(const T1 &, const T2 &);
struct storage_ref {
  storage_ref(const long *, unsigned int, unsigned int);
  const long *val;
  unsigned int len;
  unsigned int precision;
  unsigned int get_len() const;
  const long *get_val() const;
};
}
inline ::wi::storage_ref::storage_ref(const long *val_in, unsigned int len_in, unsigned int precision_in)
    : val(val_in), len(len_in), precision(precision_in) {}
inline unsigned int wi::storage_ref::get_len() const { return len; }
inline const long *wi::storage_ref::get_val() const { return val; }
template <typename storage> struct generic_wide_int : public storage {
  template <typename T> generic_wide_int(const T &);
  static const bool is_sign_extended = wi::int_traits<generic_wide_int<storage>>::is_sign_extended;
};
template <typename storage>
template <typename T>
inline generic_wide_int<storage>::generic_wide_int(const T &x) : storage(x) {}
namespace wi {
template <typename storage>
struct int_traits<generic_wide_int<storage>> : public wi::int_traits<storage> {
};
}
template <bool SE, bool HDP>
struct wide_int_ref_storage : public wi::storage_ref {
  long scratch[2];
  template <typename T> wide_int_ref_storage(const T &);
};
template <bool SE, bool HDP>
template <typename T>
inline wide_int_ref_storage<SE, HDP>::wide_int_ref_storage(const T &x)
    : storage_ref(wi::int_traits<T>::decompose(scratch, 0, x)) {}
namespace wi {
template <bool SE, bool HDP> struct int_traits<wide_int_ref_storage<SE, HDP>> {
  static const bool host_dependent_precision = HDP;
  static const bool is_sign_extended = SE;
};
}
struct wide_int_storage {
  long val[(((16 * (8)) + 64) / 64)];
  unsigned int len;
  unsigned int precision;
  template <typename T> wide_int_storage(const T &);
  long *write_val();
  void set_len(unsigned int, bool = false);
};
template <typename T> inline wide_int_storage::wide_int_storage(const T &x) {
  generic_wide_int<wide_int_ref_storage<wi::int_traits<T>::is_sign_extended,
                           wi::int_traits<T>::host_dependent_precision>>
      xi(x);
  precision = xi.precision;
  wi::copy(*this, xi);
}
inline long *wide_int_storage::write_val() { return val; }
inline void wide_int_storage::set_len(unsigned int l, bool is_sign_extended) {
  len = l;
}
namespace wi {
struct hwi_with_prec {
  long val;
  unsigned int precision;
  signop sgn;
};
hwi_with_prec shwi(long, unsigned int);
template <> struct int_traits<wi::hwi_with_prec> {
  static const bool host_dependent_precision = false;
  static const bool is_sign_extended = true;
  static wi::storage_ref decompose(long *, unsigned int,
                                   const wi::hwi_with_prec &);
};
}
inline wi::storage_ref wi::int_traits<wi::hwi_with_prec>::decompose(
    long *scratch, unsigned int precision, const wi::hwi_with_prec &x) {
  ((void)(!(precision == x.precision)
          ? fancy_abort("/vol/gcc/src/hg/trunk/local/gcc/wide-int.h", 1700, __FUNCTION__),
          0 : 0));
  scratch[0] = x.val;
  return wi::storage_ref(scratch, 1, precision);
}
template <typename T1, typename T2> inline void wi::copy(T1 &x, const T2 &y) {
  long *xval = x.write_val();
  const long *yval = y.get_val();
  unsigned int len = y.get_len();
  unsigned int i = 0;
  do
    xval[i] = yval[i];
  while (++i < len);
  x.set_len(len, y.is_sign_extended);
};
enum tree_code { ENUMERAL_TYPE, BOOLEAN_TYPE, INTEGER_TYPE, INTEGER_CST, };
struct tree_base { enum tree_code code : 16; };
struct tree_typed { tree type; };
struct tree_type_common { unsigned int precision : 10; };
union tree_node { struct tree_base base; struct tree_typed typed; struct tree_type_common type_common; };
namespace wi {
typedef const generic_wide_int<wide_int_ref_storage<false, false>> tree_to_wide_ref;
tree_to_wide_ref to_wide(const_tree);
}
extern unsigned int element_precision(const_tree);
wide_int get_nonzero_bits(const_tree name) {
  if (((enum tree_code)(name)->base.code) == INTEGER_CST)
    return wi::to_wide(name);
  unsigned int precision = element_precision(name->typed.type);
  return wi::shwi(0, precision);
}
bool ssa_name_has_boolean_range(tree op) {
  if ((op->typed.type->base.code == ENUMERAL_TYPE ||
       op->typed.type->base.code == BOOLEAN_TYPE ||
       op->typed.type->base.code == INTEGER_TYPE) &&
      op->typed.type->type_common.precision > 1 &&
      wi::eq_p(get_nonzero_bits(op), 1))
    return true;
  return false;
}

Doesn't warn on x86_64-linux, I guess there are different SRA decisions.
Comment 7 Jakub Jelinek 2019-11-21 13:52:05 UTC
I guess the problem is in a function that returns wide_int by value and has
return wi::shwi (something, prec);
In *.gimple dump I see
      D.63355 = wi::shwi (-1, precision);
      try
        {
          generic_wide_int<wide_int_storage>::generic_wide_int<wi::hwi_with_prec> (&D.63356, &D.63355);
          try
            {
              D.69890 = D.63356;
              return D.69890;
            }
where
  struct hwi_with_prec D.63355;
  struct wide_int D.63356;
  struct wide_int D.69890;
where D.69890 is the RESULT_DECL.
Makes me wonder why the wide_int isn't constructed directly into the RESULT_DECL, but it is constructed into a temporary and that one is then bitwise copied.
I thought generic_wide_int copy constructor shall invoke wide_int_storage copy constructor that should invoke wi::copy.
Comment 8 Richard Biener 2020-01-17 10:35:54 UTC
Did this somehow get fixed (the bootstrap?) or require some nonstandard configuration?
Comment 9 ro@CeBiTec.Uni-Bielefeld.DE 2020-01-17 10:39:20 UTC
> --- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
> Did this somehow get fixed (the bootstrap?) or require some nonstandard
> configuration?

Not at all.  I still cannot make any sense of the warning, but hacked
around it by disabling -Werror for the affected files in t-sparc to get
any work done:

diff --git a/gcc/config/sparc/t-sparc b/gcc/config/sparc/t-sparc
--- a/gcc/config/sparc/t-sparc
+++ b/gcc/config/sparc/t-sparc
@@ -27,3 +27,7 @@ sparc-c.o: $(srcdir)/config/sparc/sparc-
 sparc-d.o: $(srcdir)/config/sparc/sparc-d.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+
+# Hack around PR bootstrap/92002.
+tree-ssanames.o-warn += -Wno-error
+wide-int.o-warn += -Wno-error
Comment 10 Jakub Jelinek 2020-01-17 13:17:10 UTC
-Wno-error=uninitialized might be more appropriate for the workaround.
Comment 11 ro@CeBiTec.Uni-Bielefeld.DE 2020-01-26 20:49:48 UTC
> --- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
> -Wno-error=uninitialized might be more appropriate for the workaround.

In fact one needs both -Wno-error=uninitialized and
-Wno-error=maybe-uninitialized
Comment 12 Eric Botcazou 2020-01-28 11:50:48 UTC
> diff --git a/gcc/config/sparc/t-sparc b/gcc/config/sparc/t-sparc
> --- a/gcc/config/sparc/t-sparc
> +++ b/gcc/config/sparc/t-sparc
> @@ -27,3 +27,7 @@ sparc-c.o: $(srcdir)/config/sparc/sparc-
>  sparc-d.o: $(srcdir)/config/sparc/sparc-d.c
>  	$(COMPILE) $<
>  	$(POSTCOMPILE)
> +
> +# Hack around PR bootstrap/92002.
> +tree-ssanames.o-warn += -Wno-error
> +wide-int.o-warn += -Wno-error

On Linux, you need it for simplify-rtx.o too.
Comment 13 Jakub Jelinek 2020-05-07 11:56:11 UTC
GCC 10.1 has been released.
Comment 14 Eric Botcazou 2020-07-02 06:57:47 UTC
*** Bug 95940 has been marked as a duplicate of this bug. ***
Comment 15 Richard Biener 2020-07-23 06:51:53 UTC
GCC 10.2 is released, adjusting target milestone.