[C++ PATCH] P0490R0 GB 20: decomposition declaration should commit to tuple interpretation early (take 2)

Jason Merrill jason@redhat.com
Thu Dec 15 19:39:00 GMT 2016


OK.

On Thu, Dec 15, 2016 at 11:44 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Thu, Dec 15, 2016 at 07:40:58AM -0500, Nathan Sidwell wrote:
>> On 12/15/2016 07:26 AM, Jakub Jelinek wrote:
>>
>> > I don't think so.  complete_type (error_mark_node) returns error_mark_node,
>> > and COMPLETE_TYPE_P (error_mark_node) is invalid (should fail TYPE_CHECK in
>> > checking compiler).
>> >
>> > I can write it as
>> >   inst = complete_type (inst);
>> >   if (inst == error_mark_node || !COMPLETE_TYPE_P (inst))
>> >     return NULL_TREE;
>>
>> that's probably better, because complete_type can return error_mark_node if
>> 'something goes horribly wrong'
>
> Ok, here is the updated patch (and also moving the diagnostics to
> get_tuple_size caller as written in the other mail as an option),
> bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2016-12-15  Jakub Jelinek  <jakub@redhat.com>
>
>         P0490R0 GB 20: decomposition declaration should commit to tuple
>         interpretation early
>         * decl.c (get_tuple_size): Make static.  If inst is error_mark_node
>         or non-complete type, return NULL_TREE, otherwise if
>         lookup_qualified_name fails or doesn't fold into INTEGER_CST, return
>         error_mark_node.
>         (get_tuple_element_type, get_tuple_decomp_init): Make static.
>         (cp_finish_decomp): Pass LOC to get_tuple_size.  If it returns
>         error_mark_node, complain and fail.
>
>         * g++.dg/cpp1z/decomp10.C (f1): Adjust expected diagnostics.
>
> --- gcc/cp/decl.c.jj    2016-12-08 23:17:57.256167066 +0100
> +++ gcc/cp/decl.c       2016-12-15 13:48:48.087424991 +0100
> @@ -7259,7 +7259,7 @@ find_decomp_class_base (location_t loc,
>
>  /* Return std::tuple_size<TYPE>::value.  */
>
> -tree
> +static tree
>  get_tuple_size (tree type)
>  {
>    tree args = make_tree_vec (1);
> @@ -7268,6 +7268,9 @@ get_tuple_size (tree type)
>                                      /*in_decl*/NULL_TREE,
>                                      /*context*/std_node,
>                                      /*entering_scope*/false, tf_none);
> +  inst = complete_type (inst);
> +  if (inst == error_mark_node || !COMPLETE_TYPE_P (inst))
> +    return NULL_TREE;
>    tree val = lookup_qualified_name (inst, get_identifier ("value"),
>                                     /*type*/false, /*complain*/false);
>    if (TREE_CODE (val) == VAR_DECL || TREE_CODE (val) == CONST_DECL)
> @@ -7275,12 +7278,12 @@ get_tuple_size (tree type)
>    if (TREE_CODE (val) == INTEGER_CST)
>      return val;
>    else
> -    return NULL_TREE;
> +    return error_mark_node;
>  }
>
>  /* Return std::tuple_element<I,TYPE>::type.  */
>
> -tree
> +static tree
>  get_tuple_element_type (tree type, unsigned i)
>  {
>    tree args = make_tree_vec (2);
> @@ -7297,7 +7302,7 @@ get_tuple_element_type (tree type, unsig
>
>  /* Return e.get<i>() or get<i>(e).  */
>
> -tree
> +static tree
>  get_tuple_decomp_init (tree decl, unsigned i)
>  {
>    tree get_id = get_identifier ("get");
> @@ -7342,6 +7347,7 @@ store_decomp_type (tree v, tree t)
>      decomp_type_table = hash_map<tree,tree>::create_ggc (13);
>    decomp_type_table->put (v, t);
>  }
> +
>  tree
>  lookup_decomp_type (tree v)
>  {
> @@ -7502,6 +7508,12 @@ cp_finish_decomp (tree decl, tree first,
>      }
>    else if (tree tsize = get_tuple_size (type))
>      {
> +      if (tsize == error_mark_node)
> +       {
> +         error_at (loc, "%<std::tuple_size<%T>::value%> is not an integral "
> +                        "constant expression", type);
> +         goto error_out;
> +       }
>        eltscnt = tree_to_uhwi (tsize);
>        if (count != eltscnt)
>         goto cnt_mismatch;
> --- gcc/testsuite/g++.dg/cpp1z/decomp10.C.jj    2016-12-08 23:17:57.477164261 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/decomp10.C       2016-12-15 13:47:47.288240503 +0100
> @@ -7,7 +7,7 @@ namespace std {
>
>  struct A1 { int i,j; } a1;
>  template<> struct std::tuple_size<A1> {  };
> -void f1() { auto [ x ] = a1; } // { dg-error "decomposes into 2" }
> +void f1() { auto [ x ] = a1; } // { dg-error "is not an integral constant expression" }
>
>  struct A2 { int i,j; } a2;
>  template<> struct std::tuple_size<A2> { enum { value = 5 }; };
>
>
>         Jakub



More information about the Gcc-patches mailing list