<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/64033>64033</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang-tidy] modernize-use-std-print misbehaves when arguments must be re-ordered and casts added or c_str() removed
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
mikecrowe
</td>
</tr>
</table>
<pre>
The newly-added _modernize-use-std-print_ check gets confused if it has to re-order arguments at the same time as adding casts or removing calls to `c_str()`. For example applying the check with _StrictMode_ enabled to:
```c++
printf("%*s=%*d\n", 4, s.c_str(), 3, ui);
```
yields:
```c++
std::println("{:>{}}={:{}}", s.c_str(), s4, ui, static_cast<int>(3));
```
rather than the expected:
```c++
std::println("{:>{}}={:{}}", s, 4, static_cast<int>(ui), 3);
```
I attempted to fix this by:
1. Doing the argument re-ordering first in `FormatStringConverter::applyFixes`.
2. Storing the argument index in `FormatStringConverter::ArgFixes` rather than the `Expr *` for the argument, and changing the index as required during re-ordering.
This meant that the cast was being applied to the correct argument, but since there was already a replacement pending for that argument functions like `getBeginLoc()` don't report the right position and the cast ends up in the wrong place resulting in:
```c++
std::println("{:>{}}={:{}}", s.c_str(), 4s, uistatic_cast<int>(), 3);
```
Note that I hadn't even attempted to fix the `c_str()` removal at this point. I've no idea where to even start with that since `FormatStringConverter::ArgCstrRemovals` contains the matched nodes rather than an index.
Is there a good way to have fixes built upon earlier fixes within the same `DiagnosticBuilder` instance, or do I need to handle all the possible combinations myself and generate a single combined fix for each?
An alternative would be to leave the arguments where they are and use argument indices in the format string, e.g.:
```c++
std::println("{2:>{1}}={4:{3}}", 4, s, 3, static_cast<int>(ui));
```
However, if argument indices are used then they must be used in the entire format satring and I wouldn't necessarily know whether they needed to be used until I'd already started rewriting earlier arguments which makes even this rather messy.
Any advice gratefully received.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8VsFu4zgS_Rr5UrAhU3YcH3xI4jY2wO4etvse0GRJ4oYiNaySHc3XD0jajt3pIIMBZgBBiSmy-OrVe0VKItM4xE2xfCyW24kcuPVh05lXVMEfcbL3etz8aBEcHu04lVqjhpfOawzO_I7TgXBKrKd9MI5fQLWoXqFBJlDe1QOhBlODYWglAXsIOPVBYwAZmqFDxwSSgVsEkh0Cmw5BEkitjWtASWICHyBg5w95xNoUqLgr1QtxKMR9IdbFXTmDnQ-Ab7LrLYLsezvGBTF0RnU03MLLdw5G8X-8xhdAJ_cWNbAvqoei3BblQ3FX5kcV4jE-aTRlV6etRCGWhXigotrm_3SxfHJp_AkW8UWza2DiCar4Gkz8VT3-tE3-ORq0mr4AQazjjCqjse4EZ_WYRr_Ff1bb-FTb0-BlJKP7AIwWZ2RPQCzZqJfIeFE9GccxpLiv0tRPgQfJLQbgVrrENL71qBj1357KO9u_xp3pzuR_iv4ZJDN2PScNQG3egFtDsB_f8af3fAZbf1bTWbkXLccPtQnEYFzU5c6HTnIUmmuevDtgYAw53yTLnXlDiorNwcUMvrMPH8Ibp_Ht65APoTkHhJ_LUdyV3976AIWIqUPtw80WkR_pNKhWuua8f95WEgT8bTABNeghgbtKd3ZNzo9IWYfSRR-fzBzLAUdJsMe4NKZtMsnpqw8BFd_g2A8MZJzCOCNgWixtQKlHkBCwt1Jh4qVHl5pDzka-h4F6cIqNdwTWvKbsG-RHbIz7t1eXRgHau0KsYv16HzLeYJqWofdk4vpEyiUNdJpg6GMl4tgxeNdAggMBabAcwRj3j7t3Qdm9nzjgT-j_v54xU_gMrdSZFTyg-5Uv8GPLzW1Z2tzCDUHvjeMZPBdidUBwHoxGCcdUUPY5NLEMnJtx2joX_UuNPxGH_-XtktSVdyyNo4Ssk6xa1OC8RrpxgXRZ0DeKfaaTyCQ03ms4yjHCa-UBY7JIsB-MZRh67wBlsAbD6UPEfRJCOrCKu3JrZOM8sVGPg7EaQ4RnHLF0CmMJfADt4RkcZj5b6XQ8oqxNcXpPZPY22qLbGyezgruR0NZJiQ06DJIjXDKuucxEnUoTfYBStUW1u07ywYG0jCEGPCAc_WA17FMdLMZMrzsBnYvU4ggyMuM0DHTbjYxCOrugTsUCStWKSeKsmf1VC4iLB-bXJlhkF1Q3Nlhc2n_1dfv_VPn_8kc8YIgRTP0xychAurtwiy6T0g3Ekb58pTmddo5NeOdCJjISdc-Z7-wohwqJZDB2hFfnj5Hrk0JxTKrIujhHHxwbm0ykLy0wuQY1BDwGkzrOWZfXJTSqhU6-ImWrJU-e3NAh0Ti7FcgIUh-MQmiivOrB2hECKjQH1LOJ3lR6Xa3lBDfzu3VZVtX9SkzajShFvV5JUa5FvVpWZT2XlVCLebW6n6-Eup-YOKUqV0LMq-V8LmZC3Su1VuVKrHFRS1ksSuyksTNrD93Mh2ZiiAbc3C3KqppYuUdL6UYqhMMjpI-x_MvtJGzimul-aKhYlNYQ03sUNmzTVVZZ6ZopGz0Wyy18cluFztAeo-mT-t0Vk-din4881PmcTNfRfAf2Aa6aYe6EqCdDsJuWuU-XObErxK4x3A77mfJdIXYR6unPtA_-_6i4ELuUIBVilwj4IwAA__84b6xn">