llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.81k stars 11.91k forks source link

cppcoreguidelines-avoid-const-or-ref-data-members gives false positive when a templated class inherits #111985

Open Osse opened 3 weeks ago

Osse commented 3 weeks ago

When a class with a const ref member inherits a class that deletes move/copy constructors and assignment operators cppcoreguidelines-avoid-const-or-ref-data-members still points out the ref member. This is not an unusual technique (e.g. inheriting from boost::noncopyable). I have written a test case on Compiler Explorer that you can tweak using the #defines.

If the derived class is not a template the check works as expected. If the class is a template but deletes deletes the move/copy constructors and assignment operators itself also works as expected.

Summary: Is template Inherits False positive
Yes Yes Yes
Yes No No
No Yes No

Also, if the derived class is a template and inherits and deletes the constructors/operators anyway it works as expected. But this is presumably a "sub-case" of the non-inheriting case.

llvmbot commented 3 weeks ago

@llvm/issue-subscribers-clang-tidy

Author: Øystein Walle (Osse)

When a class with a const ref member inherits a class that deletes move/copy constructors and assignment operators `cppcoreguidelines-avoid-const-or-ref-data-members` still points out the ref member. This is not an unusual technique (e.g. inheriting from `boost::noncopyable`). I have written a test case on [Compiler Explorer](https://godbolt.org/z/fxxPMdsh8) that you can tweak using the `#define`s. If the derived class is _not_ a template the check works as expected. If the class _is_ a template but deletes deletes the move/copy constructors and assignment operators itself also works as expected. Summary: |Is template|Inherits|False positive| |--------------|-----------|--------------------| |Yes|Yes|**Yes**| |Yes|No|No| |No|Yes|No| Also, if the derived class is a template and inherits _and deletes the constructors/operators anyway_ it works as expected. But this is presumably a "sub-case" of the non-inheriting case.