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() _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits