PR c++/80916 - spurious "static but not defined" warning.
authorJason Merrill <jason@redhat.com>
Thu, 7 Mar 2019 15:10:22 +0000 (10:10 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 7 Mar 2019 15:10:22 +0000 (10:10 -0500)
Nothing can refer to an internal decl with no definition, so we shouldn't
treat such a decl as a possible devirtualization target.

* gimple-fold.c (can_refer_decl_in_current_unit_p): Return false
for an internal symbol with DECL_EXTERNAL.

From-SVN: r269459

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/g++.dg/warn/unused-fn1.C [new file with mode: 0644]

index b5a73871a21165900cc7f56ef962cc244adeb3b9..507c8e1452430f7899de292b2c5a5f753a9a99fe 100644 (file)
@@ -1,3 +1,9 @@
+2019-01-25  Jason Merrill  <jason@redhat.com>
+
+       PR c++/80916 - spurious "static but not defined" warning.
+       * gimple-fold.c (can_refer_decl_in_current_unit_p): Return false
+       for an internal symbol with DECL_EXTERNAL.
+
 2019-04-07  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/89618
index 7ef5004f5f9d3d98de2ab87a350ed2b04088fc8d..62d2e0abc2648b16c1e9a011aa23b5f9cea93ff2 100644 (file)
@@ -121,9 +121,12 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
       || !VAR_OR_FUNCTION_DECL_P (decl))
     return true;
 
-  /* Static objects can be referred only if they was not optimized out yet.  */
-  if (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
+  /* Static objects can be referred only if they are defined and not optimized
+     out yet.  */
+  if (!TREE_PUBLIC (decl))
     {
+      if (DECL_EXTERNAL (decl))
+       return false;
       /* Before we start optimizing unreachable code we can be sure all
         static objects are defined.  */
       if (symtab->function_flags_ready)
diff --git a/gcc/testsuite/g++.dg/warn/unused-fn1.C b/gcc/testsuite/g++.dg/warn/unused-fn1.C
new file mode 100644 (file)
index 0000000..aabc01b
--- /dev/null
@@ -0,0 +1,16 @@
+// PR c++/80916
+// { dg-options "-Os -Wunused" }
+
+struct j {
+  virtual void dispatch(void *) {}
+};
+template <typename>
+struct i : j {
+  void dispatch(void *) {} // warning: 'void i< <template-parameter-1-1> >::dispatch(void*) [with <template-parameter-1-1> = {anonymous}::l]' declared 'static' but never defined [-Wunused-function]
+};
+namespace {
+  struct l : i<l> {};
+}
+void f(j *k) {
+  k->dispatch(0);
+}