Commit ce7888da by Jakub Jelinek Committed by Jakub Jelinek

P0490R0 GB 20: decomposition declaration should commit to tuple interpretation early

	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.

From-SVN: r243724
parent 2a810ded
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.
2016-12-15 Nathan Sidwell <nathan@acm.org> 2016-12-15 Nathan Sidwell <nathan@acm.org>
PR c++/77585 PR c++/77585
......
...@@ -7259,7 +7259,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret) ...@@ -7259,7 +7259,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret)
/* Return std::tuple_size<TYPE>::value. */ /* Return std::tuple_size<TYPE>::value. */
tree static tree
get_tuple_size (tree type) get_tuple_size (tree type)
{ {
tree args = make_tree_vec (1); tree args = make_tree_vec (1);
...@@ -7268,6 +7268,9 @@ get_tuple_size (tree type) ...@@ -7268,6 +7268,9 @@ get_tuple_size (tree type)
/*in_decl*/NULL_TREE, /*in_decl*/NULL_TREE,
/*context*/std_node, /*context*/std_node,
/*entering_scope*/false, tf_none); /*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"), tree val = lookup_qualified_name (inst, get_identifier ("value"),
/*type*/false, /*complain*/false); /*type*/false, /*complain*/false);
if (TREE_CODE (val) == VAR_DECL || TREE_CODE (val) == CONST_DECL) if (TREE_CODE (val) == VAR_DECL || TREE_CODE (val) == CONST_DECL)
...@@ -7275,12 +7278,12 @@ get_tuple_size (tree type) ...@@ -7275,12 +7278,12 @@ get_tuple_size (tree type)
if (TREE_CODE (val) == INTEGER_CST) if (TREE_CODE (val) == INTEGER_CST)
return val; return val;
else else
return NULL_TREE; return error_mark_node;
} }
/* Return std::tuple_element<I,TYPE>::type. */ /* Return std::tuple_element<I,TYPE>::type. */
tree static tree
get_tuple_element_type (tree type, unsigned i) get_tuple_element_type (tree type, unsigned i)
{ {
tree args = make_tree_vec (2); tree args = make_tree_vec (2);
...@@ -7297,7 +7300,7 @@ get_tuple_element_type (tree type, unsigned i) ...@@ -7297,7 +7300,7 @@ get_tuple_element_type (tree type, unsigned i)
/* Return e.get<i>() or get<i>(e). */ /* Return e.get<i>() or get<i>(e). */
tree static tree
get_tuple_decomp_init (tree decl, unsigned i) get_tuple_decomp_init (tree decl, unsigned i)
{ {
tree get_id = get_identifier ("get"); tree get_id = get_identifier ("get");
...@@ -7342,6 +7345,7 @@ store_decomp_type (tree v, tree t) ...@@ -7342,6 +7345,7 @@ store_decomp_type (tree v, tree t)
decomp_type_table = hash_map<tree,tree>::create_ggc (13); decomp_type_table = hash_map<tree,tree>::create_ggc (13);
decomp_type_table->put (v, t); decomp_type_table->put (v, t);
} }
tree tree
lookup_decomp_type (tree v) lookup_decomp_type (tree v)
{ {
...@@ -7502,6 +7506,12 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) ...@@ -7502,6 +7506,12 @@ cp_finish_decomp (tree decl, tree first, unsigned int count)
} }
else if (tree tsize = get_tuple_size (type)) 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); eltscnt = tree_to_uhwi (tsize);
if (count != eltscnt) if (count != eltscnt)
goto cnt_mismatch; goto cnt_mismatch;
......
2016-12-15 Jakub Jelinek <jakub@redhat.com>
P0490R0 GB 20: decomposition declaration should commit to tuple
interpretation early
* g++.dg/cpp1z/decomp10.C (f1): Adjust expected diagnostics.
2016-12-15 Nathan Sidwell <nathan@acm.org> 2016-12-15 Nathan Sidwell <nathan@acm.org>
PR c++/77585 PR c++/77585
......
...@@ -7,7 +7,7 @@ namespace std { ...@@ -7,7 +7,7 @@ namespace std {
struct A1 { int i,j; } a1; struct A1 { int i,j; } a1;
template<> struct std::tuple_size<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; struct A2 { int i,j; } a2;
template<> struct std::tuple_size<A2> { enum { value = 5 }; }; template<> struct std::tuple_size<A2> { enum { value = 5 }; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment