https://gcc.gnu.org/g:a4eec6c712ec16a77eb28ae0a7366d957a2c0080

commit r15-4301-ga4eec6c712ec16a77eb28ae0a7366d957a2c0080
Author: Simon Martin <si...@nasilyan.com>
Date:   Sun Oct 13 17:58:14 2024 +0200

    Revert "c++: Fix overeager Woverloaded-virtual with conversion operators 
[PR109918]"
    
    This reverts commit 60163c85730e6b7c566e219222403ac87ddbbddd.

Diff:
---
 gcc/cp/class.cc                               | 85 ++++++++++-----------------
 gcc/cp/error.cc                               |  3 +-
 gcc/testsuite/g++.dg/warn/Woverloaded-virt1.C |  2 -
 gcc/testsuite/g++.dg/warn/Woverloaded-virt5.C | 12 ----
 gcc/testsuite/g++.dg/warn/Woverloaded-virt6.C | 12 ----
 gcc/testsuite/g++.dg/warn/Woverloaded-virt7.C | 25 --------
 gcc/testsuite/g++.dg/warn/Woverloaded-virt8.C | 15 -----
 gcc/testsuite/g++.dg/warn/Woverloaded-virt9.C | 14 -----
 8 files changed, 33 insertions(+), 135 deletions(-)

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index f754886a60ab..646072d4f202 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -3243,15 +3243,10 @@ warn_hidden (tree t)
          continue;
 
        tree name = OVL_NAME (fns);
-       size_t num_fns = 0; /* The number of fndecls in fns.  */
        auto_vec<tree, 20> base_fndecls;
        tree base_binfo;
        tree binfo;
        unsigned j;
-       hash_set<tree> overriden_base_fndecls;
-       /* base_fndecls that are hidden but not overriden. The "value"
-          contains the fndecl that hides the "key".  */
-       hash_map<tree, tree> hidden_base_fndecls;
 
        if (IDENTIFIER_CDTOR_P (name))
          continue;
@@ -3269,63 +3264,47 @@ warn_hidden (tree t)
        if (base_fndecls.is_empty ())
          continue;
 
-       /* Find all the base_fndecls that are overridden, as well as those
-          that are hidden, in T.  */
+       /* Remove any overridden functions.  */
+       bool seen_non_override = false;
        for (tree fndecl : ovl_range (fns))
          {
-           fndecl = STRIP_TEMPLATE (fndecl);
+           bool any_override = false;
            if (TREE_CODE (fndecl) == FUNCTION_DECL
-               && fndecl != conv_op_marker)
+               && DECL_VINDEX (fndecl))
              {
-               num_fns++;
-               tree fndecl_vindex = DECL_VINDEX (fndecl);
-               /* If the method from the base class has the same DECL_VINDEX
-                  as the method from the derived, it has been overridden.
-                  Note that we can't move on after finding one match: fndecl
-                  might override multiple base fns.  */
+               /* If the method from the base class has the same
+                  signature as the method from the derived class, it
+                  has been overridden.  Note that we can't move on
+                  after finding one match: fndecl might override
+                  multiple base fns.  */
                for (size_t k = 0; k < base_fndecls.length (); k++)
-                 {
-                   if (!base_fndecls[k] || !DECL_VINDEX (base_fndecls[k]))
-                     continue;
-                   tree base_fndecl_vindex = DECL_VINDEX (base_fndecls[k]);
-                   if (fndecl_vindex
-                       && !tree_int_cst_compare (fndecl_vindex,
-                                                 base_fndecl_vindex))
-                     overriden_base_fndecls.add (base_fndecls[k]);
-                   else if (IDENTIFIER_CONV_OP_P (name)
-                            && (DECL_NAME (fndecl)
-                                != DECL_NAME (base_fndecls[k])))
-                     /* If base_fndecl[k] and fndecl are conversion operators
-                        to different types, they're unrelated.  */
-                     ;
-                   else
-                     hidden_base_fndecls.put (base_fndecls[k], fndecl);
-                 }
+                 if (base_fndecls[k]
+                     && same_signature_p (fndecl, base_fndecls[k]))
+                   {
+                     base_fndecls[k] = NULL_TREE;
+                     any_override = true;
+                   }
              }
+           if (!any_override)
+             seen_non_override = true;
          }
 
-       if (warn_overloaded_virtual == 1
-           && overriden_base_fndecls.elements () == num_fns)
-         /* All the fns override a base virtual.  */
-         continue;
+       if (!seen_non_override && warn_overloaded_virtual == 1)
+         /* All the derived fns override base virtuals.  */
+         return;
 
-       /* Now give a warning for all hidden methods. Note that a method that
-          is both in hidden_base_fndecls and overriden_base_fndecls is not
-          hidden.  */
-       for (auto hidden_base_fndecl : hidden_base_fndecls)
-         {
-           tree hidden_fndecl = hidden_base_fndecl.first;
-           tree hider = hidden_base_fndecl.second;
-           if (!hidden_fndecl
-               || overriden_base_fndecls.contains (hidden_fndecl))
-             continue;
-           gcc_assert (hider);
-           auto_diagnostic_group d;
-           if (warning_at (location_of (hidden_fndecl),
-                           OPT_Woverloaded_virtual_,
-                           "%qD was hidden", hidden_fndecl))
-             inform (location_of (hider), "  by %qD", hider);
-         }
+       /* Now give a warning for all base functions without overriders,
+          as they are hidden.  */
+       for (tree base_fndecl : base_fndecls)
+         if (base_fndecl)
+           {
+             auto_diagnostic_group d;
+             /* Here we know it is a hider, and no overrider exists.  */
+             if (warning_at (location_of (base_fndecl),
+                             OPT_Woverloaded_virtual_,
+                             "%qD was hidden", base_fndecl))
+               inform (location_of (fns), "  by %qD", fns);
+           }
       }
 }
 
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 3d0dad4ee590..65f70c595cf8 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -3397,8 +3397,7 @@ location_of (tree t)
        return input_location;
     }
   else if (TREE_CODE (t) == OVERLOAD)
