The -Wuninitialized/-Wmaybe-uninitialized enhancement to warn when
a pointer or reference to an uninitialized object is passed to
a const-qualified function argument tries to avoid triggering for
objects of empty types.  However, the suppression is incomplete
and lets the warning trigger in some corner cases.  The attached
patch extends the suppression to those as well.

Tested on x86_64-linux.  I will plan to commit it later this week
if there are no objections.

Martin
Work harder to avoid -Wuninitialized for objects of empty structs (PR middle-end/96295).

Resolves:
PR middle-end/96295 - -Wmaybe-uninitialized warning for range operator with
reference to an empty struct

gcc/ChangeLog:

	PR middle-end/96295
	* tree-ssa-uninit.c (maybe_warn_operand): Work harder to avoid
	warning for objects of empty structs

gcc/testsuite/ChangeLog:

	PR middle-end/96295
	* 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..a6e8beb5740
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-11.C
@@ -0,0 +1,26 @@
+/* PR middle-end/96295 - -Wmaybe-uninitialized warning for range operator
+   with reference to an empty struct
+   { dg-do compile }
+   { dg-options "-Wall" }
+   { dg-require-effective-target c++11 } */
+
+struct I
+{
+  bool operator!= (const I&) const;
+  void* operator* () const;
+  I& operator++ ();
+};
+
+struct A
+{
+  I begin () const { return I (); }
+  I end () const { return I (); }
+};
+
+void f (void)
+{
+  for (void *p : A ())   // { dg-bogus "\\\[-Wmaybe-uninitialized" }
+    {
+      (void)p;
+    }
+}
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 7eddca397b3..c7f994b0587 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -401,6 +401,8 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
      The first_field() test is important for C++ where the predicate
      alone isn't always sufficient.  */
   tree rhstype = TREE_TYPE (rhs);
+  if (POINTER_TYPE_P (rhstype))
+    rhstype = TREE_TYPE (rhstype);
   if (TYPE_EMPTY_P (rhstype)
       || (RECORD_OR_UNION_TYPE_P (rhstype)
 	  && (!first_field (rhstype)

Reply via email to