From: Jakub Jelinek Date: Tue, 11 Apr 2017 20:51:16 +0000 (+0200) Subject: re PR c++/80370 (ICE when using structured bindings and nested generic lambdas (tsubs... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=347e1f77696d8d69db2c9e66bba6e48662de8343;p=gcc.git re PR c++/80370 (ICE when using structured bindings and nested generic lambdas (tsubst_decomp_names)) 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) : For variables with DECL_VALUE_EXPR, return true if DECL_VALUE_EXPR is type dependent. * g++.dg/cpp1z/decomp28.C: New test. From-SVN: r246857 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e16efdccb8e..c06b505b27b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2017-04-11 Jakub Jelinek + + 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) : For variables + with DECL_VALUE_EXPR, return true if DECL_VALUE_EXPR is type + dependent. + 2017-04-11 Jakub Jelinek PR c++/80363 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 516b93c3da9..438a4ec1c51 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7473,6 +7473,8 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) { 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, unsigned int count) { 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, unsigned int count) { 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, unsigned int count) 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, unsigned int count) 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)); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5a55f179096..862c2c2c08c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -23576,6 +23576,12 @@ value_dependent_expression_p (tree expression) || 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: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d8597e2b597..354adb04314 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-04-11 Jakub Jelinek + PR c++/80370 + * g++.dg/cpp1z/decomp28.C: New test. + PR middle-end/80100 * gcc.dg/pr80100.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp28.C b/gcc/testsuite/g++.dg/cpp1z/decomp28.C new file mode 100644 index 00000000000..7561d9dfc02 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/decomp28.C @@ -0,0 +1,39 @@ +// PR c++/80370 +// { dg-do compile { target c++14 } } +// { dg-options "" } + +namespace std { + template struct tuple_size; + template struct tuple_element; + template struct tuple {}; + template struct tuple_size> { static constexpr int value = 1; }; + template struct tuple_element<0, tuple> { typedef T type; }; + template int& get (tuple); +} + +template +void +foo (std::tuple b) +{ + auto [c] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +} + +template +void +bar (std::tuple b) +{ + auto [c] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +} + +void +baz (std::tuple b) +{ + foo <5> (b); + bar (b); +} + +int +main () +{ + [](auto) { [](std::tuple b) { auto[c] = b; }; } (0); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +}