]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: Fix overeager Woverloaded-virtual with conversion operators [PR109918]
authorSimon Martin <simon@nasilyan.com>
Tue, 4 Feb 2025 09:58:17 +0000 (10:58 +0100)
committerSimon Martin <simon@nasilyan.com>
Tue, 4 Feb 2025 10:01:05 +0000 (11:01 +0100)
commitd346af2af88caf1e21a5cc1f0afa33596198fb60
treeec4bd21e70504a073408eced79cd2bf3e2f0f0c5
parent0675eb17480bada678bf2769d39732027abcd6d0
c++: Fix overeager Woverloaded-virtual with conversion operators [PR109918]

We currently emit an incorrect -Woverloaded-virtual warning upon the
following test case

=== cut here ===
struct A {
  virtual operator int() { return 42; }
  virtual operator char() = 0;
};
struct B : public A {
  operator char() { return 'A'; }
};
=== cut here ===

The problem is that when iterating over ovl_range (fns), warn_hidden
gets confused by the conversion operator marker, concludes that
seen_non_override is true and therefore emits a warning for all
conversion operators in A that do not convert to char, even if
-Woverloaded-virtual is 1 (e.g. with -Wall, the case reported).

A second set of problems is highlighted when -Woverloaded-virtual is 2.

First, with the same test case, since base_fndecls contains all
conversion operators in A (except the one to char, that's been removed
when iterating over ovl_range (fns)), we emit a spurious warning for
the conversion operator to int, even though it's unrelated.

Second, in case there are several conversion operators with different
cv-qualifiers to the same type in A, we rightfully emit a warning,
however the note uses the location of the conversion operator marker
instead of the right one; location_of should go over conv_op_marker.

This patch fixes all these by explicitly keeping track of (1) base
methods that are overriden, as well as (2) base methods that are hidden
but not overriden (and by what), and warning about methods that are in
(2) but not (1). It also ignores non virtual base methods, per
"definition" of -Woverloaded-virtual.

Co-authored-by: Jason Merrill <jason@redhat.com>
PR c++/117114
PR c++/109918

gcc/cp/ChangeLog:

* class.cc (warn_hidden): Keep track of overloaded and of hidden
base methods.
* error.cc (location_of): Skip over conv_op_marker.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Woverloaded-virt1.C: Check that no warning is
emitted for non virtual base methods.
* g++.dg/warn/Woverloaded-virt10.C: New test.
* g++.dg/warn/Woverloaded-virt11.C: New test.
* g++.dg/warn/Woverloaded-virt12.C: New test.
* g++.dg/warn/Woverloaded-virt13.C: New test.
* g++.dg/warn/Woverloaded-virt5.C: New test.
* g++.dg/warn/Woverloaded-virt6.C: New test.
* g++.dg/warn/Woverloaded-virt7.C: New test.
* g++.dg/warn/Woverloaded-virt8.C: New test.
* g++.dg/warn/Woverloaded-virt9.C: New test.
12 files changed:
gcc/cp/class.cc
gcc/cp/error.cc
gcc/testsuite/g++.dg/warn/Woverloaded-virt1.C
gcc/testsuite/g++.dg/warn/Woverloaded-virt10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Woverloaded-virt11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Woverloaded-virt12.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Woverloaded-virt13.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Woverloaded-virt5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Woverloaded-virt6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Woverloaded-virt7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Woverloaded-virt8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/Woverloaded-virt9.C [new file with mode: 0644]