c++: Fix bogus error with __integer_pack [PR94490]
Here we issue a bogus: error: '(0 ? fake_tuple_size_v<int> : fake_tuple_size_v<int>)' is not a constant expression because cxx_constant_value in expand_integer_pack gets *(0 ? VIEW_CONVERT_EXPR<const int>(fake_tuple_size_v) : VIEW_CONVERT_EXPR<const int>(fake_tuple_size_v)) which is a REFERENCE_REF_P and we evaluate its operand to 3, so we end up with *3 and that fails. Sounds like we need to get rid of the REFERENCE_REF_P then. That is what tsubst_copy_and_build/INDIRECT_REF will do: if (REFERENCE_REF_P (t)) { /* A type conversion to reference type will be enclosed in such an indirect ref, but the substitution of the cast will have also added such an indirect ref. */ r = convert_from_reference (r); } so I think it's reasonable to call instantiate_non_dependent_expr_sfinae. PR c++/94490 gcc/cp/ChangeLog: * pt.c (expand_integer_pack): Call instantiate_non_dependent_expr_sfinae. gcc/testsuite/ChangeLog: * g++.dg/ext/integer-pack5.C: New test.
This commit is contained in:
parent
cde87638bf
commit
9af081003f
@ -3792,6 +3792,7 @@ expand_integer_pack (tree call, tree args, tsubst_flags_t complain,
|
||||
}
|
||||
else
|
||||
{
|
||||
hi = instantiate_non_dependent_expr_sfinae (hi, complain);
|
||||
hi = cxx_constant_value (hi);
|
||||
int len = valid_constant_size_p (hi) ? tree_to_shwi (hi) : -1;
|
||||
|
||||
|
29
gcc/testsuite/g++.dg/ext/integer-pack5.C
Normal file
29
gcc/testsuite/g++.dg/ext/integer-pack5.C
Normal file
@ -0,0 +1,29 @@
|
||||
// PR c++/94490
|
||||
// { dg-do compile { target c++14 } }
|
||||
|
||||
template<class T>
|
||||
constexpr int fake_tuple_size_v = 3;
|
||||
template<int...> struct intseq {};
|
||||
|
||||
// So that it compiles with clang++.
|
||||
#if __has_builtin(__make_integer_seq)
|
||||
using size_t = decltype(sizeof(1));
|
||||
template<typename, size_t... _Indices>
|
||||
using _IdxTuple = intseq<_Indices...>;
|
||||
|
||||
template<int N> using genseq = __make_integer_seq<_IdxTuple, size_t, N>;
|
||||
#else
|
||||
template<int N> using genseq = intseq<__integer_pack(N)...>;
|
||||
#endif
|
||||
|
||||
template<int A, class S = genseq<0 ? A : A>>
|
||||
struct arith_result
|
||||
{ };
|
||||
|
||||
template<typename T>
|
||||
auto Mul(const T&)
|
||||
{
|
||||
return [](auto) { return arith_result<fake_tuple_size_v<T>> { }; }(0);
|
||||
}
|
||||
|
||||
auto x = Mul(0);
|
Loading…
Reference in New Issue
Block a user