<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/147374>147374</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang] Possibly incorrect -Winfinite-recursion emitted
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
baxter-huntington
</td>
</tr>
</table>
<pre>
The following minimal examples are used as a reference:
**Example A** (https://godbolt.org/z/5Mvbj7ePd):
```cpp
#include <string>
#include <iostream>
class Bar {
public:
explicit Bar(const std::string aValue) : mValue{aValue} {};
bool operator==(const std::string aValue) const {
std::cout << "bool operator==(const std::string aValue) const\n";
return aValue == mValue;
};
friend bool operator==(const std::string aLhs, Bar aRhs) { return aRhs == aLhs; }
private:
std::string mValue;
};
int main() {
auto other1 = Bar("Bar");
[[ maybe_unused ]] auto equal = other1 == "Bar";
}
```
**Example B** (https://godbolt.org/z/aM5f8odqa):
```cpp
#include <string>
#include <iostream>
template<typename T>
class Foo {
public:
explicit Foo(const T aValue) : mValue{aValue} {};
bool operator==(const T aValue) const {
std::cout << "bool operator==(const T aValue) const\n";
return aValue == mValue;
};
friend bool operator==(const T aLhs, Foo aRhs) { return aRhs == aLhs; }
private:
T mValue;
};
int main() {
auto thing1 = Foo<std::string>("Foo");
[[maybe_unused]] auto equal = thing1 == "Foo";
}
```
In Clang 21 (and the most recent trunk at the time of writing), **Example A** results in the following warning being emitted:
```
<source>:13:62: warning: all paths through this function will call itself [-Winfinite-recursion]
13 | friend bool operator==(const std::string aLhs, Bar aRhs) { return aRhs == aLhs; }
|
```
In older versions (e.g., Clang 20.1.0), no warning is emitted. `const`-qualifying `aRhs` resolves the warning in Clang 21. Is this a false positive? I'm not sure I understand what Clang deems to be infinitely recursive here.
Notably, when using a class template as in **Example B**, no warning is emitted.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy8Vt2O2zYTfRr6ZrCGTFmWdeEL_8TAAl8-BMGivSwoaWQxpUiHHNlxn74YSrbTjds0bZqFsKLM0TnzdzhSIeiDRVyJbCOy3UT11Dq_KtUnQv_U9pa0PZCzk9LVl9VLi9A4Y9xZ2wN02upOGcBPqjsaDKA8Qh-wBhVAgccGPdoKRboGkaz5kny9GexhfAQhly3RMYh0LeReyP3B1aUzNHX-IOT-NyH32dtT-SHHd7WQBZsla7FIhqs6HiNyqm1l-hpBpNtAXtuDSN98saNdII-qG_eSdWVUCLBRHkS-Ecn62JdGVwMHAAB-OhpdaWITIZeVs4EgUM0W6XogAvWTMj0KWQDH2g1P-Wb8Od9F7Hwn0s1AysClcwbcEb0i50W64-vr-MO-yDcwwvDfzbxyPXGUIt2CkPJfUIhsa4WUg8dXHo_UezuawgB4jTa9efQ60MZrtPW3xfu_Ngi5jWVR73ldxJivDrxvw5U-mjJ5vmM-rqDXJ0V4L-Fr9JvH7ONnzmpL0ClthVyOhCOA6smBoxb9jGnHVhBSxoWMPXm1jTraQKcuJf7S2ygHke1Ethtg8GOvTES5A_LTHe3m12dN_kg-m78vH_U2a5au_qju8vl-CiLsjiYmfEuXI1rVIbwMu4O49s59TVx7527N8PLd5fTyXwjoC9AfK5mXm0g4vd8mEmZ8rZOXfygLarU9DLLgInLn_EFt3AhRK7HEj7TyuVQeK-XOMSplxPpzpTxb2BplDyBnrA9la6AWoXOBwGOFloB8b38FRXGDdIfgGjh7zQOPvZTcAY_GlcfQGwqgbXz1Pg_Pylu-l8j_sdNEWL-aVrxOt8H1nufiG5GuZ6lI1wvJnT4C8FIZA0dFbQBqvesPLSchQNPbirSzcNbGQMVWmgKahnP59LO2jbaa8Mlj1fugneWExmTPUhD5Fn74gQxDf2_hYZGcqdHDCaOvgUuF08OUmcbyJdPZNBnLYd0txTpc8zsFPsGi_hbJE7eMbi5sIhZJ9HSRcMWcOWGI9bpB3FtkCs9hyK-CRpmAcHRBkz6hSPfwLGTegXUEofcIz9DbGn0gbqpzq2iEqRG7AOSgRLjWwVxgrMQJoUWP0yHy_ztSpblwUOcWLfQhJhmG8_J6oPJnlLbw8NT_i3xM6lVaF2mhJria5dmsmKWLopi0q2ZeVUWGRVY0i2JWq3qZyGxeyXmZN00mk4leyURmSZ7ks-V8lhbTplCLQs6lqrN6uVhKMU-wU9pMjTl1PF8mOoQeV7N5nubziVElmhA_JaWsOCus0mw38St-4ansD0HME6MDhTsEaTLx-3N4I9vBOxeCLs0FtK2c91gRPOrta8iT3pvVqxGoqe3LaeU6IffMNN6ejt59wIqE3EfPg5D70fnTSv4eAAD__1RQUCU">