<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/63761>63761</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Clang frontend crash on constexpr libc++ vector::insert
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
hfinkel
</td>
</tr>
</table>
<pre>
Compiling the following with Clang (15, 16, and trunk on https://gcc.godbolt.org/z/P5fa9a9z6) crashes:
```bash
clang++ -std=c++20 -stdlib=libc++
```
```cpp
#include <vector>
constexpr void ins(std::vector<std::size_t> &t, std::size_t i) {
t.insert(t.begin(), i);
}
constexpr bool test1() {
std::vector<std::size_t> t;
for (int i = 0; i < 57; ++i)
ins(t, 0);
return true;
}
int main() {
static_assert(test1());
}
```
There is no crash when not targeting libc++.
With a Clang 16 asserts-enabled build, the (truncated) backtrace looks like this:
```
clang++: /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:3438: void expandArray(clang::APValue&, unsigned int): Assertion `Index < Size' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0. Program arguments: /llvm-project-16.0.0/bin/clang++ -std=c++20 -stdlib=libc++ -c -o /tmp/q2.o q2.cpp
1. q2.cpp:17:1: current parser token '}'
2. q2.cpp:15:12: parsing function body 'main'
3. q2.cpp:15:12: in compound statement ('{}')
#0 0x00007f0d69f704e5 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /llvm-project-16.0.0.src/llvm/lib/Support/Unix/Signals.inc:567:22
#1 0x00007f0d69f6e71c llvm::sys::RunSignalHandlers() /llvm-project-16.0.0.src/llvm/lib/Support/Signals.cpp:104:20
#2 0x00007f0d69e8ab68 HandleCrash /llvm-project-16.0.0.src/llvm/lib/Support/CrashRecoveryContext.cpp:73:5
#3 0x00007f0d69e8ab68 CrashRecoverySignalHandler(int) /llvm-project-16.0.0.src/llvm/lib/Support/CrashRecoveryContext.cpp:390:62
#4 0x00007f0d6e0e01b0 __restore_rt (/lib64/libpthread.so.0+0x141b0)
#5 0x00007f0d698fa9e5 raise (/lib64/libc.so.6+0x3d9e5)
#6 0x00007f0d698e38a4 abort (/lib64/libc.so.6+0x268a4)
#7 0x00007f0d698e3789 _nl_load_domain.cold (/lib64/libc.so.6+0x26789)
#8 0x00007f0d698f3026 (/lib64/libc.so.6+0x36026)
#9 0x00007f0d68148af9 clang::APValue::getArrayFiller() /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:3438:3
#10 0x00007f0d68148af9 expandArray(clang::APValue&, unsigned int) /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:3452:54
#11 0x00007f0d6819b9af clang::APValue::getArrayInitializedElt(unsigned int) /llvm-project-16.0.0.src/clang/include/clang/AST/APValue.h:503:5
#12 0x00007f0d6819b9af findSubobject<(anonymous namespace)::PointerExprEvaluator::VisitCXXNewExpr(const clang::CXXNewExpr*)::FindObjectHandler> /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:3736:39
#13 0x00007f0d6819b9af (anonymous namespace)::PointerExprEvaluator::VisitCXXNewExpr(clang::CXXNewExpr const*) /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:9662:31
#14 0x00007f0d6819edd5 EvaluatePointer(clang::Expr const*, (anonymous namespace)::LValue&, (anonymous namespace)::EvalInfo&, bool) /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:8826:1
#15 0x00007f0d68177e0d Evaluate(clang::APValue&, (anonymous namespace)::EvalInfo&, clang::Expr const*) /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:14988:25
#16 0x00007f0d6818f2d8 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:5235:9
#17 0x00007f0d6818e950 EvaluateStmt((anonymous namespace)::StmtResult&, (anonymous namespace)::EvalInfo&, clang::Stmt const*, clang::SwitchCase const*) /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:5247:40
#18 0x00007f0d681938bc HandleFunctionCall(clang::SourceLocation, clang::FunctionDecl const*, (anonymous namespace)::LValue const*, llvm::ArrayRef<clang::Expr const*>, (anonymous namespace)::CallRef, clang::Stmt const*, (anonymous namespace)::EvalInfo&, clang::APValue&, (anonymous namespace)::LValue const*) /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:6208:36
#19 0x00007f0d681b7cae handleCallExpr /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:7800:78
#20 0x00007f0d681b7cae VisitCallExpr /llvm-project-16.0.0.src/clang/lib/AST/ExprConstant.cpp:7615:24
...
```
Courtesy of C-Reduce (and a small amount of manual cleanup), below is a reduced test case. Note that, **even with the reduced test case, the crash only occurs when compiling with -stdlib=libc++** (and the fact that some of the classes are defined in namespace std is necessary to trigger the crash).
```cpp
namespace {
template < bool, typename a = void > struct b {
typedef a p;
};
template < bool c > using d = b< c >;
template < typename a, a e > struct f {
static const a g = e;
};
template < bool h > using j = f< bool, h >;
template < typename a, typename m > struct n : j< __is_same(a, m) > {};
template < typename a > using o = __remove_reference_t(a);
template < typename a > struct aa {
using p = a;
};
template < typename a > struct q : f< bool, __is_final(a) > {};
template < typename a > struct r : f< bool, __is_assignable(a, a) > {};
template < typename a > struct ab {
using p = a;
};
template < typename ac > struct s {
constexpr bool operator()(ac ad, ac v) { return ad < v; }
};
template < typename a > using u = b< r< a >::g >::p;
template < typename a > u< a > constexpr ae(a &ad, a v) { ad = v; }
template < typename > struct x {
typedef long y;
};
}
void *operator new(unsigned long, void *);
namespace std {
template < typename a > constexpr a *ag(a *ai) { return new (ai) a; }
template < typename a, typename > struct aj {
using p = a *;
};
template < typename, typename ak > struct al : ab< ak > {};
template < typename an, typename ao = an > struct ap {
using p = x< ao >::y;
};
template < typename an > struct aq {
using ar = an;
using as = ar::as;
using at = aj< as, ar >::p;
using y = ap< at >::p;
using au = al< ar, y >::p;
template < typename a > constexpr static void av(ar, a ah) { ag(ah); }
};
template < typename > struct allocator;
struct aw {};
template < typename a, bool = q< a >::g > struct ax {
using ay = a &;
using az = a;
constexpr ax(aw) {}
template < typename m, typename = d< n< ax, typename aa< m >::p >::g > >
constexpr ax(m bb) : bc(bb) {}
constexpr ay bd() { return bc; }
constexpr az bd() const { return bc; }
a bc;
};
template < typename ac, typename be > struct bf : ax< ac >, ax< be, 1 > {
using bg = ax< ac >;
using bh = ax< be, 1 >;
template < typename w, typename bi > constexpr bf(w bj, bi bk) : bg(bj), bh(bk) {}
constexpr bg::ay bl() { return static_cast< bg & >(*this).bd(); }
constexpr bg::az bl() const { return static_cast< bg const & >(*this).bd(); }
constexpr bh::ay bm() { return static_cast< bh & >(*this).bd(); }
};
template < typename a, typename bn > constexpr a bo(a bw, a bp, bn bq) {
return bq(bw, bp) ?: bw;
}
template < typename a > constexpr a bo(a bw, a bp) { return bo(bw, bp, s< a >()); }
template < typename > struct br {
template < typename m > constexpr br(m) {}
};
template < typename a, typename = allocator< a > > struct bs;
template < typename bt > struct bu {
bt bv;
};
template < typename an > constexpr bu< typename aq< an >::at > cg(an bx, unsigned long by) {
return {bx.allocate(by)};
}
template < typename a > struct allocator {
typedef a as;
constexpr a *allocate(unsigned long by) {
return static_cast< a * >(operator new(by * sizeof(a)));
}
};
template < typename a, typename bz > struct ca {
typedef a as;
typedef bz ar;
typedef o< ar > cb;
typedef aq< cb > cc;
typedef as az;
typedef cc::au au;
typedef cc::at at;
at cd;
at ce;
at cf;
bf< at, ar > z;
constexpr cb bx() { return z.bm(); }
constexpr at &cp() { return z.bl(); }
constexpr ca(au, au, cb &);
constexpr void ch(az);
};
}
template < typename a, typename bz >
constexpr std::ca< a, bz >::ca(au ci, au, cb &bw) : z(nullptr, bw) {
auto cj = cg(bx(), ci);
cd = cj.bv;
ce = cf = cd;
cp() = cd + ci;
}
template < typename a, typename bz > constexpr void std::ca< a, bz >::ch(az) {
cc::av(bx(), cf);
}
namespace std {
template < typename a, typename bz > struct bs {
typedef a as;
typedef bz ar;
typedef aq< ar > cc;
typedef as az;
typedef cc::au au;
typedef cc::at at;
typedef at ck;
typedef br< a > cl;
constexpr au capacity() const { return cp() - ce; }
constexpr ck cv(cl, az);
at ce = nullptr;
bf< at, ar > z = bf< at, ar >(nullptr, aw());
constexpr au cm(au) const;
constexpr at cn(ca< as, ar & > &, at);
constexpr at &cp() { return z.bl(); }
constexpr at cp() const { return z.bl(); }
};
template < typename a, typename bz >
constexpr bs< a, bz >::at bs< a, bz >::cn(ca< as, ar & > &e, at) {
at co = ce;
ae(ce, e.ce);
ae(cp(), e.cp());
return co;
}
template < typename a, typename bz >
constexpr bs< a, bz >::au bs< a, bz >::cm(au da) const {
au ci = capacity();
return bo(2 * ci, da);
}
template < typename a, typename bz >
constexpr bs< a, bz >::ck bs< a, bz >::cv(cl, az ad) {
at ah(cp());
ar bw;
ca< as, ar & > e(cm(1), ah - ce, bw);
e.ch(ad);
cn(e, ah);
return ah;
}
constexpr void db(bs< unsigned long > &t, unsigned long i) {
t.cv(t, i);
}
constexpr bool cq() {
bs< unsigned long > t;
for (int i = 0; i < 57; ++i)
db(t, 0);
return true;
}
static_assert(cq());
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkW81u47qSfhplU2hBpmxZXmThdseYAxzcaXTO3Lm7gKQoWx2JVEgqjv30A5L6txw76eym0XAskaz66pfFkoyVynacsXtv8d1b_LjDld4Leb9PM_7M8jsikuP9RhRllmd8B3rPIBV5Lg7m6pDpPWxyzHfgoXi28NAGZpH5xDwBLSv-DILDXutSeeHaQ1sPbXeU-juREJFrX8idh7YnD21_LlK8wqtT5KEVUInVntklwQ8vaD6jwP0nWO3dLWp4e-i7h77DN6UTL_xB3SUK7I08I174I89IfXtEaZI8Lcv6DgozTvMqYeCFm1dGtZBe-FCzFlxp9lZKeBVZAhlXHoothLUXrpvJm_aOyk7sSXvhA3go0kZHoyHIjOjessYIAKD9jCsmtYdi7RO2y7iHYg-tzGoz2wsbgZY_xqiIEDlopvTMrelRvgmlbokDpEIaA2dcQwZe-AMCL_xuv25gsTTfnXYtpha9U4kVNeiDBZBMV5IbB2HnIhguBW5EHcDGOqNPWDUq6YSb1MWklf_ZM8kgU8CFczM47BkHLjRoLHdMG7_u_MXvr_1f4-64dvhZBA6J-sY4JjlLgFRZnhhxTZQYgLLiFGuWGDkIps9aYsogF-JZQZ49M9D77KKXn3m4F67BQ9s8fy2-lVL8ZlR_m0V-4Ae-ktRD23ru1jg92q4f__HQ9uGtlBvjFJhr33h2uA7nYWxoWb9lbyXmyVpKfPRQ7ChYT1j__DfOK-YhG88Vt1nC-Lm2yl7D2kqfCQ5eFPzFE_Zm_eExOzEPLSHFWc6SWn8__35YPz6AqkiRacBAqh1IVgqpQYtxfsj0viI-FUUt7EhmD20zpSqmPLS1eaaJUaN1Z9JW1wZ6KVkpBWVKsQSUqKS7bVZipQTNjIVAVhwUlVmpa8iPGtNnSKqibA0U-PBTip3EBWC5qwrGtbpsFA9tifHi7YeTFHyj8E0YsrooPbR9Qb6AF-S3iWnmg_1X3wvXs6X5MFhoJSXjGkosFZOgxTPj4KGliQq0dMuR31u5MB_ILDVLjPenFafWrib3m7UuGuvF4RnvjkLGgYqiFBVPbLQyoyKwIbo0cewwtDnCQ2EAwVsQBMEyDZJolS6DOVuANbpLR0flvvyUGdfWJP84u8bdJIkPT0JpyXBRe6tz0veDpfEsGyuPVWmc0UPb_-HZm7mR7TjOlZ9x6oXrRWT0i1CHezbEHbHljE7h_lVxR-q_ME9yJlWT1T4BrcFUqz2YG0xBhwkNMLEYkygGx3djw-IzTO3KX4yKVyaPG8E1e2vyyDI0qun4h1P8B-sHqnAbymeV8Q6ucBV44TrqWWveR8YCFsxIAE9PkiktJHuStY8aJtHc_S31XjKc-EqYSP4evM3mMxIMfHcxkDdO8YotQOJMsXNy1BCKLKEwWbHFgFA0JMTCGM8BEzGFq0cIRTGeDwgtx4SW8QqeeP6UC5w8JcIEsk9Fnlyhu4xXA7rxSNIwQNH7MkaBicQeiVWfRDybxzhdwcR2Yy92TNsdaZvlzlGuesnHtr6wre9mwRSuz22KX4RwYVLpYt5BnA0hrsgKp1dV9xfPdIbz7MSSh9xUS58CW2-tvTsOeM3S3xuoQS8PGLxoCm-a8eSxIoLYLTzceCjGXPBjISoFHBdMlTavr-p8LzKumTQKenjFeYVtnWpG_p2pTG_-859_sYMZNfYxGuwrpD-6bkluM578t2XfJCBbi3-ByZZhZNNOp4JwSgVfKfKUsGAV4UT-EsFWUWR8MZx1gs1HgrEkWUANl9USDPGNkG2uqeHvfoRdmWsY_8VTUc82R56vkj2OUWRrqlb0xVD05ZIFSSv6e2niY0JcVt3XCDabr2KTA1EvYqOhaHGKkrgV7VEX2qbgd6Uws34xVZlc82dSG0oDh-mPHTJN9xus2JfrZYFCU8j2gng50gpbLYL_f1qZm9J3HnRqiUcpIIwJrcvMbX1y2OA8H0bEoz13_S0oNuMj_M2yH4zmH08VgxVdCW53wV8s9cLNxZAKH27gYoQxdK7Y49OW_VCyOBP5a8wcocDWRVFn5lHBRpYUM9i70wTOc6vIr2C9jIPA_mlZo2CKtdsEv5RzZI-uqC61fN9_p2-0EZXUTB1BpLD59oslFWXOWAlgUAXOc8CFqLg2MwrMK5wDzRnmVVl37AjLxQEyBRikXZ_Y_hxQrJgP_xKagd5j7bxg7aE1e2Xc9Vj1np2vaTpNrucheH4EQWkllWtp0bZpa0lMdkMtm0YM29vFVFsUoETBjCiWQ46VYgqwZJCwNHNlZOeeoHRie2qMMqWwPIIWoGW22zHZQfTQyn-_4doRbLt-mhVljrXtwNYb_Ab0sWRmLmDbjbSNLFPNKS0rqoH0u6hmbsJSwFAOWoThJQZALa3K9kISy4CYMXt7elmHx3aWgPXRpH00rofp4hcw7Cx5diOwfQ_Yb7sy7WtlfyvA9qro4-TghWv4baY_PWXqSeHClDV2RWETjamXXRfnCpMeTmFxmrN2IV7Zk2Qpk4xT9qQd7dVNtGqIGPd16RiUlgG-rsJpki9W6oEerfRpxnFeQ_yo5DVpeYG0e-KCSd6q9w-YYPIlKqF9mqpPcvREQZRM2pNJ3XePMQVsm96YwmvdsG8a_DixbF7tE4K2Lf8h_6m6AJTmAzsnt0fd7mt5G8WWQE8qbK0AHopqMTopsIv-IfxpBj3tvU1ln1zwHRwnLdJSdmkMrRsVA2eH_sHd0DAIm3n94Bmm4unsOdJGTwWGGt7VeljjbGRGzg52j7D38Q3aGGaZvrf-vuitVqKbPXa4CzwPeOQ27rD1mXrotrjiQ6oudWE-IF5eEuDNshOdT05b-xLrAZOXcyZY1mh6j9HqEeVG6mYBVucztJthcztW1svlVPA0C45ufmnn6_dmYhefOLdTpSF9nJ5_myvW-6N1cfxqnE66oMT7Niqto-6d938krQx8JDdHESHbJc3A4UZfafoNVvyXqczU8nqbsOaxdfroXKenUf7uJ2H8ZqQ_NE9GG-kv6bcYReIPSMw4t4Dfhv6Ozc2iZ72xQO2z7zNABRDi9rA1mOIyri8HCHtrjkCS7vluk2cIHVh0sOLUrXDF03vrsLt1--43UAQZuApJXTpx8e2KQLSpr4lNRLM2xwzsSFx1N1g5tjXZ9-b0qF0NnMMQcjaKI5J6KD4A-W39NAPy3JrHhI-5784ke3P1_J6xSH1ONUbLz41WP5WnWGkrw874tNNS7KG1fcKNVn5jvYsWbtmcOjZnlj5nVk_5HMt9J1lxXbL9B9jcmEE6A_KzPZkIuyGTg0uApLT24kBeRu-JNFHwYkxpZ5u5xtpba_DDealxa10wgWEYsWLAcwOqy4S9FzM-UD0ROSifppPa2NlNNVqMffijJnD7WLsvNJViH5u6QpDowfSqLwrRQF4_XhL0pKyG427T4V2Sdjs1ULs_ciBvg2dUtgIlx2nf8ZbfyZtfS28KYjtxskq95UzSaHH6HD6oUMZVaAfhCvLu33S4WnK1I44qanK0Yyo7MZE2x9DhS0TwB6F86uuC4huU0NwmJ1vGnd0Xrrpy5iUTE5wzUOJm0KkZCvBp4r6ZbJ2nAly9N64B918JwxpoMrpmo-u0d01SV0x2xSecJt2AEuu542R88psUfblGsPsALScX51cWU2wcobLw7KdRpnuGPYXSFqjUbJ74NH757NaQmfAaN79fDtfv5VFbnLmq89SFfI0aaDYGTg7Nhn_yUMyrPC-1LaXJYRRIuNICqOsn2dzRqN8Sy0YacEdi-tvvJTMA6tInTd2fvmN09rAj4KHvhuofKGlshqtKas006Gs0jv06FjmdfJvwYyfsdzICUV-QEersL78s4K_Fe0tWA32eAtrbMmneqc9N6wVpBRSXmGb6eKnIaz3mm0spFwL2GeirfchkXf809FObjqzLNa7_fipyXaazgWHomGPX-G1TGMlW1Gmklmt6ngbKDXQ8PJC76hLqJ0FYX-TzJ4nOMC8vqf7C-s9tgeNkRtRkeGJ9aeSKklirpUE600Bd56a_H9kun3vxk_n187RuiR0suxTA_O5q4r1lKr4yx19SS3VRLc7HIMEDG3b5HKh7S3sYaOdy2Ood2VrIbSAJnkx9Xy4bfb440g9p21geGxfvB8Ya2FH2DzsAF1zHWtvocFabG-9dqml2xx4J5rvdIxnFovFM53_7SdXi_Xvv5tttKyFm47FqGJa6_d8IDEfGvxDQvtWXvvn3APTl7K16uAThz38A0Pyzkn74dwDj1_0b7O-_63-X3IfJKlzhO3Y_i-I4Xq2W8fJuf09TjBBicbKYLWeLebJYkChJwmWK0DyMI3yX3aMAhcEyWM2C-Wq-9KPFch7TZZrEbIXjlHjzgBU4y_08fy18IXd39j30-yhcRrO7HBOWq-ZXNPLePp4m1U558yDPlFbdMp3pnN27nxGkUnDNeNI-xe2l6t4b4c0vNUyMuN-E3FUyv__8m_MW9P8FAAD__z63Fxk">