From 9af081003f9c19f33457e0ed1aa14a764f462c3c Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Sat, 6 Nov 2021 18:10:39 -0400 Subject: [PATCH] c++: Fix bogus error with __integer_pack [PR94490] Here we issue a bogus: error: '(0 ? fake_tuple_size_v : fake_tuple_size_v)' is not a constant expression because cxx_constant_value in expand_integer_pack gets *(0 ? VIEW_CONVERT_EXPR(fake_tuple_size_v) : VIEW_CONVERT_EXPR(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. --- gcc/cp/pt.c | 1 + gcc/testsuite/g++.dg/ext/integer-pack5.C | 29 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ext/integer-pack5.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f4b9d9673fbe..6b560952639f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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; diff --git a/gcc/testsuite/g++.dg/ext/integer-pack5.C b/gcc/testsuite/g++.dg/ext/integer-pack5.C new file mode 100644 index 000000000000..84938649d31d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/integer-pack5.C @@ -0,0 +1,29 @@ +// PR c++/94490 +// { dg-do compile { target c++14 } } + +template +constexpr int fake_tuple_size_v = 3; +template struct intseq {}; + +// So that it compiles with clang++. +#if __has_builtin(__make_integer_seq) +using size_t = decltype(sizeof(1)); +template +using _IdxTuple = intseq<_Indices...>; + +template using genseq = __make_integer_seq<_IdxTuple, size_t, N>; +#else +template using genseq = intseq<__integer_pack(N)...>; +#endif + +template> +struct arith_result +{ }; + +template +auto Mul(const T&) +{ + return [](auto) { return arith_result> { }; }(0); +} + +auto x = Mul(0); -- 2.47.2