[Bug bootstrap/92002] [10 regression] -Wuninitialized warning in gcc/wide-int.cc

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Nov 21 13:42:00 GMT 2019


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

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
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.


More information about the Gcc-bugs mailing list