Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add unnecessary-virtual-specifier to -Wextra #138741

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 7, 2025
Merged

Conversation

DKLoehr
Copy link
Contributor

@DKLoehr DKLoehr commented May 6, 2025

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 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.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 6, 2025
@llvmbot
Copy link
Member

llvmbot commented May 6, 2025

@llvm/pr-subscribers-libcxx

@llvm/pr-subscribers-clang

Author: Devon Loehr (DKLoehr)

Changes

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 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.


Full diff: https://github.com/llvm/llvm-project/pull/138741.diff

1 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticGroups.td (+4-4)
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 1faf8508121f4..bb6e7070b1574 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``.
   }];
 }
 
@@ -1163,6 +1162,7 @@ def Extra : DiagGroup<"extra", [
     FUseLdPath,
     CastFunctionTypeMismatch,
     InitStringTooLongMissingNonString,
+    WarnUnnecessaryVirtualSpecifier,
   ]>;
 
 def Most : DiagGroup<"most", [

@DKLoehr DKLoehr force-pushed the virtual-warning branch from 964841d to 3fa5eff Compare May 6, 2025 19:12
@llvmbot llvmbot added the cmake Build system in general and CMake in particular label May 6, 2025
@DKLoehr
Copy link
Contributor Author

DKLoehr commented May 6, 2025

@zmodem @AaronBallman @Sirraide -- reviewers from previous attempt

@philnik777 -- do you think this PR will work with libc++?

@philnik777
Copy link
Contributor

This should probably work. To make sure you can make a simple change in the libcxx/ subdirectory to trigger the libc++ pre-commit CI (which should of course be removed again before actually committing).

@DKLoehr DKLoehr requested a review from a team as a code owner May 6, 2025 19:24
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label May 6, 2025
Copy link
Member

@Sirraide Sirraide left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LLVM cleanup was more surprising: I discovered that we have an old policy 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.

I wonder if we could add an escape hatch for this somehow—maybe don’t fire the warning on the first virtual function that is declared out-of-line if there’s an easy way of doing that, but that feels like a hack. We could also add an attribute instead to surpress the warning, but is adding an attribute for a single diagnostic really worth it?

Alternatively, we could ‘fix’ our codebase instead by introducing an LLVM_VIRTUAL_ANCHOR macro or sth like that which disables the diagnostic for that one declaration—I guess this probably depends how common this pattern is elsewhere; if there are a lot of people who do this then the attribute might be easier to use.

Copy link
Collaborator

@zmodem zmodem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm (without the libcxx/src/hash.cpp change obviously)

@DKLoehr
Copy link
Contributor Author

DKLoehr commented May 7, 2025

Looks like all the libc++ checks passed, so we should be good.

Alternatively, we could ‘fix’ our codebase instead by introducing an LLVM_VIRTUAL_ANCHOR macro or sth like that which disables the diagnostic for that one declaration.

This seems like a good way to do it, since it clearly documents what's going on. LLVM is the only project I've seen with such a policy; across all of chromium's dependencies, the extra virtual specifiers we flagged were indeed mistakes. The issue with libc++ was more to do with infrastructure than the warning itself, IIUC.

@Sirraide
Copy link
Member

Sirraide commented May 7, 2025

This seems like a good way to do it, since it clearly documents what's going on. LLVM is the only project I've seen with such a policy; across all of chromium's dependencies, the extra virtual specifiers we flagged were indeed mistakes. The issue with libc++ was more to do with infrastructure than the warning itself, IIUC.

Alright, in that case I’d say it would be nice to do that in a follow-up pr so we can stop disabling the warning.

@zmodem zmodem merged commit 8810595 into llvm:main May 7, 2025
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category cmake Build system in general and CMake in particular libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants