PR tree-optimization/90635 * vr-values.c (simplify_stmt_using_ranges): Simplify V_C_E into NOP_EXPR in some cases. * g++.dg/warn/Wuninitialized-11.C: New test. diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-11.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-11.C new file mode 100644 index 00000000000..8e3782264bb --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-11.C @@ -0,0 +1,46 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-O2 -Wuninitialized" } + +using size_t = decltype(sizeof(1)); +inline void *operator new (size_t, void *p) { return p; } +template +struct optional +{ + optional () : m_dummy (), live (false) {} + void emplace () { new (&m_item) T (); live = true; } + ~optional () { if (live) m_item.~T (); } + + union + { + struct {} m_dummy; + T m_item; + }; + bool live; +}; + + +extern int get (); +extern void set (int); + +struct A +{ + A () : m (get ()) {} + ~A () { set (m); } + + int m; +}; + +struct B +{ + B (); + ~B (); +}; + +void func () +{ + optional maybe_a; + optional maybe_b; + + maybe_a.emplace (); + maybe_b.emplace (); +} diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 2e3a0788710..bfd3f4f2cea 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -4308,6 +4308,54 @@ vr_values::simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) return simplify_bit_ops_using_ranges (gsi, stmt); break; + + case VIEW_CONVERT_EXPR: + /* If we're converting an object with a range which is + directly representable in the final type, then just + turn the VIEW_CONVERT_EXPR into a NOP_EXPR. + + Various optimizers/analyzers handle the NOP_EXPR + better than VIEW_CONVERT_EXPR. */ + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME) + { + const value_range_equiv *vr + = get_value_range (TREE_OPERAND (rhs1, 0)); + if (vr->kind () == VR_RANGE) + { + /* See if the min and max values convert to themselves. */ + tree min = vr->min (); + tree max = vr->min (); + tree min_converted = const_unop (VIEW_CONVERT_EXPR, + TREE_TYPE (lhs), + min); + tree max_converted = const_unop (VIEW_CONVERT_EXPR, + TREE_TYPE (lhs), + max); + if (TREE_CODE (min) == INTEGER_CST + && TREE_CODE (max) == INTEGER_CST + && min_converted + && max_converted + && TREE_CODE (min_converted) == INTEGER_CST + && TREE_CODE (max_converted) == INTEGER_CST + /* These may not be strictly necessary, but to be safe + do not do this optimization if the original or + converted min/max have their sign bit set. */ + && tree_int_cst_sgn (min) != -1 + && tree_int_cst_sgn (min_converted) != -1 + && tree_int_cst_sgn (max) != -1 + && tree_int_cst_sgn (max_converted) != -1 + && operand_equal_p (min, min_converted, OEP_ONLY_CONST) + && operand_equal_p (max, max_converted, OEP_ONLY_CONST)) + { + gimple_assign_set_rhs_code (stmt, NOP_EXPR); + gimple_assign_set_rhs1 (stmt, TREE_OPERAND (rhs1, 0)); + update_stmt (stmt); + return true; + } + } + } + break; + CASE_CONVERT: if (TREE_CODE (rhs1) == SSA_NAME && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))