Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
Some fixes for bit-field and decltype handling, and address comparison in constant expressions. Tested x86_64-pc-linux-gnu, applied to trunk. On Mon, Nov 14, 2016 at 10:16 AM, Jason Merrillwrote: > On Mon, Nov 14, 2016 at 9:51 AM, Jakub Jelinek wrote: >> On Sun, Nov 13, 2016 at 11:53:10PM -0500, Jason Merrill wrote: >>> On Wed, Nov 9, 2016 at 8:05 AM, Jakub Jelinek wrote: >>> > On Wed, Nov 09, 2016 at 01:24:22PM +0100, Jakub Jelinek wrote: >>> >> The following patch is a WIP on P0217R3 - decomposition declarations. >>> >> It contains various FIXMEs, Jason, do you think you could finish it up? >>> >>> Here's what I'm checking in, as a delta from from your patch. More >>> testcases would still be welcome. >> >> Do we want to check this in (tested on x86_64-linux)? > > Yes, thanks, I keep forgetting the macros. > >> Or are some further >> changes needed before that (e.g. has inline, constexpr, extern, static >> etc. been allowed for decompositions in Issaquah or not)? > > These haven't been considered yet. > >> Are you going to update https://gcc.gnu.org/projects/cxx-status.html ? >> Seems during the C++ meeting clang added: >> >> Matching template template parameters to compatible arguments P0522R0 >> Removing deprecated dynamic exception specificationsP0003R5 >> Pack expansions in using-declarations P0195R2 >> >> rows to their table too, are you going to add those as well (to the table >> and/or GCC 7)? > > I will. > > Jason commit 01702a64c7d8524d662dd4b5d07accdeddafb7f6 Author: Jason Merrill Date: Tue Nov 15 00:08:19 2016 -0500 Various C++17 decomposition fixes. * tree.c (bitfield_p): New. * cp-tree.h: Declare it. * typeck.c (cxx_sizeof_expr, cxx_alignof_expr) (cp_build_addr_expr_1): Use it instead of DECL_C_BIT_FIELD. * decl.c (cp_finish_decomp): Look through reference. Always SET_DECL_DECOMPOSITION_P. * semantics.c (finish_decltype_type): Adjust decomposition handling. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8c2dbe1..edcd3b4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6572,6 +6572,7 @@ extern cp_lvalue_kind lvalue_kind (const_tree); extern bool glvalue_p (const_tree); extern bool obvalue_p (const_tree); extern bool xvalue_p (const_tree); +extern bool bitfield_p (const_tree); extern tree cp_stabilize_reference (tree); extern bool builtin_valid_in_constant_expr_p(const_tree); extern tree build_min (enum tree_code, tree, ...); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f142c1f..2af95a7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7350,18 +7350,23 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d)) { v[count - i - 1] = d; - if (processing_template_decl) - { - retrofit_lang_decl (d); - SET_DECL_DECOMPOSITION_P (d); - } + retrofit_lang_decl (d); + SET_DECL_DECOMPOSITION_P (d); } tree type = TREE_TYPE (decl); - tree eltype = NULL_TREE; + tree dexp = decl; + if (TREE_CODE (type) == REFERENCE_TYPE) -type = TREE_TYPE (type); +{ + /* If e is a constant reference, use the referent directly. */ + if (DECL_INITIAL (decl)) + dexp = DECL_INITIAL (decl); + dexp = convert_from_reference (dexp); + type = TREE_TYPE (type); +} + tree eltype = NULL_TREE; unsigned HOST_WIDE_INT eltscnt = 0; if (TREE_CODE (type) == ARRAY_TYPE) { @@ -7391,7 +7396,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); - tree t = convert_from_reference (decl); + tree t = dexp; t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE); @@ -7410,7 +7415,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); - tree t = convert_from_reference (decl); + tree t = dexp; t = build1_loc (DECL_SOURCE_LOCATION (v[i]), i ? IMAGPART_EXPR : REALPART_EXPR, eltype, t); @@ -7428,7 +7433,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); - tree t = convert_from_reference (decl); + tree t = dexp; convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]), , size_int (i)); t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, @@
Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
On Mon, Nov 14, 2016 at 9:51 AM, Jakub Jelinekwrote: > On Sun, Nov 13, 2016 at 11:53:10PM -0500, Jason Merrill wrote: >> On Wed, Nov 9, 2016 at 8:05 AM, Jakub Jelinek wrote: >> > On Wed, Nov 09, 2016 at 01:24:22PM +0100, Jakub Jelinek wrote: >> >> The following patch is a WIP on P0217R3 - decomposition declarations. >> >> It contains various FIXMEs, Jason, do you think you could finish it up? >> >> Here's what I'm checking in, as a delta from from your patch. More >> testcases would still be welcome. > > Do we want to check this in (tested on x86_64-linux)? Yes, thanks, I keep forgetting the macros. > Or are some further > changes needed before that (e.g. has inline, constexpr, extern, static > etc. been allowed for decompositions in Issaquah or not)? These haven't been considered yet. > Are you going to update https://gcc.gnu.org/projects/cxx-status.html ? > Seems during the C++ meeting clang added: > > Matching template template parameters to compatible arguments P0522R0 > Removing deprecated dynamic exception specificationsP0003R5 > Pack expansions in using-declarations P0195R2 > > rows to their table too, are you going to add those as well (to the table > and/or GCC 7)? I will. Jason
Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
On Sun, Nov 13, 2016 at 11:53:10PM -0500, Jason Merrill wrote: > On Wed, Nov 9, 2016 at 8:05 AM, Jakub Jelinekwrote: > > On Wed, Nov 09, 2016 at 01:24:22PM +0100, Jakub Jelinek wrote: > >> The following patch is a WIP on P0217R3 - decomposition declarations. > >> It contains various FIXMEs, Jason, do you think you could finish it up? > > Here's what I'm checking in, as a delta from from your patch. More > testcases would still be welcome. Do we want to check this in (tested on x86_64-linux)? Or are some further changes needed before that (e.g. has inline, constexpr, extern, static etc. been allowed for decompositions in Issaquah or not)? Are you going to update https://gcc.gnu.org/projects/cxx-status.html ? Seems during the C++ meeting clang added: Matching template template parameters to compatible arguments P0522R0 Removing deprecated dynamic exception specificationsP0003R5 Pack expansions in using-declarations P0195R2 rows to their table too, are you going to add those as well (to the table and/or GCC 7)? 2016-11-14 Jakub Jelinek * c-cppbuiltin.c (c_cpp_builtins): Define __cpp_structured_bindings. * g++.dg/cpp1z/feat-cxx1z.C: Test __cpp_structured_bindings macro. --- gcc/c-family/c-cppbuiltin.c.jj 2016-11-09 23:55:12.0 +0100 +++ gcc/c-family/c-cppbuiltin.c 2016-11-14 15:21:56.814759245 +0100 @@ -943,6 +943,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_deduction_guides=201606"); cpp_define (pfile, "__cpp_noexcept_function_type=201510"); cpp_define (pfile, "__cpp_template_auto=201606"); + cpp_define (pfile, "__cpp_structured_bindings=201606"); } if (flag_concepts) cpp_define (pfile, "__cpp_concepts=201507"); --- gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C.jj 2016-11-09 23:55:14.0 +0100 +++ gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C 2016-11-14 15:26:13.459539622 +0100 @@ -392,6 +392,12 @@ # error "__cpp_noexcept_function_type != 201510" #endif +#ifndef __cpp_structured_bindings +# error "__cpp_structured_bindings" +#elif __cpp_structured_bindings != 201606 +# error "__cpp_structured_bindings != 201606" +#endif + #ifdef __has_cpp_attribute # if ! __has_cpp_attribute(maybe_unused) Jakub
Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
On Mon, Nov 14, 2016 at 12:04:24AM -0500, Jason Merrill wrote: > On Wed, Nov 9, 2016 at 7:24 AM, Jakub Jelinekwrote: > > The match.pd hunk is needed, otherwise the generic folding happily folds > > int arr[2]; > > ... > > auto [ x, y ] = arr; > > == [0] > > into 0, because it thinks x and arr are distinct VAR_DECLs. Though, if > > such comparisons are required to be folded in constexpr contexts under > > certain conditions, we'd need to handle the DECL_VALUE_EXPRs in constexpr.c > > somehow. > > What do you think of this approach instead? As Richard said, we'd need to change the 3 other functions too. And there is additional complication, for OpenMP we defer gimplification of vars with DECL_VALUE_EXPRs on them, because they often get a different DECL_VALUE_EXPR. So if optimizers look through DECL_VALUE_EXPR rather than punt on vars with DECL_VALUE_EXPR, we risk the undesirable value expressions might leak into the IL. So I think we want just punt on vars with DECL_VALUE_EXPR (perhaps even in those 4 functions), except for constexpr.c where we perhaps special case the decomposition vars or something similar. Jakub
Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
On Mon, Nov 14, 2016 at 6:04 AM, Jason Merrillwrote: > On Wed, Nov 9, 2016 at 7:24 AM, Jakub Jelinek wrote: >> The match.pd hunk is needed, otherwise the generic folding happily folds >> int arr[2]; >> ... >> auto [ x, y ] = arr; >> == [0] >> into 0, because it thinks x and arr are distinct VAR_DECLs. Though, if >> such comparisons are required to be folded in constexpr contexts under >> certain conditions, we'd need to handle the DECL_VALUE_EXPRs in constexpr.c >> somehow. > > What do you think of this approach instead? get_addr_base_and_unit_offset_1 is infrastructure related to get_ref_base_and_extent, get_inner_reference and get_base_address. All of those should really behave the same with respect to the innermost decl. Thus I don't think we should handle this here. Richard.
Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
On Mon, Nov 14, 2016 at 08:11:25AM +0100, Jakub Jelinek wrote: > On Sun, Nov 13, 2016 at 11:53:10PM -0500, Jason Merrill wrote: > > On Wed, Nov 9, 2016 at 8:05 AM, Jakub Jelinekwrote: > > > On Wed, Nov 09, 2016 at 01:24:22PM +0100, Jakub Jelinek wrote: > > >> The following patch is a WIP on P0217R3 - decomposition declarations. > > >> It contains various FIXMEs, Jason, do you think you could finish it up? > > > > Here's what I'm checking in, as a delta from from your patch. More > > testcases would still be welcome. > > Thanks, I'll try to add some more testsuite coverage in stage3. > But, it seems you haven't checked the testcases (except for the modification > of existing one). I've checked them in now after retesting them. Jakub
Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
On Sun, Nov 13, 2016 at 11:53:10PM -0500, Jason Merrill wrote: > On Wed, Nov 9, 2016 at 8:05 AM, Jakub Jelinekwrote: > > On Wed, Nov 09, 2016 at 01:24:22PM +0100, Jakub Jelinek wrote: > >> The following patch is a WIP on P0217R3 - decomposition declarations. > >> It contains various FIXMEs, Jason, do you think you could finish it up? > > Here's what I'm checking in, as a delta from from your patch. More > testcases would still be welcome. Thanks, I'll try to add some more testsuite coverage in stage3. But, it seems you haven't checked the testcases (except for the modification of existing one). Jakub
Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
On Wed, Nov 9, 2016 at 7:24 AM, Jakub Jelinekwrote: > The match.pd hunk is needed, otherwise the generic folding happily folds > int arr[2]; > ... > auto [ x, y ] = arr; > == [0] > into 0, because it thinks x and arr are distinct VAR_DECLs. Though, if > such comparisons are required to be folded in constexpr contexts under > certain conditions, we'd need to handle the DECL_VALUE_EXPRs in constexpr.c > somehow. What do you think of this approach instead? commit 7aa4bc14bdd8f01937ce2dc148722f0468d66d1b Author: Jason Merrill Date: Sun Nov 13 19:17:40 2016 -0500 addr_base diff --git a/gcc/match.pd b/gcc/match.pd index 79a418f..29ddcd8 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2547,15 +2547,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (with { int equal = 2; - /* Punt in GENERIC on variables with value expressions; - the value expressions might point to fields/elements - of other vars etc. */ - if (GENERIC - && ((VAR_P (base0) && DECL_HAS_VALUE_EXPR_P (base0)) - || (VAR_P (base1) && DECL_HAS_VALUE_EXPR_P (base1 -; - else if (decl_in_symtab_p (base0) - && decl_in_symtab_p (base1)) + if (decl_in_symtab_p (base0) + && decl_in_symtab_p (base1)) equal = symtab_node::get_create (base0) ->equal_address_to (symtab_node::get_create (base1)); else if ((DECL_P (base0) diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 0396feb..0a8523b 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -673,6 +673,15 @@ get_addr_base_and_unit_offset_1 (tree exp, HOST_WIDE_INT *poffset, { switch (TREE_CODE (exp)) { + case VAR_DECL: + if (DECL_HAS_VALUE_EXPR_P (exp)) + { + exp = DECL_VALUE_EXPR (exp); + continue; + } + else + goto done; + case BIT_FIELD_REF: { HOST_WIDE_INT this_off = TREE_INT_CST_LOW (TREE_OPERAND (exp, 2));
Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
On Wed, Nov 9, 2016 at 8:05 AM, Jakub Jelinekwrote: > On Wed, Nov 09, 2016 at 01:24:22PM +0100, Jakub Jelinek wrote: >> The following patch is a WIP on P0217R3 - decomposition declarations. >> It contains various FIXMEs, Jason, do you think you could finish it up? Here's what I'm checking in, as a delta from from your patch. More testcases would still be welcome. commit cb763ca9dafb0aa6847bcfcc8ee776dcd78e1abb Author: Jason Merrill Date: Sat Nov 12 00:15:35 2016 -0800 Implement P0217R3 - C++17 structured bindings gcc/cp/ * cp-tree.h (struct lang_decl_base): Add decomposition_p. (DECL_DECOMPOSITION_P): New (enum auto_deduction_context): Add adc_decomp_type. (enum cp_declarator_kind): Add cdk_decomp. * constexpr.c (cxx_eval_constant_expression): Look through DECL_VALUE_EXPR. (potential_constant_expression_1): Likewise. * decl.c (reshape_init): Preserve CONSTRUCTOR_IS_DIRECT_INIT. (check_initializer): Use build_aggr_init for DECL_DECOMPOSITION_P. (cp_finish_decl): Pass adc_decomp_type for decomposition. (find_decomp_class_base, get_tuple_size, get_tuple_element_type) (get_tuple_decomp_init, cp_finish_decomp): New. (grokdeclarator): Handle decomposition. * init.c (build_aggr_init): Handle decomposition array. (build_vec_init): Handle initialization from { array }. * name-lookup.c (add_function): Always wrap TEMPLATE_DECL in OVERLOAD. * parser.c (declarator_can_be_parameter_pack): Handle cdk_decomp. (function_declarator_p, strip_declarator_types) (cp_parser_check_declarator_template_parameters): Likewise. (cp_parser_range_for, cp_convert_range_for): Handle decomposition. (cp_parser_simple_declaration): Parse decomposition. (cp_parser_decomposition_declaration): New. * pt.c (tsubst_decomp_names): New. (subst_expr) [DECL_EXPR, RANGE_FOR_STMT]: Handle decomposition. (do_auto_deduction): Handle adc_decomp_type. * semantics.c (finish_decltype_type): Look through DECL_VALUE_EXPR. * typeck.c (is_bitfield_expr_with_lowered_type): Likewise. * tree.c (lvalue_kind): Likewise. (cp_build_reference_type): Handle reference collapsing. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 739e902..e8c7702 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3770,7 +3770,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, return (*ctx->values->get (t)); case VAR_DECL: - if (is_capture_proxy (t)) + if (DECL_HAS_VALUE_EXPR_P (t)) return cxx_eval_constant_expression (ctx, DECL_VALUE_EXPR (t), lval, non_constant_p, overflow_p); /* fall through */ @@ -5037,6 +5037,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, return RECUR (TREE_OPERAND (t, 0), rval); case VAR_DECL: + if (DECL_HAS_VALUE_EXPR_P (t)) + return RECUR (DECL_VALUE_EXPR (t), rval); if (want_rval && !var_in_maybe_constexpr_fn (t) && !type_dependent_expression_p (t) diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index f44bd32..9b9b511 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -617,14 +617,6 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE); gcc_assert (EXPR_HAS_LOCATION (*expr_p)); input_location = EXPR_LOCATION (*expr_p); - if (VAR_P (VEC_INIT_EXPR_SLOT (*expr_p)) - && DECL_DECOMPOSITION_P (VEC_INIT_EXPR_SLOT (*expr_p)) - && init - && DIRECT_LIST_INIT_P (init) - && CONSTRUCTOR_NELTS (init) == 1 - && (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (init, 0)->value)) - == ARRAY_TYPE)) - from_array = 1; *expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE, init, VEC_INIT_EXPR_VALUE_INIT (*expr_p), from_array, diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e684996..f142c1f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6074,6 +6074,10 @@ reshape_init (tree type, tree init, tsubst_flags_t complain) return error_mark_node; } + if (CONSTRUCTOR_IS_DIRECT_INIT (init) + && BRACE_ENCLOSED_INITIALIZER_P (new_init)) +CONSTRUCTOR_IS_DIRECT_INIT (new_init) = true; + return new_init; } @@ -6194,15 +6198,6 @@ check_initializer (tree decl, tree init, int flags, vec **cleanups) gcc_assert (init != NULL_TREE); init = NULL_TREE; } - else if (VAR_P (decl) - && DECL_DECOMPOSITION_P (decl) - &&
Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings
Hi! On Wed, Nov 09, 2016 at 01:24:22PM +0100, Jakub Jelinek wrote: > The following patch is a WIP on P0217R3 - decomposition declarations. > It contains various FIXMEs, Jason, do you think you could finish it up? Some more comments: Invalid? code like int arr[2]; extern int x, y; auto [ x, y ] = arr; depends on PR78217 fix, so I haven't added testsuite coverage for that yet. Nor for decomp at namespace scope. There is no coverage for bitfields either. And the testsuite coverage surely needs to have some verification of the exact types and cv quals of the individual decls, the tests only cover their addresses. As implemented in the patch, those decls with DECL_VALUE_EXPRs have non-reference type always, not sure if it is ok or not. Jakub
[WIP C++ PATCH] P0217R3 - C++17 structured bindings
Hi! The following patch is a WIP on P0217R3 - decomposition declarations. It contains various FIXMEs, Jason, do you think you could finish it up? The most important unfinished part in the patch is that cp_finish_decomp for classes doesn't try to check if std::tuple_size::value is well-formed integral constant expression and use decl.get() or get(decl) as initializers and std::tuple_element::type as type of the individual vars (that need cp_finish_decl then and dropping of DEC_HAS_VALUE_EXPR_P/DECL_VALUE_EXPR if they have any) - template-ids, lookups, instantiations isn't something I'm comfortable enough with to write that. Another thing is with the non-reference decompositions - I think int arr[2]; ... auto [ x, y ] = arr; works properly as copy-initialization, avoids explicit copy constructors, as I've tried to test in the decomp6.C, though the templates used during the VEC_INIT_EXPR gimplification aren't actually instantiated (see the fixme routine in the test that really shouldn't be necessary). But auto [ x, y ] { arr }; doesn't seem to work correctly, see the commented out part of decomp6.C, the cp-gimplify.c hunk is kind of hackish, but it seems to try to use A::A conversion ctor while I believe it should use the A::A(const A &) copy ctor. Another thing is in find_decomp_class_base - I think the current code will just reject if the same base class with any non-static data members appears as virtual base in more than one place in the bases tree, not really sure what should be done, how to check if the paths to that base are accessible etc. Another thing is in find_decomp_class_base caller, while that function can return some base class if the only non-static data members are in such a base and not in the derived class(es), the caller isn't prepared to expand that, not sure if we need build_base_path or what to actually generate the COMPONENT_REFs for the artificial FIELD_DECLs or what. Not sure about how the qualifiers from class fields and from the cv-qualifiers on the decomposition declaration should be treated, at the moment I'm oring them in. The match.pd hunk is needed, otherwise the generic folding happily folds int arr[2]; ... auto [ x, y ] = arr; == [0] into 0, because it thinks x and arr are distinct VAR_DECLs. Though, if such comparisons are required to be folded in constexpr contexts under certain conditions, we'd need to handle the DECL_VALUE_EXPRs in constexpr.c somehow. Mangling of the decomposition declaration base decls at namespace scope isn't implemented; I think the DECL_ASSEMBLER_NAME for them (they have NULL DECL_NAME) could be done in cp_finish_decomp, where we have all the corresponding identifiers available, but it would probably need to be done through direct calls to the demangler, as the base decl isn't all that is needed for that. Per IRC discussions, the associated VAR_DECLs are chained through DECL_CHAIN. It isn't that easy though, because decls are pushed into the bindings in reverse order and afterwards nreversed. Plus at least for the (not yet implemented) std::tuple_size::value stuff where the VAR_DECLs shouldn't have DECL_VALUE_EXPR, the desired final order is that the nameless artificial base decl comes first and then the other decls in the order they appear. But that means that at cp_finish_decl time of the base decl they are actually in the order y, x, D.1234 for tha above auto [ x, y ] = arr; - so the finalizing of those is done by separate cp_finish_decomp that needs to know the start of the chain (the last named variable of the decomposition) plus the base artificial decl and count. For range for it uses the DECL_VALUE_EXPRs to find those, maybe it would be better to pass around during parsing not just address of a tree (the range decl), but address of a triplet (range decl, first decomp decl in the chain (i.e. last one) and count, so that range for parsing doesn't have to rediscover those. The base decl has the DECL_DECOMPOSITION_P flag on it set and NULL_TREE DECL_NAME, the instantiation code in the patch doesn't parse DECL_VALUE_EXPRs though, because if the decomp initializer is not type dependent, those DECL_VALUE_EXPRs aren't actually in a standardized form that could be easily parseable, so it just assumes those named decls have also DECL_DECOMPOSITION_P flag on and non-NULL DECL_NAME and follow the base decl in DECL_CHAIN (the new ones created with tsubst_expr in reverse order again). If nothing attempts to fold stuff in templates, perhaps we could avoid setting DECL_VALUE_EXPRs at all when processing_template_decl? --- gcc/match.pd.jj 2016-11-07 18:32:56.0 +0100 +++ gcc/match.pd2016-11-08 14:00:05.391773322 +0100 @@ -2547,8 +2547,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (with { int equal = 2; - if (decl_in_symtab_p (base0) - && decl_in_symtab_p (base1)) + /* Punt in GENERIC on variables with value expressions; + the value expressions might point to