-    t = OVL_FIRST (t) != conv_op_marker ? OVL_FIRST (t)
-      : OVL_FIRST (OVL_CHAIN (t));
+    t = OVL_FIRST (t);
 
   if (DECL_P (t))
     return DECL_SOURCE_LOCATION (t);
diff --git a/gcc/testsuite/g++.dg/warn/Woverloaded-virt1.C 
b/gcc/testsuite/g++.dg/warn/Woverloaded-virt1.C
index 9091bfabc967..92f8327b9d05 100644
--- a/gcc/testsuite/g++.dg/warn/Woverloaded-virt1.C
+++ b/gcc/testsuite/g++.dg/warn/Woverloaded-virt1.C
@@ -5,12 +5,10 @@ class Foo
 {
 public:
     virtual void f(int);       // { dg-warning "hidden" }
-    void g(int);               // Not virtual, so no warning
 };
 
 class Bar : public Foo
 {
 public:
     virtual void f(short);     // { dg-message "by" }
-    virtual void g(short);
 };
diff --git a/gcc/testsuite/g++.dg/warn/Woverloaded-virt5.C 
b/gcc/testsuite/g++.dg/warn/Woverloaded-virt5.C
deleted file mode 100644
index 01cd562609a8..000000000000
--- a/gcc/testsuite/g++.dg/warn/Woverloaded-virt5.C
+++ /dev/null
@@ -1,12 +0,0 @@
-// PR c++/109918 - Exact PR testcase
-// { dg-do compile }
-// { dg-additional-options -Wall }
-
-struct A {
-  virtual operator int() { return 42; }
-  virtual operator char() = 0;
-};
-
-struct B : public A {
-  operator char() { return 'A'; }
-};
diff --git a/gcc/testsuite/g++.dg/warn/Woverloaded-virt6.C 
b/gcc/testsuite/g++.dg/warn/Woverloaded-virt6.C
deleted file mode 100644
index c18049e3a92b..000000000000
--- a/gcc/testsuite/g++.dg/warn/Woverloaded-virt6.C
+++ /dev/null
@@ -1,12 +0,0 @@
-// PR c++/109918 - PR testcase with -Woverloaded-virtual=2
-// { dg-do compile }
-// { dg-additional-options -Woverloaded-virtual=2 }
-
-struct A {
-  virtual operator int() { return 42; }
-  virtual operator char() = 0;
-};
-
-struct B : public A {
-  operator char() { return 'A'; }
-};
diff --git a/gcc/testsuite/g++.dg/warn/Woverloaded-virt7.C 
b/gcc/testsuite/g++.dg/warn/Woverloaded-virt7.C
deleted file mode 100644
index be50c890d20f..000000000000
--- a/gcc/testsuite/g++.dg/warn/Woverloaded-virt7.C
+++ /dev/null
@@ -1,25 +0,0 @@
-// PR c++/109918 - Test different CV-quals
-// { dg-do compile }
-// { dg-additional-options -Woverloaded-virtual }
-
-struct A {
-  virtual operator char() { return 'a'; }
-  virtual operator char() const { return 'b'; } // { dg-warning "was hidden" }
-  virtual operator int() { return 42; }
-};
-
-struct B : public A {
-  operator char() { return 'A'; } // { dg-note "by" }
-  operator int() { return 43; }
-};
-
-struct AA {
-  virtual char func(char) { return 'a'; }
-  virtual char func(char) const { return 'b'; } // { dg-warning "was hidden" }
-  virtual int func(int) { return 42; }
-};
-
-struct BB : public AA {
-  char func(char) { return 'A'; } // { dg-note "by" }
-  int func(int) { return 43; }
-};
diff --git a/gcc/testsuite/g++.dg/warn/Woverloaded-virt8.C 
b/gcc/testsuite/g++.dg/warn/Woverloaded-virt8.C
deleted file mode 100644
index 51af2dae77ca..000000000000
--- a/gcc/testsuite/g++.dg/warn/Woverloaded-virt8.C
+++ /dev/null
@@ -1,15 +0,0 @@
-// Identified when investigating PR c++/109918: no warning was emitted due to
-// an incorrect early return in warn_hidden.
-// { dg-additional-options -Wall }
-
-struct Foo
-{
-  virtual void f(int); // { dg-warning "hidden" }
-  virtual void g() {}
-};
-
-struct Bar : Foo
-{
-  virtual void f(short); // { dg-message "by" }
-  virtual void g() {}
-};
diff --git a/gcc/testsuite/g++.dg/warn/Woverloaded-virt9.C 
b/gcc/testsuite/g++.dg/warn/Woverloaded-virt9.C
deleted file mode 100644
index 6d315c63a08e..000000000000
--- a/gcc/testsuite/g++.dg/warn/Woverloaded-virt9.C
+++ /dev/null
@@ -1,14 +0,0 @@
-// PR c++/109918: Non virtual overloads in derived classes that don't override
-// anything shouldn't cause warnings, even at -Woverloaded-virtual=2
-// { dg-additional-options -Woverloaded-virtual=2 }
-
-struct Foo
-{
-  virtual void g() {}
-};
-
-struct Bar : Foo
-{
-  virtual void g() {}
-  void g(int) {}
-};

Reply via email to