Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings

2016-11-14 Thread Jason Merrill
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 Merrill  wrote:
> 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

2016-11-14 Thread Jason Merrill
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


Re: [WIP C++ PATCH] P0217R3 - C++17 structured bindings

2016-11-14 Thread Jakub Jelinek
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)?  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

2016-11-14 Thread Jakub Jelinek
On Mon, Nov 14, 2016 at 12:04:24AM -0500, Jason Merrill wrote:
> 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?

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

2016-11-14 Thread Richard Biener
On Mon, Nov 14, 2016 at 6:04 AM, Jason Merrill  wrote:
> 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

2016-11-13 Thread Jakub Jelinek
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 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.
> 
> 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

2016-11-13 Thread Jakub Jelinek
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.

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

2016-11-13 Thread Jason Merrill
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?
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

2016-11-13 Thread Jason Merrill
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.
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

2016-11-09 Thread Jakub Jelinek
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

2016-11-09 Thread Jakub Jelinek
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