Skip to content

Commit 8810595

Browse files
authored
Add unnecessary-virtual-specifier to -Wextra (#138741)
Effectively a reland of #133265, though due to discussion there we add the warning to -Wextra instead of turning it on by default. We still need to disable it for LLVM due to our unusual policy of using virtual `anchor` functions even in final classes. We now check if the warning exists before disabling it in LLVM builds, so hopefully this will fix the issues libcxx ran into last time. From the previous PR: I've been working on cleaning up this warning in two codebases: LLVM and chromium (plus its dependencies). The chromium + dependency cleanup has been straightforward. Git archaeology shows that there are two reasons for the warnings: classes to which `final` was added after they were initially committed, and classes with virtual destructors that nobody remarks on. Presumably the latter case is because people are just very used to destructors being virtual. The LLVM cleanup was more surprising: I discovered that we have an [old policy](https://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers) about including out-of-line virtual functions in every class with a vtable, even `final` ones. This means our codebase has many virtual "anchor" functions which do nothing except control where the vtable is emitted, and which trigger the warning. I looked into alternatives to satisfy the policy, such as using destructors instead of introducing a new function, but it wasn't clear if they had larger implications. Overall, it seems like the warning is genuinely useful in most codebases (evidenced by chromium and its dependencies), and LLVM is an unusual case. Therefore we should enable the warning by default, and turn it off only for LLVM builds.
1 parent bf59716 commit 8810595

File tree

3 files changed

+12
-7
lines changed

3 files changed

+12
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,9 +434,9 @@ Improvements to Clang's diagnostics
434434
- The ``-Wsign-compare`` warning now treats expressions with bitwise not(~) and minus(-) as signed integers
435435
except for the case where the operand is an unsigned integer
436436
and throws warning if they are compared with unsigned integers (##18878).
437-
- The ``-Wunnecessary-virtual-specifier`` warning has been added to warn about
438-
methods which are marked as virtual inside a ``final`` class, and hence can
439-
never be overridden.
437+
- The ``-Wunnecessary-virtual-specifier`` warning (included in ``-Wextra``) has
438+
been added to warn about methods which are marked as virtual inside a
439+
``final`` class, and hence can never be overridden.
440440

441441
- Improve the diagnostics for chained comparisons to report actual expressions and operators (#GH129069).
442442

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -421,13 +421,12 @@ def CXX11WarnSuggestOverride : DiagGroup<"suggest-override">;
421421
def WarnUnnecessaryVirtualSpecifier : DiagGroup<"unnecessary-virtual-specifier"> {
422422
code Documentation = [{
423423
Warns when a ``final`` class contains a virtual method (including virtual
424-
destructors). Since ``final`` classes cannot be subclassed, their methods
425-
cannot be overridden, and hence the ``virtual`` specifier is useless.
424+
destructors) that does not override anything. Since ``final`` classes cannot
425+
be subclassed, their methods cannot be overridden, so there is no point to
426+
introducing new ``virtual`` methods.
426427

427428
The warning also detects virtual methods in classes whose destructor is
428429
``final``, for the same reason.
429-
430-
The warning does not fire on virtual methods which are also marked ``override``.
431430
}];
432431
}
433432

@@ -1164,6 +1163,7 @@ def Extra : DiagGroup<"extra", [
11641163
FUseLdPath,
11651164
CastFunctionTypeMismatch,
11661165
InitStringTooLongMissingNonString,
1166+
WarnUnnecessaryVirtualSpecifier,
11671167
]>;
11681168

11691169
def Most : DiagGroup<"most", [

llvm/cmake/modules/HandleLLVMOptions.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,11 @@ if (LLVM_ENABLE_WARNINGS AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL))
882882
# The LLVM libraries have no stable C++ API, so -Wnoexcept-type is not useful.
883883
append("-Wno-noexcept-type" CMAKE_CXX_FLAGS)
884884

885+
# LLVM has a policy of including virtual "anchor" functions to control
886+
# where the vtable is emitted. In `final` classes, these are exactly what
887+
# this warning detects: unnecessary virtual methods.
888+
add_flag_if_supported("-Wno-unnecessary-virtual-specifier" CXX_SUPPORTS_UNNECESSARY_VIRTUAL_FLAG)
889+
885890
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
886891
append("-Wnon-virtual-dtor" CMAKE_CXX_FLAGS)
887892
endif()

0 commit comments

Comments
 (0)