<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/58452>58452</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
False positive compile error when expanding packs in function parameters
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
yabinc
</td>
</tr>
</table>
<pre>
Repro: https://godbolt.org/z/G6e3cK4W9
`template <typename A, typename B>
using ConditionalRewrite = B;
template <typename T>
using SignatureType = int;
template <typename... Args>
struct Type1 {
template <typename... Params>
using Return = SignatureType<int(ConditionalRewrite<Args, Params>...)>;
};
template <typename... Args>
struct Type2 {
using T1 = Type1<Args...>;
template <typename... Params>
using Return = typename T1::template Return<Params...>;
};
template <typename T>
typename T::template Return<int, int> InvokeMethod() {
return 3;
}
int Function1() {
return InvokeMethod<Type2<int, int>>();
}
`
When compiling the above code, clang reports below error:
<source>:10:3: error: pack expansion contains parameter packs 'Args' and 'Params' that have different lengths (2 vs. 1)
using Return = SignatureType<int(ConditionalRewrite<Args, Params>...)>;
^
However, the length of Args and Params are the same when instantiating Type2<int, int>::Return<int, int>.
The problem happens after https://reviews.llvm.org/D131802.
My understanding of the problem is below:
The error was reported in https://github.com/root-project/root/blob/master/interpreter/llvm/src/tools/clang/lib/Sema/SemaTemplateVariadic.cpp#L727 in function Sema::CheckParameterPacksForExpansion(). CheckParameterPacksForExpansion() checks if the lengths of all unexpanded
parameter packs are the same.
The expansion we care in the example is in L10 "ConditionalRewrite<Args, Params>...". Since we instantiate Type1<int, int>,
Args is a pack TemplateArgument: <int, int>, which has pack length 2. But for Params, its content changes in multiple runs of
CheckParameterPacksForExpansion. It can be either <type-parameter-0-0...> or <int, int>. And when Params is <type-parameter-0-0...>, CheckParameterPacksForExpansion() thinks its length is 1 (which doesn't match the length of Args), and reports the error.
I experimented adding below lines in CheckParameterPacksForExpansion() to skip the length check when a template arg is expandable:
const TemplateArgument& Arg = TemplateArgs(Depth, Index);
if (Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion()) {
ShouldExpand = false;
continue;
}
It can avoid the compile error. But I don't know if there are other cases to consider. So I'd like to leave it to maintainers for a proper fix.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy9Vttu20YQ_RrqZWGCF13sBz3Yst0aTYAgMZrHYkUOxa0pLrG7lON8fc_sUhItK6mLABUk8TaXMzNnZrjW5cvyM3VGR_m1qJ3rLE6i7B7fjS7XunGxNhtcfcfvtznlxR_Tr1dRchsl18P_PHG07RrpSET5yr101MotCVhZicPVTZTfBfneqnYjVrotlVO6lc1nejbKK9-y2M3Y-FnLjye2vqhNK11v6BES3oxq3TsMxXEsrs3GHsxZZ_rCCTaTimgxGBDiR8qfpJHbo7oQAc9nApjWA3kFDdoMLLt8GzweeSRI2cEoPETZFVt_HUq0uP3F4LJxcAHzY-rx-tAHMOz_jfNfScaxgCmTLD_iDkIwGIyc9fy-sEfkGN86781XYxXYcice2p1-oo_kal2iSMj9OE0mxJEfMQDPCAyMiPu-Lbis6Q_VX_nIV74Yp0D46_XPuJon4eRrTa0o9LZTDSfZ1STkWu8I90piU0Ujcd9Qp42zYk2NfhZkjDaci3FW85XVvSnIO75OE_zlPAv2wqKTxZOgb51sLUKDg9ZJ1VrcR6nIkfESVkTZIlB4IWRb8uXACNxwtXSilsBXqqoiQ0hWQ-3G1ax3mYmdjUXKIf8_jSRENLsbp-F3_Uw7Mn5kIZcBm9CVbyEfT7AmpCEvYZlYz1wF5MLJ1inpfB-dryjz7zzt4gDgETYxhdcNbZGoDsyFr4qz-3ooG9operZx0-y2w2S-TfP0MsnicTwfX0TflmQYWsm4EIobuVADJ07YwCh84cWztAN7qATS09WgXN2vYxCQIWntLmD4byrccInDutFrHLbSOs7rPaIl0xkKVwwfB2sK_DutG1Ts3nOWHyrW_EJbORweh879UxolS1XERddFWf5hAWoBWzW0nfAqPtermoqnT3uGfmKC3mtzt2dx6K9YvEtMFCxlhapG3LCcUdk0SLPvjZLKkMLTthgTJn6T60NbPaN1WRThOP9AImTiOuHOhzRBm2T_ge1ZjI5pC2K7R4LSYb6_pme2CpA82eFShqbfpx23-y2x6LU4o4s2UEUN1tqgNjQPINz0TlQg034QQAnDiCcID4CiRrnJB7jtG6c4XtO3nNkA51-qE4sHGJEtmCwIhETKh0VwcSjCRXKRhG0itHkDHhsSne27eGhvBP8TG6z5Psq4WrVMGYQ7pAOWU551IVmlJgvZhRNb6XD9dujwxII7Hj37Ke723fmKRw_MIjKKK4RelaXv9zDxsRxCgt-JWgv7pLoxGs_9kCJ5XP3SbDigwHyJiXKYI8J_UGLr3vInm3No4UXj-AyhXt5S52qO9wGd9G28-4JB9B6kIBwzxf6y6jvtd2x-y_Y4t_PBQZBZ00YNgV2gdspy1CcRnyzp8PlS674pvWTpsVaysXQCyMeIid-fPjh5LRgoKndalT6vYWnvC-lb5AF0CGR4alG0MGcM-dGhPa8LaVFHlIcTqzDX0d5aPECnRI2fiB81xPtVOT7fYkPzlsYC8A0oefCDJKJS3-IJLdP5fJ5ms2yaTMplXl7lV3LilGtoec-xik5bDJrdCdpAg1B05lgYcOMBfOgZO-lNs_zJ0hgWAB9Gu0NZ2xOvgtnldJZN6mWSTWeLrKLZbC4XlbxKi4KmKS2onGZXVZpNGgmm22U0u8HQawnZYxM4j2a3E7XMkixLk_QyS_JpksQl7OTVbJGkRIuqmkbTBCtDNYd1OjFLD2ndg5bTpFHWHXftRFqL1xAi7w72ZY_3OLN8kWvM2on3vPTI_wEZfTuU">