[clang] Warn about virtual methods in `final` classes (PR #131188)

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 14 09:08:58 PDT 2025


================
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunnecessary-virtual-specifier %s
+
+struct Foo final {
+  Foo() = default;
+  virtual ~Foo() = default;                      // expected-warning {{virtual method}}
+  virtual Foo& operator=(Foo& other) = default;  // expected-warning {{virtual method}}
+  virtual Foo& operator=(Foo&& other) = default; // expected-warning {{virtual method}}
+  void f();
+  virtual void f(int);                           // expected-warning {{virtual method}}
+  int g(int x) { return x; };
+  virtual int g(bool);                           // expected-warning {{virtual method}}
+  static int s();
+};
+
+struct BarBase {
+  virtual ~BarBase() = delete;
+  virtual void virt() {}
+  virtual int virt(int);
+  int nonvirt();
+};
+
+struct Bar final : BarBase {
+  ~Bar() override = delete;
+  void virt() override {};
+  // `virtual ... override;` is a common pattern, so don't warn
+  virtual int virt(int) override;
+  virtual int virt(bool);                        // expected-warning {{virtual method}}
+  int nonvirt();
+};
----------------
zmodem wrote:

I'd also like to see the case of a function which does override something, but isn't marked with override. For example:

```
struct Base {
  virtual void foo();
};
struct Derived final : public Base {
  virtual void foo();
};
```

Should we warn here?

The `virtual` is unnecessary because it's already "inherited". But at least pre-c++11 writing out the `virtual` was common to signal to the reader that it was in fact a virtual function. On the other hand, pre-c++11 code wouldn't be able to use `final`.

We will already warn (`-Wsuggest-override`), maybe that's enough for that one?

https://github.com/llvm/llvm-project/pull/131188


More information about the cfe-commits mailing list