<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/67875>67875</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang-tidy] Add check for qualifier of member method
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang-tidy
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
zjyhjqs
</td>
</tr>
</table>
<pre>
Since C++11, [ref-qualifier](https://en.cppreference.com/w/cpp/language/member_functions#Member_functions_with_cv-qualifiers) is introduced to solve the performance issues like [string concatenation](https://en.cppreference.com/w/cpp/string/basic_string/operator%2B).
It's generally neglected that ref-qualifier is also beneficial for avoiding some unexpected cases, such as immediate dangling, unconventional operator behaviors and useless operations for r-value object.
```cpp
// assign to a (non-proxy) r-value object is meaningless, and `a` is a dangling reference
const auto& a = (getA() = obj);
// modify a pr-value by increment operators should be invalid, and also dangling here
const auto& it = ++getIterator();
// empty operation for r-value object
getA().setProperty();
```
In fact, **most member methods** not qualified as `const` should be `l-value` qualified. (Imagine if we replace the current syntax with [deducing this](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter))
# Propose
## `*-qualify-member-method`
Checks qualifier for operator overload, swap and setter method. (`private` and `delete` method will be ignored)
method | qualifier
--------|----------
`=`,`op=` | Normal: `&`<br />Proxy: `const&` and `const&&`<br />Tuple: `&`, `&&`, `const&` and `const&&`
`[]`| Container: `&`, `&&`, (optional)`const&`, `const&&`<br />View: `const` and unqualified
`++`,`--` (both prefix and postfix) | `&`
`&`(unary address operator) | `&`
`set*` | Normal: `&`<br />Proxy: `const`
`[Ss]wap` | `&`
## Options
`StrictMode`: All member methods should be explicitly qualified as either or both `const` and `&`/`&&`.
`IgnoreImplicitAssignment`: Ignore the missing qualifier for implicitly defined assignment operator.
`IgnoredClass`: Suppress warning for member methods of the listed class. (use full signature to prevent overloaded method may be too verbose)
# Example
```cpp
class A {
public:
A& operator= (const A&) = default; // Warn: should be qualified as `&` or `const`
void setPropertyB(B b); // Warn: setter should be qualified as `&` or `const`
};
```
```cpp
// (enable `IgnoreImplicitAssignment`) Ok
// (disable `IgnoreImplicitAssignmern`) Warn: explicitly declare the assignment operator as `&` or `const`
class Builder {
public:
// (disable `StrictMode`) Ok
// (enable `StrictMode`) Warn: Member method should be qualified
Builder& withProperty(C c);
};
```
# Links
- [N2819 - Ref-qualifiers for assignment operators of the Standard Library](https://wg21.link/N2819)
- [P1906 - Provided operator= return lvalue-ref on rvalue](https://wg21.link/P1906)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysV91u2zoSfhr6ZmBDpuK_C1_YTg0EOD2n2Cx2LwNKGllsKFKHpOx4n34xpCxbTpoAxTGKtqI0M99880vhnDxoxDWbbdnscSRaXxm7_t_Pc_XzbzfKTHFeP0udI-wY3zK-nU4Z3wGbbS2W479boWQp0bLZI-PLyvvGsXTD-J7xPepJ3jQWS7Soc5zkpmZ8f2J8nzcN43sl9KEVB2R8X2OdoX0pW517abRjPP1-d_Rykr56yY9Xm47xFUgHUntrijbHArwBZ9QRwVcIDdrS2FoQeOlciw6UfEXC7ryV-gC50bnwqAVZ-B0Xoh7G95lwMn_pH02DVnhjGZ8RaasJSx5Zsol_P3nGFw4OqNEKpc6g8aAw94S_Eh4GxJKDQjkDGWosZS6FgtJYEEcjC_LBmRqh1fjWRBW5cOgoRK7NKxAOZF1jIYVHKIQ-qABwB63OjT6iJs-FggtgyLASR2msA6ELaB0qdK57TWEIxu34KFSLYLKfmPuBc2yexD9EUDwJTEJMNIqQAMaX2uhxY83bmYI41Ecu1yi01AcyTmgJC5sngs2TQEjvCvSxicZyo50H0XrD-JwspY9k7YB-w_iSbNGJyX4yvmLpdoA84qxNIcszCGguqLIzSJ1brFH7nigHrjKtKiBDkPoolCwuQEO4eoAV2g-xSd-Bo6I6oH_yl5RZ_hIb1o0_X4PxQSzi51d3Jw79D0sS_nyv-RKpQW5qKEXuQ4nzDeOb2jgPsTyhRl-ZwsUXoI2HS5oWlGgUdHKRgnQlh80TFSHSeS8wobA81eIgNYIs4YRgsVEij7Wbt9YS3e6svXgDqn2q2wKLNidWfSXdP99zvr01SubSv0QyXxphRY0eLfHGV8OIpEDEGod3x_SGWOWbrorP42hqHPm7Y3xXYf7q4FrwFNS-HM0RrTIi5JY7iSYkmEPv-3AEItk8aaw8Ch9I7qqlQIXxIH4JJ6lUyNeDNhaLO4-6j9hidwUT34y7H1vsxv3vmkTpY3B3x-aJaeJT0PInNV_F0k2kYx6-3WUWKFTptx-h-uPbmDfhkwv6_uid4L_bRuFQLaVrfLh9_lpr70MYfvSfxQ52RnshNdqvbfClaWIHJTIHFu8xvHPjPxJPA_c7lK3ui-SKL3SJnubxOHDMl5nxFVC6y7cg2xjnS_kW-txidwP-qihiW7Za2DOIorDX_k7N51eCDj3V_e-Gdsj1M9XuSTQXdffmbkvpryZW53DGPHsrc__dFBhMb2Cj1F2buulB2NW1Og87FkpfoQUae0TkfSRu-Nrfhn4Cd2ieQkE91dHKJkw6mhYdtvg69LVaOkf9a1jusu7xFVhKHdBdlPTBuZ-zUW2xU8K5ztJzS83POTgJS_MzaL-jxZQBiZIurAskHXpI6xDKVikgw8K3hNhQch0DiK4RYXHpJrU4E7feGDiizagRvm-R395ETdX66YYQMMAG2KIbTU2bKZlTUw-PAAAbmpl9msapHgfqJsQlDvYCS9Eqz9ItdCPzv8JqYuaaDPczq2sQxn6Qrb152rbgZpZuGV9uIYvz9J2t2J9_z-Ti8fMJ_csFi_ElapGpMHI_y0i-gr9e70UL6T6XtbqTvXh5U1QF5kp0Gf5B4n7tdcyAbStVgfbTPPgQ8bAb3Pg3lLjS807g4tT321r5KIJXvR1ayktaT262rB3kg0Xry5DyFP6Q-rVrcmPadP7ky-kKxvCv28tA3L4_YLiv6mcvdCFsAX_IzAp7_mhHOh34dKKkfmV8H8z0dRss_5iukjmMabs5Sqr326qz6FurQYWFbmyxBKPBxvXuC1NBL-OrUbFOi1W6EiNcT-ereTJLk1U6qtYlT9KHWfKQ4EKUi2k6n80W01I8IM6ns6mYjeSaJ5w-TpLZbJqmk1w8zEu-5NkSUaQLwR4SrIVUE6WO9cTYwyjc-9bzxXIxGymRoXLhost5Tpvg2MvizDini69dk9A4aw-OPSTUHd1VjZdehSvyjdjsETZFATntbyEu155uymHTHbVWrYfMHKSv2qzbT8lO9w9disIiz_fxzsr4PsD_fwAAAP__klPFgg">