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) {} -};