[PATCH] vrp: Handle VCE in vrp_simplify_cond_using_ranges [PR80635]

Jakub Jelinek jakub@redhat.com
Wed Feb 24 18:46:19 GMT 2021


On Wed, Feb 24, 2021 at 01:32:02PM +0100, Richard Biener wrote:
> Small comment about the patch below, which otherwise is OK:
> 
> I think that !INTEGRAL_TYPE_P (TREE_TYPE (innerop)) is a sufficient
> condition here.

Unfortunately as shown during the bootstrap, that patch contained a fatal
thinko, 
> > +	default:
> > +	  break;

for default: we need return;

Here is a version of the patch that passed bootstrap/regtest on x86_64-linux
and i686-linux, ok for trunk?

2021-02-24  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/80635
	* tree-vrp.c (vrp_simplify_cond_using_ranges): Also handle
	VIEW_CONVERT_EXPR if modes are the same, innerop is integral and
	has mode precision.

	* g++.dg/warn/pr80635-1.C: New test.
	* g++.dg/warn/pr80635-2.C: New test.

--- gcc/tree-vrp.c.jj	2021-02-24 12:56:58.573939572 +0100
+++ gcc/tree-vrp.c	2021-02-24 13:05:22.675326780 +0100
@@ -4390,11 +4390,22 @@ vrp_simplify_cond_using_ranges (vr_value
       gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
       tree innerop;
 
-      if (!is_gimple_assign (def_stmt)
-	  || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
+      if (!is_gimple_assign (def_stmt))
 	return;
 
-      innerop = gimple_assign_rhs1 (def_stmt);
+      switch (gimple_assign_rhs_code (def_stmt))
+	{
+	CASE_CONVERT:
+	  innerop = gimple_assign_rhs1 (def_stmt);
+	  break;
+	case VIEW_CONVERT_EXPR:
+	  innerop = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
+	  if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
+	    return;
+	  break;
+	default:
+	  return;
+	}
 
       if (TREE_CODE (innerop) == SSA_NAME
 	  && !POINTER_TYPE_P (TREE_TYPE (innerop))
--- gcc/testsuite/g++.dg/warn/pr80635-1.C.jj	2021-02-24 12:24:15.176834532 +0100
+++ gcc/testsuite/g++.dg/warn/pr80635-1.C	2021-02-24 12:24:15.176834532 +0100
@@ -0,0 +1,46 @@
+// PR tree-optimization/80635
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -Wmaybe-uninitialized" }
+
+using size_t = decltype (sizeof (1));
+inline void *operator new (size_t, void *p) { return p; }
+template<typename T>
+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); }	// { dg-bogus "may be used uninitialized in this function" }
+
+  int m;
+};
+
+struct B
+{
+  B ();
+  ~B ();
+};
+
+void func ()
+{
+  optional<A> maybe_a;
+  optional<B> maybe_b;
+
+  maybe_a.emplace ();
+  maybe_b.emplace ();
+}
--- gcc/testsuite/g++.dg/warn/pr80635-2.C.jj	2021-02-24 12:24:15.176834532 +0100
+++ gcc/testsuite/g++.dg/warn/pr80635-2.C	2021-02-24 12:24:15.176834532 +0100
@@ -0,0 +1,31 @@
+// PR tree-optimization/80635
+// { dg-do compile { target c++17 } }
+// { dg-options "-O2 -Wmaybe-uninitialized" }
+
+#include <optional>
+
+extern int get ();
+extern void set (int);
+
+struct A
+{
+  A () : m (get ()) {}
+  ~A () { set (m); }	// { dg-bogus "may be used uninitialized in this function" }
+
+  int m;
+};
+
+struct B
+{
+  B ();
+  ~B ();
+};
+
+void func ()
+{
+  std::optional<A> maybe_a;
+  std::optional<B> maybe_b;
+
+  maybe_a.emplace ();
+  maybe_b.emplace ();
+}


	Jakub



More information about the Gcc-patches mailing list