From: Jakub Jelinek Date: Thu, 15 Dec 2016 20:42:11 +0000 (+0100) Subject: P0490R0 GB 20: decomposition declaration should commit to tuple interpretation early X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ce7888dae8bfce7f3049727d31d8b7ae4e83c88d;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9c6ee489689..5c6713234a8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2016-12-15 Jakub Jelinek + + 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 PR c++/77585 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d7dbf94c076..e83b542d424 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7259,7 +7259,7 @@ find_decomp_class_base (location_t loc, tree type, tree ret) /* Return std::tuple_size::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::type. */ -tree +static tree get_tuple_element_type (tree type, unsigned i) { tree args = make_tree_vec (2); @@ -7297,7 +7300,7 @@ get_tuple_element_type (tree type, unsigned i) /* Return e.get() or get(e). */ -tree +static tree get_tuple_decomp_init (tree decl, unsigned i) { tree get_id = get_identifier ("get"); @@ -7342,6 +7345,7 @@ store_decomp_type (tree v, tree t) decomp_type_table = hash_map::create_ggc (13); decomp_type_table->put (v, t); } + tree lookup_decomp_type (tree v) { @@ -7502,6 +7506,12 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) } else if (tree tsize = get_tuple_size (type)) { + if (tsize == error_mark_node) + { + error_at (loc, "%::value%> is not an integral " + "constant expression", type); + goto error_out; + } eltscnt = tree_to_uhwi (tsize); if (count != eltscnt) goto cnt_mismatch; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ac49d4d71c0..ea45738e265 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-12-15 Jakub Jelinek + + 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 PR c++/77585 diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp10.C b/gcc/testsuite/g++.dg/cpp1z/decomp10.C index 2abbaaebe9a..c2bcb93c1d7 100644 --- a/gcc/testsuite/g++.dg/cpp1z/decomp10.C +++ b/gcc/testsuite/g++.dg/cpp1z/decomp10.C @@ -7,7 +7,7 @@ namespace std { struct A1 { int i,j; } a1; template<> struct std::tuple_size { }; -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 { enum { value = 5 }; };