[llvm] 8810595 - Add unnecessary-virtual-specifier to -Wextra (#138741)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 7 11:10:31 PDT 2025
Author: Devon Loehr
Date: 2025-05-07T20:10:25+02:00
New Revision: 8810595068a3f17c444e7f96733a6cd9dc08987e
URL: https://github.com/llvm/llvm-project/commit/8810595068a3f17c444e7f96733a6cd9dc08987e
DIFF: https://github.com/llvm/llvm-project/commit/8810595068a3f17c444e7f96733a6cd9dc08987e.diff
LOG: 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.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticGroups.td
llvm/cmake/modules/HandleLLVMOptions.cmake
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 350244e3054cf..89d7f137d0fe0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -434,9 +434,9 @@ Improvements to Clang's diagnostics
- The ``-Wsign-compare`` warning now treats expressions with bitwise not(~) and minus(-) as signed integers
except for the case where the operand is an unsigned integer
and throws warning if they are compared with unsigned integers (##18878).
-- The ``-Wunnecessary-virtual-specifier`` warning has been added to warn about
- methods which are marked as virtual inside a ``final`` class, and hence can
- never be overridden.
+- The ``-Wunnecessary-virtual-specifier`` warning (included in ``-Wextra``) has
+ been added to warn about methods which are marked as virtual inside a
+ ``final`` class, and hence can never be overridden.
- Improve the diagnostics for chained comparisons to report actual expressions and operators (#GH129069).
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 76092b84b46ff..7b0dcde44296e 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -421,13 +421,12 @@ def CXX11WarnSuggestOverride : DiagGroup<"suggest-override">;
def WarnUnnecessaryVirtualSpecifier : DiagGroup<"unnecessary-virtual-specifier"> {
code Documentation = [{
Warns when a ``final`` class contains a virtual method (including virtual
-destructors). Since ``final`` classes cannot be subclassed, their methods
-cannot be overridden, and hence the ``virtual`` specifier is useless.
+destructors) that does not override anything. Since ``final`` classes cannot
+be subclassed, their methods cannot be overridden, so there is no point to
+introducing new ``virtual`` methods.
The warning also detects virtual methods in classes whose destructor is
``final``, for the same reason.
-
-The warning does not fire on virtual methods which are also marked ``override``.
}];
}
@@ -1164,6 +1163,7 @@ def Extra : DiagGroup<"extra", [
FUseLdPath,
CastFunctionTypeMismatch,
InitStringTooLongMissingNonString,
+ WarnUnnecessaryVirtualSpecifier,
]>;
def Most : DiagGroup<"most", [
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index 8b3303fe9f3d2..c427a65ee030c 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -882,6 +882,11 @@ if (LLVM_ENABLE_WARNINGS AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL))
# The LLVM libraries have no stable C++ API, so -Wnoexcept-type is not useful.
append("-Wno-noexcept-type" CMAKE_CXX_FLAGS)
+ # LLVM has a policy of including virtual "anchor" functions to control
+ # where the vtable is emitted. In `final` classes, these are exactly what
+ # this warning detects: unnecessary virtual methods.
+ add_flag_if_supported("-Wno-unnecessary-virtual-specifier" CXX_SUPPORTS_UNNECESSARY_VIRTUAL_FLAG)
+
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
append("-Wnon-virtual-dtor" CMAKE_CXX_FLAGS)
endif()
More information about the llvm-commits
mailing list