aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Martin <simon@nasilyan.com>2024-10-13 17:58:14 +0200
committerSimon Martin <simon@nasilyan.com>2024-10-13 17:58:14 +0200
commita4eec6c712ec16a77eb28ae0a7366d957a2c0080 (patch)
tree1194a3e29ad47586d8487857c450f1271f410899
parentf0f11559d569faffacea63db5c4a5ad98335c4ad (diff)
downloadgcc-a4eec6c712ec16a77eb28ae0a7366d957a2c0080.zip
gcc-a4eec6c712ec16a77eb28ae0a7366d957a2c0080.tar.gz
gcc-a4eec6c712ec16a77eb28ae0a7366d957a2c0080.tar.bz2
Revert "c++: Fix overeager Woverloaded-virtual with conversion operators [PR109918]"
This reverts commit 60163c85730e6b7c566e219222403ac87ddbbddd.
-rw-r--r--gcc/cp/class.cc85
-rw-r--r--gcc/cp/error.cc3
-rw-r--r--gcc/testsuite/g++.dg/warn/Woverloaded-virt1.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/Woverloaded-virt5.C12
-rw-r--r--gcc/testsuite/g++.dg/warn/Woverloaded-virt6.C12
-rw-r--r--gcc/testsuite/g++.dg/warn/Woverloaded-virt7.C25
-rw-r--r--gcc/testsuite/g++.dg/warn/Woverloaded-virt8.C15
-rw-r--r--gcc/testsuite/g++.dg/warn/Woverloaded-virt9.C14
8 files changed, 33 insertions, 135 deletions
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index f754886..646072d 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 3d0dad4..65f70c5 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 9091bfa..92f8327 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 01cd562..0000000
--- 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 c18049e..0000000
--- 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 be50c89..0000000
--- 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 51af2da..0000000
--- 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 6d315c6..0000000
--- 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) {}
-};