Hi! On Mon, Apr 10, 2017 at 04:48:43PM -0400, Jason Merrill wrote: > On Mon, Apr 10, 2017 at 4:35 PM, Jakub Jelinek <ja...@redhat.com> wrote: > > - store_decomp_type (v[i], eltype); > > + if (!processing_template_decl) > > + store_decomp_type (v[i], eltype); > > This spot shouldn't change; we do want to remember the decltype even > in a template. > > > @@ -3935,7 +3935,10 @@ cxx_eval_constant_expression (const cons > > return (*ctx->values->get (t)); > > > > case VAR_DECL: > > - if (DECL_HAS_VALUE_EXPR_P (t)) > > + if (DECL_HAS_VALUE_EXPR_P (t) > > + /* Don't recurse on DECL_VALUE_EXPR of decomposition decls > > + that have not been finalized yet. */ > > + && (!DECL_DECOMPOSITION_P (t) || TREE_TYPE (DECL_VALUE_EXPR (t)))) > > Hmm, we shouldn't get here in this case. I think > value_dependent_expression_p should return true for a VAR_DECL with > type-dependent DECL_VALUE_EXPR.
So like this? Or just type_dependent_expression_p check rather than both? 2017-04-11 Jakub Jelinek <ja...@redhat.com> PR c++/80370 * decl.c (cp_finish_decomp): If processing_template_decl on non-dependent decl, only set TREE_TYPE on the v[i] decls, but don't change their DECL_VALUE_EXPR nor cp_finish_decl them. Instead make sure DECL_VALUE_EXPR is the canonical NULL type ARRAY_REF for tsubst processing. * pt.c (value_dependent_expression_p) <case VAR_DECL>: For variables with DECL_VALUE_EXPR, return true if DECL_VALUE_EXPR is type or value dependent. * g++.dg/cpp1z/decomp28.C: New test. --- gcc/cp/decl.c.jj 2017-04-10 22:26:56.441388051 +0200 +++ gcc/cp/decl.c 2017-04-11 15:21:24.473163169 +0200 @@ -7473,6 +7473,8 @@ cp_finish_decomp (tree decl, tree first, { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); + if (processing_template_decl) + continue; tree t = unshare_expr (dexp); t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, eltype, t, size_int (i), NULL_TREE, @@ -7492,6 +7494,8 @@ cp_finish_decomp (tree decl, tree first, { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); + if (processing_template_decl) + continue; tree t = unshare_expr (dexp); t = build1_loc (DECL_SOURCE_LOCATION (v[i]), i ? IMAGPART_EXPR : REALPART_EXPR, eltype, @@ -7510,6 +7514,8 @@ cp_finish_decomp (tree decl, tree first, { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); + if (processing_template_decl) + continue; tree t = unshare_expr (dexp); convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]), &t, size_int (i)); @@ -7559,8 +7565,9 @@ cp_finish_decomp (tree decl, tree first, SET_DECL_VALUE_EXPR (v[i], NULL_TREE); DECL_HAS_VALUE_EXPR_P (v[i]) = 0; } - cp_finish_decl (v[i], init, /*constexpr*/false, - /*asm*/NULL_TREE, LOOKUP_NORMAL); + if (!processing_template_decl) + cp_finish_decl (v[i], init, /*constexpr*/false, + /*asm*/NULL_TREE, LOOKUP_NORMAL); } } else if (TREE_CODE (type) == UNION_TYPE) @@ -7615,12 +7622,26 @@ cp_finish_decomp (tree decl, tree first, tt = TREE_OPERAND (tt, 0); TREE_TYPE (v[i]) = TREE_TYPE (tt); layout_decl (v[i], 0); - SET_DECL_VALUE_EXPR (v[i], tt); - DECL_HAS_VALUE_EXPR_P (v[i]) = 1; + if (!processing_template_decl) + { + SET_DECL_VALUE_EXPR (v[i], tt); + DECL_HAS_VALUE_EXPR_P (v[i]) = 1; + } i++; } } - if (DECL_NAMESPACE_SCOPE_P (decl)) + if (processing_template_decl) + { + for (unsigned int i = 0; i < count; i++) + if (!DECL_HAS_VALUE_EXPR_P (v[i])) + { + tree a = build_nt (ARRAY_REF, decl, size_int (i), + NULL_TREE, NULL_TREE); + SET_DECL_VALUE_EXPR (v[i], a); + DECL_HAS_VALUE_EXPR_P (v[i]) = 1; + } + } + else if (DECL_NAMESPACE_SCOPE_P (decl)) SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v)); } --- gcc/cp/pt.c.jj 2017-04-10 08:18:51.000000000 +0200 +++ gcc/cp/pt.c 2017-04-11 15:37:59.727673709 +0200 @@ -23576,6 +23576,13 @@ value_dependent_expression_p (tree expre || type_dependent_expression_p (DECL_INITIAL (expression)) || value_dependent_expression_p (DECL_INITIAL (expression)))) return true; + if (DECL_HAS_VALUE_EXPR_P (expression)) + { + tree value_expr = DECL_VALUE_EXPR (expression); + if (type_dependent_expression_p (value_expr) + || value_dependent_expression_p (value_expr)) + return true; + } return false; case DYNAMIC_CAST_EXPR: --- gcc/testsuite/g++.dg/cpp1z/decomp28.C.jj 2017-04-11 15:21:24.473163169 +0200 +++ gcc/testsuite/g++.dg/cpp1z/decomp28.C 2017-04-11 15:21:24.473163169 +0200 @@ -0,0 +1,39 @@ +// PR c++/80370 +// { dg-do compile { target c++14 } } +// { dg-options "" } + +namespace std { + template <typename> struct tuple_size; + template <long, typename> struct tuple_element; + template <typename...> struct tuple {}; + template <typename... T> struct tuple_size<tuple<T...>> { static constexpr int value = 1; }; + template <typename T, typename... U> struct tuple_element<0, tuple<T, U...>> { typedef T type; }; + template <int, typename... T> int& get (tuple<T...>); +} + +template <int N> +void +foo (std::tuple<int> b) +{ + auto [c] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +} + +template <typename T> +void +bar (std::tuple<T> b) +{ + auto [c] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +} + +void +baz (std::tuple<int> b) +{ + foo <5> (b); + bar (b); +} + +int +main () +{ + [](auto) { [](std::tuple<int> b) { auto[c] = b; }; } (0); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +} Jakub