Skip to content

clang-tidy: modernize-use-override provides invalid fix-it if a parameter has __attribute__ #138486

@e-kwsm

Description

@e-kwsm

Prepare /tmp/a.cpp:

struct B {
  virtual ~B() = default;
  virtual void f([[maybe_unused]] int x) {}
  virtual void g(int x __attribute__((unused))) {}
};

struct D : B {
  ~D() = default;
  virtual void f([[maybe_unused]] int x) {}
  virtual void g(int x __attribute__((unused))) {}
};

and /tmp/compile_commands.json:

[{
  "directory": "/tmp",
  "command": "clang++ -std=c++11 -Werror=unused-parameter -Wsuggest-override -Wsuggest-destructor-override -c -o a.o a.cpp",
  "file": "a.cpp",
  "output": "a.o"
}]
$ clang-tidy --checks=modernize-use-override --fix a.cpp
6 warnings generated.
a.cpp:8:3: warning: '~D' overrides a destructor but is not marked 'override' [clang-diagnostic-suggest-destructor-override]
    8 |   ~D() = default;
      |   ^
a.cpp:2:11: note: overridden virtual function is here
    2 |   virtual ~B() = default;
      |           ^
a.cpp:8:3: warning: annotate this function with 'override' or (rarely) 'final' [modernize-use-override]
    8 |   ~D() = default;
      |   ^
      |        override
a.cpp:8:8: note: FIX-IT applied suggested code changes
    8 |   ~D() = default;
      |        ^
a.cpp:9:16: warning: 'f' overrides a member function but is not marked 'override' [clang-diagnostic-suggest-override]
    9 |   virtual void f([[maybe_unused]] int x) {}
      |                ^
a.cpp:3:16: note: overridden virtual function is here
    3 |   virtual void f([[maybe_unused]] int x) {}
      |                ^
a.cpp:9:16: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override]
    9 |   virtual void f([[maybe_unused]] int x) {}
      |   ~~~~~~~      ^
      |                                          override
a.cpp:9:3: note: FIX-IT applied suggested code changes
    9 |   virtual void f([[maybe_unused]] int x) {}
      |   ^
a.cpp:9:41: note: FIX-IT applied suggested code changes
    9 |   virtual void f([[maybe_unused]] int x) {}
      |                                         ^
a.cpp:10:16: warning: 'g' overrides a member function but is not marked 'override' [clang-diagnostic-suggest-override]
   10 |   virtual void g(int x __attribute__((unused))) {}
      |                ^
a.cpp:4:16: note: overridden virtual function is here
    4 |   virtual void g(int x __attribute__((unused))) {}
      |                ^
a.cpp:10:16: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override]
   10 |   virtual void g(int x __attribute__((unused))) {}
      |   ~~~~~~~      ^
      |                        override
a.cpp:10:3: note: FIX-IT applied suggested code changes
   10 |   virtual void g(int x __attribute__((unused))) {}
      |   ^
a.cpp:10:24: note: FIX-IT applied suggested code changes
   10 |   virtual void g(int x __attribute__((unused))) {}
      |                        ^
clang-tidy applied 5 of 5 suggested fixes.

gives

struct D : B {
  ~D() override = default;
  void f([[maybe_unused]] int x) override {}
  void g(int x override __attribute__((unused))) {}
};

Here, the override specifier for g is wrong, which must be

  void g(int x __attribute__((unused))) override {}

https://godbolt.org/z/eG3KKPWoa

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang-tidyinvalid-code-generationTool (e.g. clang-format) produced invalid code that no longer compiles

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions