mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-25 12:41:01 +08:00
c++: Fix constexpr if and braced functional cast.
While partially instantiating a generic lambda, we can encounter pack expansions or constexpr if where we can't actually do the substitution immediately, and instead remember a partial instantiation context in *_EXTRA_ARGS. This includes any local_specializations used in the pattern or condition. In this testcase our tree walk wasn't finding the use of i because we weren't walking into the type of a CONSTRUCTOR. Fixed by moving the code for doing that from find_parameter_packs_r into cp_walk_subtrees. 2020-02-11 Jason Merrill <jason@redhat.com> PR c++/92583 PR c++/92654 * tree.c (cp_walk_subtrees): Walk CONSTRUCTOR types here. * pt.c (find_parameter_packs_r): Not here.
This commit is contained in:
parent
68bb7e3b9d
commit
c2368db567
@ -1,3 +1,10 @@
|
||||
2020-02-12 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/92583
|
||||
PR c++/92654
|
||||
* tree.c (cp_walk_subtrees): Walk CONSTRUCTOR types here.
|
||||
* pt.c (find_parameter_packs_r): Not here.
|
||||
|
||||
2020-02-12 Iain Sandoe <iain@sandoe.co.uk>
|
||||
|
||||
* coroutines.cc (build_actor_fn): Implement deallocation function
|
||||
|
@ -3924,9 +3924,6 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
|
||||
case TEMPLATE_DECL:
|
||||
if (!DECL_TEMPLATE_TEMPLATE_PARM_P (t))
|
||||
return NULL_TREE;
|
||||
gcc_fallthrough();
|
||||
|
||||
case CONSTRUCTOR:
|
||||
cp_walk_tree (&TREE_TYPE (t),
|
||||
&find_parameter_packs_r, ppd, ppd->visited);
|
||||
return NULL_TREE;
|
||||
|
@ -5024,6 +5024,11 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
|
||||
*walk_subtrees_p = 0;
|
||||
break;
|
||||
|
||||
case CONSTRUCTOR:
|
||||
if (COMPOUND_LITERAL_P (*tp))
|
||||
WALK_SUBTREE (TREE_TYPE (*tp));
|
||||
break;
|
||||
|
||||
case TRAIT_EXPR:
|
||||
WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
|
||||
WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
|
||||
|
@ -2,5 +2,5 @@
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template<typename, int> struct A;
|
||||
template<typename T> struct A<T, T{}> {}; // { dg-error "partial specialization" }
|
||||
template<typename T> struct A<T, T{}> {}; // { dg-error "partial specialization|involves template parameter" }
|
||||
A<int, 0> a;
|
||||
|
24
gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C
Normal file
24
gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C
Normal file
@ -0,0 +1,24 @@
|
||||
// PR c++/92583
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
template <int> struct a {
|
||||
constexpr operator int() { return 42; }
|
||||
};
|
||||
template <typename> using b = int;
|
||||
template <typename d, d> struct e {};
|
||||
template <typename d, d g> using h = e<d, __integer_pack(g)...>;
|
||||
template <typename j, typename k, k... index> void apply(j f, e<k, index...>) {
|
||||
(f(a<index>{}), ...);
|
||||
}
|
||||
template <auto l, typename j> void m(j f) {
|
||||
using k = b<decltype(l)>;
|
||||
using n = h<k, l>;
|
||||
apply(f, n{});
|
||||
}
|
||||
template <int, int c> void o() {
|
||||
auto p = [](auto i) {
|
||||
if constexpr (a<i>{}) ;
|
||||
};
|
||||
m<c>(p);
|
||||
}
|
||||
auto q() { o<0, 1>; }
|
Loading…
x
Reference in New Issue
Block a user