re PR c++/2972 (-Wuninitialized could warn about uninitialized member variable usage...
authorRichard Biener <rguenther@suse.de>
Mon, 24 Apr 2017 07:34:51 +0000 (07:34 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 24 Apr 2017 07:34:51 +0000 (07:34 +0000)
2017-04-24  Richard Biener  <rguenther@suse.de>

PR c++/2972
* tree-ssa-uninit.c (warn_uninitialized_vars): Handle some
pointer-based references.

* g++.dg/warn/Wuninitialized-10.C: New testcase.

From-SVN: r247090

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wuninitialized-10.C [new file with mode: 0644]
gcc/tree-ssa-uninit.c

index 2f3a3985415f301ec8d13f7308d2a8f423a47b4c..a9c9a3698e625db5e09238347abade2c4cb231d8 100644 (file)
@@ -1,3 +1,9 @@
+2017-04-24  Richard Biener  <rguenther@suse.de>
+
+       PR c++/2972
+       * tree-ssa-uninit.c (warn_uninitialized_vars): Handle some
+       pointer-based references.
+
 2017-04-24  Richard Biener  <rguenther@suse.de>
 
        PR bootstrap/79814
index e87a01adf3c7aa3b96e5b06919a0de190c374b68..148901463f44a17cb873cb1363e782c7b10425dc 100644 (file)
@@ -1,3 +1,8 @@
+2017-04-24  Richard Biener  <rguenther@suse.de>
+
+       PR c++/2972
+       * g++.dg/warn/Wuninitialized-10.C: New testcase.
+
 2017-04-23  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/80484
diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-10.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-10.C
new file mode 100644 (file)
index 0000000..1fd8b1d
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-do compile }
+// { dg-options "-Wuninitialized" }
+
+struct A
+{
+  int f,g;
+
+  A()
+    {
+      f = g; // { dg-warning "g. is used uninitialized" }
+    }
+};
+
+A a;
index e019ecc9d29e019af64fdf2b077fb7b4c80fb4a1..60731b2737de52d787f6561e3b1c7c34762ce607 100644 (file)
@@ -279,20 +279,22 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
              ao_ref ref;
              ao_ref_init (&ref, rhs);
 
-             /* Do not warn if it can be initialized outside this function.  */
+             /* Do not warn if the base was marked so or this is a
+                hard register var.  */
              tree base = ao_ref_base (&ref);
-             if (!VAR_P (base)
-                 || DECL_HARD_REGISTER (base)
-                 || is_global_var (base)
+             if ((VAR_P (base)
+                  && DECL_HARD_REGISTER (base))
                  || TREE_NO_WARNING (base))
                continue;
 
              /* Do not warn if the access is fully outside of the
                 variable.  */
-             if (ref.size != -1
+             if (DECL_P (base)
+                 && ref.size != -1
                  && ref.max_size == ref.size
                  && (ref.offset + ref.size <= 0
                      || (ref.offset >= 0
+                         && DECL_SIZE (base)
                          && TREE_CODE (DECL_SIZE (base)) == INTEGER_CST
                          && compare_tree_int (DECL_SIZE (base),
                                               ref.offset) <= 0)))
@@ -305,11 +307,12 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
                  && oracle_cnt > vdef_cnt * 2)
                limit = 32;
              check_defs_data data;
+             bool fentry_reached = false;
              data.found_may_defs = false;
              use = gimple_vuse (stmt);
              int res = walk_aliased_vdefs (&ref, use,
                                            check_defs, &data, NULL,
-                                           NULL, limit);
+                                           &fentry_reached, limit);
              if (res == -1)
                {
                  oracle_cnt += limit;
@@ -318,6 +321,16 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
              oracle_cnt += res;
              if (data.found_may_defs)
                continue;
+             /* Do not warn if it can be initialized outside this function.
+                If we did not reach function entry then we found killing
+                clobbers on all paths to entry.  */
+             if (fentry_reached
+                 /* ???  We'd like to use ref_may_alias_global_p but that
+                    excludes global readonly memory and thus we get bougs
+                    warnings from p = cond ? "a" : "b" for example.  */
+                 && (!VAR_P (base)
+                     || is_global_var (base)))
+               continue;
 
              /* We didn't find any may-defs so on all paths either
                 reached function entry or a killing clobber.  */