From e99d77c97fbee5c17594374b978a0c4f9cd125f4 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 5 Apr 2018 10:20:53 -0400 Subject: [PATCH] PR c++/85200 - ICE with constexpr if in generic lambda. * pt.c (extract_locals_r): Don't record the local specs of variables declared within the pattern. From-SVN: r259127 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 13 +++++++++++-- gcc/testsuite/g++.dg/cpp1z/constexpr-if19.C | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-if19.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4ae78f73b2b..99ec3ea171e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-04-05 Jason Merrill + + PR c++/85200 - ICE with constexpr if in generic lambda. + * pt.c (extract_locals_r): Don't record the local specs of variables + declared within the pattern. + 2018-04-05 Alexandre Oliva PR c++/84979 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 741c578b65b..ed6e62c2364 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11597,8 +11597,12 @@ tsubst_binary_right_fold (tree t, tree args, tsubst_flags_t complain, struct el_data { + hash_set internal; tree extra; tsubst_flags_t complain; + + el_data (tsubst_flags_t c) + : extra (NULL_TREE), complain (c) {} }; static tree extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_) @@ -11606,8 +11610,13 @@ extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_) el_data &data = *reinterpret_cast(data_); tree *extra = &data.extra; tsubst_flags_t complain = data.complain; - if (tree spec = retrieve_local_specialization (*tp)) + if (TREE_CODE (*tp) == DECL_EXPR) + data.internal.add (DECL_EXPR_DECL (*tp)); + else if (tree spec = retrieve_local_specialization (*tp)) { + if (data.internal.contains (*tp)) + /* Don't mess with variables declared within the pattern. */ + return NULL_TREE; if (TREE_CODE (spec) == NONTYPE_ARGUMENT_PACK) { /* Maybe pull out the PARM_DECL for a partial instantiation. */ @@ -11658,7 +11667,7 @@ extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_) static tree extract_local_specs (tree pattern, tsubst_flags_t complain) { - el_data data = { NULL_TREE, complain }; + el_data data (complain); cp_walk_tree_without_duplicates (&pattern, extract_locals_r, &data); return data.extra; } diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if19.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if19.C new file mode 100644 index 00000000000..40016a5b7e1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if19.C @@ -0,0 +1,17 @@ +// PR c++/85200 +// { dg-additional-options -std=c++17 } + +struct A{ + constexpr operator int(){ return 0; } +}; + +template < typename > +void f(){ + [](auto known){ + if constexpr(constexpr int k = known); + }(A{}); +} + +int main(){ + f(); +} -- 2.30.2