<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/143585>143585</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Bad source locations in implicit deduction guides AST nodes
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
michael-jabbour-sonarsource
</td>
</tr>
</table>
<pre>
## Problem
There seems to be a general problem in `SourceLocation`s of AST nodes that are created in `TemplateSubstitutionKind::Rewrite` mode. My understanding is that [this mode is used](https://github.com/llvm/llvm-project/blob/7e471c1fd0c4de4656cfaac39e247d207e987510/clang/include/clang/Sema/Template.h#L46-L55) to “rewrite” constructor decls as implicit deduction guides, or when "rewriting" expressions for the spacehip operator. The problem is that in this mode, `TemplateInstantiator` re-uses the location of child nodes while substituting into the template pattern. For example, in the following example:
```cpp
template <int N1, int N2>
struct SomeClass2Arrs {
SomeClass2Arrs(int (&arr)[N2]);
SomeClass2Arrs(int (&arr1)[N1], int (&arr2)[N2]);
template <int OtherN,
int Test1 = N1 + OtherN | 1>
constexpr SomeClass2Arrs(const SomeClass2Arrs<N1, N2>& other);
};
template <int N> using SomeClassSquare1 = SomeClass2Arrs<N, N>;
int arr[10]; SomeClassSquare1 scs(arr, arr);
template <int N> using SomeClass1Arr = SomeClass2Arrs<("this is an arbitrarily complex expr", "using comma", 42), N>;
SomeClass1Arr sc1a(arr);
```
In this case, the implicit deduction guide doesn’t contain the `DeclRefExpr` to `N1` anymore, but the whole thing has been substituted by the expression at line 14. The problem is that this results in bad incorrect `SourceLocation` for many nodes (e.g. note the bad range for BinaryOperator '|' `<line:14:55, line:6:39>`):
```
|-FunctionTemplateDecl 0x18ef4d10 <line:14:1, col:116> col:18 implicit <deduction guide for SomeClass1Arr>
| |-NonTypeTemplateParmDecl 0x18ef4448 <col:11, col:15> col:15 'int' depth 0 index 0 N
| |-NonTypeTemplateParmDecl 0x18ef44c0 <line:5:13, col:17> col:17 'int' depth 0 index 1 OtherN
| |-NonTypeTemplateParmDecl 0x18ef4538 <line:6:13, col:39> col:17 'int' depth 0 index 2 Test1
| | `-TemplateArgument <line:14:55, line:6:39> expr '("this is an arbitrarily complex expr" , "using comma" , 42) + OtherN | 1'
| | `-BinaryOperator 0x18ef45b0 <line:14:55, line:6:39> 'int' '|'
| | |-BinaryOperator 0x18ef4590 <line:14:55, line:5:17> 'int' '+'
| | | |-ParenExpr 0x18ef2c58 <line:14:55, col:112> 'int'
| | | | `-BinaryOperator 0x18ef2c38 <col:56, col:110> 'int' ','
| | | | |-BinaryOperator 0x18ef2bf8 <col:56, col:95> 'const char[12]' lvalue ','
| | | | | |-StringLiteral 0x18ef2b30 <col:56> 'const char[36]' lvalue "this is an arbitrarily complex expr"
| | | | | `-StringLiteral 0x18ef2bd0 <col:95> 'const char[12]' lvalue "using comma"
| | | | `-IntegerLiteral 0x18ef2c18 <col:110> 'int' 42
| | | `-DeclRefExpr 0x18ef4518 <line:5:17> 'int' NonTypeTemplateParm 0x18ef44c0 'OtherN' 'int'
| | `-IntegerLiteral 0x18ec8ef0 <line:6:39> 'int' 1
```
Live example on CE: https://godbolt.org/z/87rs3aP89
## Impact
The issue seems to impact some clang-tidy checks. For example, when running the `hicpp-signed-bitwise` check on the "simpler" example below, one can see that one of the reported issues has an incorrect range:
```cpp
template <int N> struct SomeClass {
explicit SomeClass(int(&)[N]);
template <int OtherN,
int Test = OtherN + 1 | N>
SomeClass(const SomeClass<OtherN>& other);
};
// Trigger the generation of the implicit deduction guides
int arr[5]; SomeClass s(arr);
```
```
$ clang-tidy-19 --checks=-*,hicpp-signed-bitwise file.cpp --
3 warnings generated.
/home/user/file.cpp:3:17: warning: use of a signed integer operand with a binary bitwise operator [hicpp-signed-bitwise]
3 | template <int OtherN,
| ^~~~~~~
4 | int Test = OtherN + 1 | N>
| ~~~~~~~~~~~~~~~~~~~~~ ~
/home/user/file.cpp:4:17: warning: use of a signed integer operand with a binary bitwise operator [hicpp-signed-bitwise]
4 | int Test = OtherN + 1 | N>
| ^~~~~~~~~~ ~
```
Live example on CE: https://godbolt.org/z/K36qvcP8o
_The result of running `hicpp-signed-bitwise` check on the previous example also results in broken ranges and can be seen in the previous CE link._
I am wondering if the described behavior is intended (e.g. for performance reasons, or to avoid making `TemplateInstantiator` more complex). Are there any caveats that one should be aware of before trying to fix the AST location in `Rewrite` mode? Or does this feel out of scope for the clang frontend? I would appreciate any thoughts about that.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEWMtu47jSfhpmU7AhUVcvvLCdGGhM_-lgkv2AosoWpyVSQ1Jx8i_62Q9ISb4odncaZ4BjBIgtkfXV9WMVmTFiLxGXJFmT5P6OdbZSetkIXjGsZ3-zolCdnhklmTaq0xzvClW-LwmNCI3gSauixoYEKxKsXirUCAaxMWAVFAgM9ihRsxrafiEICSQNnr2kr4ozK5QkaWBA7WD1_AJSlWjAVswC0whcI7NYDttesGlrZvG5K4wVtnOb_xCyJNGKRKs_8aCFRZIG0KgS5_B_79DJErWxTJZC7kEMkkmytpUwfpl72BksSXJPaF5Z2xonjm4J3e6FrbpizlVD6LauX8d_s1arv5FbQrdFrQpCtxnGWcjDXRnwuMQ4TVK-Y4xHC6RxVtIgw0WeJWFA6JbXTO4J3QrJ667EsyfP2DBCt6OV84rQ6Guczr4mCaEL51LyQEkekMVGD7YOv--BK2ms7rhVGkrktQFmQDRtLbiwUGLZcect2HeiREPoBpSGQ4USCKW9NOGUoIBvrUZjhJIGdkqDrRBMyzhWogXVomZW6Tm8VHgK6uBXIeHoVwdxFrIv0kXBCrfZRUjjrDM-0gj1kAcuB3gl6nLIgkMlagRzDLaLoLTK77GDXGiZtajlHLZKA76xpq09ttcFYafqWh3c1vFdtOqzlaRB_8fblgSro0ASbYS08Bj2Uiw8UhI9kGDV-xeeVYObmhlDV1obINmaBCuYPCY0d1sJzQlNmdaELkiyfqQ-yxYk-syecNgU-k29LseX9LrEqRXfbIX6kdCNf3v6uHcvaGwIJLqHxxAIXQ-LgWQbCHuToc8rlxIflfWvpo-jTe-43mk0BeWEHjV0f9n98fsHp5PoATrjwnWU-_xPxzT2in4E81gOyot0Mpy3k3UYOMdE649yDHfK-5hsYAjN7-gTrrS-rowPDvUVIAwwCUwXwmqmRf0OXLnse_PlRSj15UFpL5urxlW-fxj7yF5YdQlteMhGA0bNx1TurfgylCFnxpeCq4NbVAClQiNHHllYF3DLhuIhaXCPvP4Tdw9O6zTwHJQGj6H7zuR7o7RHKDrrNxwqVaMDl3uomIECUZ4KGEso3v26E8cAs1ALiRDG1znFW6LRdLU1rqgL5k4DrrRGbq-eJZ61GibfBxohNMf5fg5SWfToToRmco9-5VpIpt-_DcQGhGYk2xCaOdkk2jjlSLQKYxKtHA9vYHiSkmgVLVyQ0sBHYsorPtc3s20nvb9HJnQeheAtzHEXl2EAEwxfPVzV7muYuvwbfuSnGJJoMw2js-QiT_oCdrXslHhU8uW9xVGHJ6abcz3iOHdCR9gzFZIzDRLnHCGtc06Jra0gACFLfIMAHn8DjJ8bnTjJ0RlidoaY3UQMR2r7NGwS5Wew6QTWR_LXsLRnzROqy5LZCLnS-65BaacxvZ43vgp8vv0Gb8BV4oAjc3wkcpqdaQte30nKjw4qPiTjDcVP3jlWywUG-HjcQFn8HCU55sAlCl1fRfFIT0yjdBQ1gFCe5NdBxgynFwDXxd52FeXRWb0k6bnk4Irq1x00BuSWq2ixu4GySAaQ_gjmFfNHXt8LZFC_srrDz0F7-Gerhdx_Fda36iN6FFygX0GM0iniZ0-_n2qUBjc0Ks80-qwPpkfsTeQ0mH2RFveoJ7A8vCDHSYDjqyLTYHZ2ch5zP8ynzDfJ9CscdkGbNBs7uux2-t6whOe4CyYUOK3ncHKAfRWvOHbOoCRsHki0gsmUpMpC1XautBti_p_QbZ5pE7GnfDGciP2s-KVpGbfHURGEMd3ZuCj8azCqQfAT0cyK8h14hfy7-dDe-9FFd1K64A69SiV42878PFvOCmEPwvhp0Itw2vt1lBp3kKLuh53etAJrdfBTkUTgTDq1-v7DPVA7v1Vjq7SfRp3mxnc4TJ51I76p-PSA4Tw_nSmO4wS-DWf98VU_HvQDwND8_3e9v29ix6OCriH0GfQ4dv7nwJNWn0SbQfgnevw-SeBFi_0e-3GyvxQYR76ftafmoqlPpj09mJ93whc_aXyWV7NwAbNZn1wkup8RuiJ0cy2DYCdqnPO2hdmMBKsIDky7rDOjGVjOezMr1bhxvjPOGdtxm6uyodJX4173tTM-sRj0cC4srmT7EVuWcBC2AgaFPxpgVEYd-9RkfTXfk_sh3NFACL9Oi5E4zj8kefjhP8Oq-MOqT6bRNYAf1z7w4xdejP8XXvxX7b7m36Pl_wbx_hGl_7zyp1z1Av968azlZifnpJEuP0uVrcZXoTpz1IPVRl3MYlp9dzTsaM9RYemps_CkLscbmKOUzYPr8b7P_xqmVGANHJQsUfubnZ4ISjRci8KNilixV6G06yZcVGWJ5XGWc-NOi3qndMMkd0Yyo-R4r2UVsFclSmjY98HgW_dQboIduxNCF3NYaT8kanTzLXD2isya01FgKtXVpb_bPDDtc6_AnRNi9bs_ixTsxJu3ZfX8crrb6m8wJ3eUJNrCN-1n8H7Q3SHWoDofLsNVi8crOE9dsNPKu8Jt_AIHrwtrW41cuBJ3KttKdfvKGmCF8mM5s46f7splVC6iBbvDZZjFiySncUrvqmWwiDDHBWdZmOzyLN_tdukuieKkxLhYxPxOLGlAkyANg3ARZHE4p3GQc14UBU3inEYpiQNsmKjndf3auGy88wfkMoyjJE_ualZgbfwFM6USD_3x6Xqx5P5OL_2FatHtDYmDWhhrTmKssDUu16yE_ur56E2ffTfPjNNF8l2n6-Vv3-n2xzuh28GA1yX9TwAAAP__DRIT9g">