OK.
On Tue, Apr 11, 2017 at 1:13 PM, Jakub Jelinek <ja...@redhat.com> wrote: > On Tue, Apr 11, 2017 at 03:41:39PM +0200, Jakub Jelinek wrote: >> So like this? Or just type_dependent_expression_p check rather than >> both? > > To answer myself, testing there both type_dependent_expression_p > and value_dependent_expression_p for value_expr breaks > the lambda-generic-const2.C testcase. So I'll test this instead: > > 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 > 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-11 19:06:52.871624849 +0200 > +++ gcc/cp/pt.c 2017-04-11 19:10:39.795803274 +0200 > @@ -23576,6 +23576,12 @@ 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)) > + 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