-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Crash in TreeTransform<TemplateInstantiator>::TransformExpr with invalid expr #107560
Comments
@llvm/issue-subscribers-clang-frontend Author: Utkarsh Saxena (usx95)
This is the creduced version: https://godbolt.org/z/v14xaYf9r
<details> # 1 "" 3
typedef int size_t;
template <class _Tp>
_Tp &&forward();
template <class _Fp, class... _Args>
void __invoke(_Fp __f, _Args... __args) noexcept(noexcept(__f(__args...)));
template <class _Tp, _Tp...>
struct integer_sequence {};
template <size_t... _Ip>
using index_sequence = integer_sequence<size_t, _Ip...>;
template <class _Tp, _Tp _Ep>
using make_integer_sequence = __make_integer_seq<integer_sequence, _Tp, _Ep>;
template <size_t _Np>
using make_index_sequence = make_integer_sequence<size_t, _Np>;
template <class>
struct __type_identity {};
template <int>
struct in_place_index_t {};
template <size_t _Idx>
in_place_index_t<_Idx> in_place_index;
struct Trans_NS___access___union {
template <class _Vp>
static auto &&__get_alt(_Vp &&, in_place_index_t<0>) {
return forward<_Vp>().__head;
}
template <class _Vp, int _Ip>
static auto &&__get_alt(_Vp &&, in_place_index_t<_Ip>) {
return __get_alt(forward<_Vp>().__tail, in_place_index<_Ip - 1>);
}
};
struct Trans_NS___access___base {
template <int _Ip, class _Vp>
static auto &&__get_alt(_Vp &&) {
return Trans_NS___access___union::__get_alt(forward<_Vp>().__data,
in_place_index<_Ip>);
}
};
template <size_t... _Is>
struct __dispatcher {
template <class _Fp, class... _Vs>
static constexpr void __dispatch(_Fp __f, _Vs... __vs) {
__invoke(__f, Trans_NS___access___base::__get_alt<_Is>(__vs)...);
}
};
template <class _Fp, class... _Vs, size_t... _Is>
constexpr void __make_dispatch(index_sequence<_Is...>) {
__dispatcher<_Is...>::template __dispatch<_Fp, _Vs...>;
}
struct Trans_NS___visitation___base {
template <class _Visitor, class... _Vs>
static constexpr void __visit_alt_at(_Visitor, _Vs...) {
__make_fdiagonal<_Visitor, decltype(_Vs())...>;
}
template <int _Ip, class _Fp, class... _Vs>
static constexpr void __make_fdiagonal_impl() {
__make_dispatch<_Fp, _Vs...>(
index_sequence<(__type_identity<_Vs>{}, _Ip)...>{});
}
template <class _Fp, class... _Vs, size_t... _Is>
constexpr void __make_fdiagonal_impl(index_sequence<_Is...>) {
Trans_NS___visitation___base__make_farray(
__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...);
}
template <class _Fp, class _Vp, class... _Vs>
static constexpr void __make_fdiagonal() {
constexpr size_t __np = _Vp ::__size();
__make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<__np>{});
}
};
template <int, class _Tp>
struct __alt {
_Tp __value;
};
template <int, class...>
struct __union {};
template <size_t _Index, class _Tp, class... _Types>
struct __union<_Index, _Tp, _Types...> {
__union();
__alt<_Index, _Tp> __head;
__union<1, _Types...> __tail;
};
template <class... _Types>
struct assignment {
template <size_t, class _Args>
void __emplace(_Args);
template <int _Ip, class _Tp, class _Arg>
constexpr void __assign_alt(__alt<_Ip, _Tp>, _Arg) {
struct S {
void bar() {
assignment *f;
f->__emplace<_Ip>(forward<_Arg>());
}
};
}
void foo(assignment __that) {
Trans_NS___visitation___base::__visit_alt_at(
[this](auto __this_alt, auto __that_alt) {
__assign_alt(__this_alt, forward<decltype(__that_alt)>());
},
*this, assignment());
}
static constexpr size_t __size() { return sizeof...(_Types); }
__union<0, _Types...> __data;
};
template <class>
struct hash_policy_traits {
template <class... Ts>
static auto apply(Ts... ts) -> decltype(abcd(Ts(ts)...));
};
template <class Policy>
struct raw_hash_set {
raw_hash_set(raw_hash_set &&) {
hash_policy_traits<Policy>::template apply<int>;
}
};
void Foo() {
assignment<int, double, raw_hash_set<int>> v;
v.foo({});
} </p> <details>
</p> |
Note, assertions trunk is usually more useful since it usually crashes earlier and/or the assertion can provide more useful information. Crashing since clang-7: https://godbolt.org/z/cc86KGrvj |
Duplicate of: #63819 but this one is a shorter reproducer. |
…ansion (#108197) (In reference to 5901d82) Consider when `Input[I]` is a `VarDecl` with parameter pack. We would have already expanded the pack before the code change in the loop`for (unsigned I = 0; I != *NumExpansions; ++I) {`. Now in `if (RetainExpansion) {`, without this change, we continue to substitute the pack in the pattern even when we do not have meaningful `ArgumentPackSubstitutionIndex` set. This leads to use of an invalid pack substitution index in `TemplateInstantiator::TransformFunctionParmPackRefExpr` in `TransformedDecl = (*Pack)[getSema().ArgumentPackSubstitutionIndex];` This change sets `ArgumentPackSubstitutionIndex` to `-1` while retaining expansion to instruct `TransformFunctionParmPackRefExpr` to build `FunctionParmPackExpr` instead of substituting the param pack. --- There are other instances of `RetainExpansion` and IIUC, they should also unset the `ArgumentPackSubstitutionIndex`. It would be great if someone can verify my understanding. If this is correct then we could instead have a `ArgumentPackSubstitutionIndexRAII` as part of `ForgetPartiallySubstitutedPackRAII`. EDIT: I have moved this to `ForgetPartiallySubstitutedPackRAII`. Fixes #63819 Fixes #107560
This is the creduced version: https://godbolt.org/z/v14xaYf9r
Code
Stack trace
The text was updated successfully, but these errors were encountered: