<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/63169>63169</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Clang crash due to overflow of PseudoObjectExprBitfields:NumSubExprs
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
alinas
</td>
</tr>
</table>
<pre>
Reproducer:
```
struct t1 {};
struct t2 {
t1 b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16,
b17, b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31,
b32, b33, b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46,
b47, b48, b49, b50, b51;
int v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16,
v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42;
};
void aj(...);
void f1(t2 w) { __builtin_dump_struct(&w, aj); }
```
Analysis of cause from @dwblaikie:
The data read in https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ComputeDependence.cpp#L682 is invalid and causes the crash. This is due to the unsigned:8 at https://github.com/llvm/llvm-project/blob/main/clang/include/clang/AST/Stmt.h#L597 overflowing:
```
// These don't need to be particularly wide, because they're
// strictly limited by the forms of expressions we permit.
unsigned NumSubExprs : 8;
unsigned ResultIndex : 32 - 8 - NumExprBits;
```
Removing an element from the repro (either of the struct or int member variables) the length of the range is 254 (so getNumSubExprs in 255)
Adding one element, it's not that it's /good/ at NumSubExprs 256 - it still has the same problem, the value gets truncated to fit in the unsigned:8 bitfield, but because it overflows to 1 (rather than zero) at least the range is valid (empty (the -1 doesn't create the end<begin)) so it doesn't crash - but probably isn't doing the right things either (because it's not visiting all the subexprs - it's visiting none of them).
What the code is /meant/ to do when the size is too large... is there a bail out?
Side notes for debugging:
An assertion in the llvm::iterator_range ctor (also, this code should probably use llvm::ArrayRef since its iterators are just pointers anyway - and a similar assertion should go in the llvm::ArrayRef ctor), at least for iterators that support op<= that begin <= end would've caught this.
Also a more specific assertion in PseudoObjectExpr::PseudoObjectExpr ctors that asserts that NumSubExprs actually can/does store the value (without truncation/overflow/etc) that it's intended to.
Both of those assertions would probably be worth adding once (the iterator_range/arrayref one might be a harder sell if it's too expensive/may have to go under LLVM's EXPENSIVE_CHECKS category) the bug is fixed.
@rjmccall
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysV11v47oR_TXMyyCGRclfD35wsmv0ore3F5vFbd8CShpL3FKkQFJ0fH99MRw5djbtQ4EuFkxMcc4czjkzclQIurOIe7F6EqsvD2qKvfN7ZbRV4aF27WX_DUfv2qlBL8qDWH4Ry4NYL-f_-WOIfmoixALE5klsvojyaT734bHMj_MW0OF6KeQz1EVeZV7LvFZ5XeV1nddNXrd53XHUHMzRBYcXHF8wQMEIBUFc09K_umC4gvEKBpQMKGc6DCgZUDKgZEDJnCSjSEaRjFIySln8nLOcL8iAJQOWDFgyYMmAJQOWDFgxYMW0Kkap5joxSsUo1ad7VgxYMWDFgCsGXBXvKgFoGyHl_ZTzpJwm5SwpJ0k5R8pEU4ZNGTXtOGoO5mhWI7EaidVIrEb6pEZiNRKrkViNxGokOdNhQFYjsRqJ1UisRmI1EquRWI3EaqRPaqRyviADshqJ1UisRmI1EquRWI3EaiRWI1Xy5vRPrk9Ot6B-CLldLBZC7t4f5wenQshtlHAWckdtAa-v9aRN1Pa1nYbxlXtG0HXWZ0pGSIQBlOk_NSGvB6vMJegA7gSNmgLCybsBRLVsz7VR-l8ab12c1-89QquiAo-qBW2hj3EMdEgehTx2OvZTvWjcIOTRmHT98Th69wOJ4rE2rhbyOChthTw2RtmODmnaPLx8F_L47IZxivgFR7Qt2gYXzTgKWf663krQAbRNylC5bMusA8QeofEq9Av43tORAO2EEF1-Mtk8tlpRHrag4v-Ls7aNmVq822H-L3GIi54Ir3YbcAn9ybiztt1_m4hkMuYC33sMCK2zQm4iWMSWLlEjjMpH3UxGeXOBs6a0z1AjqxZ7vAi58fgJL0Svm2guYPSgI7ZQX3JJTs4PWXZ8Gz2GoJ0NcEYY0Q86Lm4419rBb9PwMtVf30YfQJQH2N5NhLtj3zBMJv5iW3zLx0oJj7CFR4qn4Ccdw837H-vwDQeXtO1AWUCDA9rIhiTGnl4sIOQWdezRE3fanl8XzuexNOBQo4ekvFa1wUD9QqcM2i721xivbIfkEbmqCDE46DDeX1BbkKsV9RD3SdsSLWfxyouqr6OQmwDWRYi9itfPZCnnWqq-ih_KJldreAQdIURtDPSKjRvUgDB6VxscCJf2kjITEqsA0U-2UZGdcNKRyH1yda3jSaNpsyum-O4MHd8NGCi-oPt6lSsYe2XhT_SOqqQiGFQhfiwQNxoVfRjjhX6hx48FtA4De7TxqGK2IKBtRflcY0dtsiPU4IjB_WEVenjMFOnGqjYX0PPD1lGRc37d9cRE2y7ArLeQ29ul3gufdNAxW8YYLuZUYy724_XY-xFL-rEFBiF3s8n_QdLl-eHafGdqdFQk8ZEq1jo498glD_rPfCQ6B0b5DheLRf7co0dQUCttwE1RlMf7ofmiWyS2GKjvoMV66rr7eXCwoEJAH7WzV3nzJCoPojzoiF5F519Zlia6XA1lgmO76MDkQ-8m094KS7W6wRy8V5dveIKgbUNFDHBFDqA8wo8pRBidthFpx17O6gKPecwqCHrQRvk7nnO2zn1m_J6KuAp-vb4bjEpwS5w7J0zj6HwEN4ryWZRfeDcbCeYdtC2cKaGQm4Q092eLhFnHgwkOFAzOI4QRG33Szceq_h5wat3faxrq1JDM9efdzHnmxeHzh_tOVk2clDEXaBS9EcjgECKlvjWvkNuzjr2b4rWFNY3147UfhTxibHhC3aYHVd-2udnniz256-RyAW83ClyOm9o1wtn52IO6TqsGrx370UJCHhUp5PGUZ9qQ260mB_fKt-ghoDGgT1dS5Hd8G9EGnTC_CC_Qq5RfsJ2DyVLMr7_-8bd8-us_f__628svf3x9ff7L1-e_vgBNr875y3Ua11NHXXPSb9gu7htFVEv_Y2gaauaHdl-2u3KnHnBfrLfrYr0sN9VDv1_LctuqZb1e1rtys9uumnKnmk2zPTWq2Nblg97LpSyX6-Wm2KzkqlrI02m1ksW6KWrVVvIkqiUOSpsFOXbhfPegQ5hwvy6L9e7BqBpNuP6J4_f5u0A9dUFUS6NDDLewqKPB_TO9_efRNn_ruGpMuv1ssKd5VNM3kDtPPUze7P_nbyaZeBDymLn_OwAA___sNzAZ">