From 58dec010560be6fc090a2b5a65e5b4349b88748b Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 29 May 2017 12:52:58 +0000 Subject: [PATCH] PR c++/80891 (#3) PR c++/80891 (#3) * cp-tree.h (build_min_nt_call_vec): Declare. * decl.c (build_offset_ref_call_from_tree): Call it. * parser.c (cp_parser_postfix_expression): Likewise. * pt.c (tsubst_copy_and_build): Likewise. * semantics.c (finish_call_expr): Likewise. * tree.c (build_min_nt_loc): Keep unresolved lookups. (build_min): Likewise. (build_min_non_dep): Likewise. (build_min_non_dep_call_vec): Likewise. (build_min_nt_call_vec): New. PR c++/80891 (#3) * g++.dg/lookup/pr80891-3.C: New. From-SVN: r248571 --- gcc/cp/ChangeLog | 16 ++++++++++- gcc/cp/cp-tree.h | 1 + gcc/cp/decl2.c | 2 +- gcc/cp/parser.c | 2 +- gcc/cp/pt.c | 2 +- gcc/cp/semantics.c | 2 +- gcc/cp/tree.c | 38 +++++++++++++++++++++---- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/g++.dg/lookup/pr80891-3.C | 26 +++++++++++++++++ 9 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/pr80891-3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8f5dbc3f08b..67d86fa1114 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,10 +1,24 @@ -2017-05-26 Nathan Sidwell +2017-05-29 Nathan Sidwell + + PR c++/80891 (#3) + * cp-tree.h (build_min_nt_call_vec): Declare. + * decl.c (build_offset_ref_call_from_tree): Call it. + * parser.c (cp_parser_postfix_expression): Likewise. + * pt.c (tsubst_copy_and_build): Likewise. + * semantics.c (finish_call_expr): Likewise. + * tree.c (build_min_nt_loc): Keep unresolved lookups. + (build_min): Likewise. + (build_min_non_dep): Likewise. + (build_min_non_dep_call_vec): Likewise. + (build_min_nt_call_vec): New. PR c++/80891 (#2) * tree.c (ovl_copy): Adjust assert, copy OVL_LOOKUP. (ovl_used): New. (lookup_keep): Call it. +2017-05-26 Nathan Sidwell + Implement DR2061 * name-lookup.c (push_inline_namespaces): New. (push_namespace): Look inside inline namespaces. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a64e3ddd989..f1df0bd8dd7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6891,6 +6891,7 @@ extern tree build_min_nt_loc (location_t, enum tree_code, ...); extern tree build_min_non_dep (enum tree_code, tree, ...); extern tree build_min_non_dep_op_overload (enum tree_code, tree, tree, ...); +extern tree build_min_nt_call_vec (tree, vec *); extern tree build_min_non_dep_call_vec (tree, tree, vec *); extern vec* vec_copy_and_insert (vec*, tree, unsigned); extern tree build_cplus_new (tree, tree, tsubst_flags_t); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 73eeb01fd75..a095901be09 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4891,7 +4891,7 @@ build_offset_ref_call_from_tree (tree fn, vec **args, || TREE_CODE (fn) == MEMBER_REF); if (type_dependent_expression_p (fn) || any_type_dependent_arguments_p (*args)) - return build_nt_call_vec (fn, *args); + return build_min_nt_call_vec (fn, *args); orig_args = make_tree_vector_copy (*args); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4f2c2d53294..313eebbc3d5 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -6952,7 +6952,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, { maybe_generic_this_capture (instance, fn); postfix_expression - = build_nt_call_vec (postfix_expression, args); + = build_min_nt_call_vec (postfix_expression, args); release_tree_vector (args); break; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 68514c911e9..9c423366102 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17389,7 +17389,7 @@ tsubst_copy_and_build (tree t, && TREE_CODE (fn) != FIELD_DECL) || type_dependent_expression_p (fn) || any_type_dependent_arguments_p (call_args))) - ret = build_nt_call_vec (function, call_args); + ret = build_min_nt_call_vec (function, call_args); else if (!BASELINK_P (fn)) ret = finish_call_expr (function, &call_args, /*disallow_virtual=*/false, diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index df83d23c713..87b95345d5c 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2322,7 +2322,7 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, if (type_dependent_expression_p (fn) || any_type_dependent_arguments_p (*args)) { - result = build_nt_call_vec (fn, *args); + result = build_min_nt_call_vec (fn, *args); SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location)); KOENIG_LOOKUP_P (result) = koenig_p; if (is_overloaded_fn (fn)) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 9951b28d23d..37297d2a465 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -3216,13 +3216,14 @@ build_min_nt_loc (location_t loc, enum tree_code code, ...) { tree x = va_arg (p, tree); TREE_OPERAND (t, i) = x; + if (x && TREE_CODE (x) == OVERLOAD) + lookup_keep (x, true); } va_end (p); return t; } - /* Similar to `build', but for template definitions. */ tree @@ -3245,8 +3246,13 @@ build_min (enum tree_code code, tree tt, ...) { tree x = va_arg (p, tree); TREE_OPERAND (t, i) = x; - if (x && !TYPE_P (x) && TREE_SIDE_EFFECTS (x)) - TREE_SIDE_EFFECTS (t) = 1; + if (x) + { + if (!TYPE_P (x) && TREE_SIDE_EFFECTS (x)) + TREE_SIDE_EFFECTS (t) = 1; + if (TREE_CODE (x) == OVERLOAD) + lookup_keep (x, true); + } } va_end (p); @@ -3281,6 +3287,8 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...) { tree x = va_arg (p, tree); TREE_OPERAND (t, i) = x; + if (x && TREE_CODE (x) == OVERLOAD) + lookup_keep (x, true); } if (code == COMPOUND_EXPR && TREE_CODE (non_dep) != COMPOUND_EXPR) @@ -3292,14 +3300,34 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...) return convert_from_reference (t); } -/* Similar to `build_nt_call_vec', but for template definitions of +/* Similar to build_min_nt, but call expressions */ + +tree +build_min_nt_call_vec (tree fn, vec *args) +{ + tree ret, t; + unsigned int ix; + + ret = build_vl_exp (CALL_EXPR, vec_safe_length (args) + 3); + CALL_EXPR_FN (ret) = fn; + CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE; + FOR_EACH_VEC_SAFE_ELT (args, ix, t) + { + CALL_EXPR_ARG (ret, ix) = t; + if (TREE_CODE (t) == OVERLOAD) + lookup_keep (t, true); + } + return ret; +} + +/* Similar to `build_min_nt_call_vec', but for template definitions of non-dependent expressions. NON_DEP is the non-dependent expression that has been built. */ tree build_min_non_dep_call_vec (tree non_dep, tree fn, vec *argvec) { - tree t = build_nt_call_vec (fn, argvec); + tree t = build_min_nt_call_vec (fn, argvec); if (REFERENCE_REF_P (non_dep)) non_dep = TREE_OPERAND (non_dep, 0); TREE_TYPE (t) = TREE_TYPE (non_dep); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b3f6773594a..d8603f8a8a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-05-29 Nathan Sidwell + PR c++/80891 (#3) + * g++.dg/lookup/pr80891-3.C: New. + PR c++/80891 (#2) * g++.dg/lookup/pr80891-2.C: New. diff --git a/gcc/testsuite/g++.dg/lookup/pr80891-3.C b/gcc/testsuite/g++.dg/lookup/pr80891-3.C new file mode 100644 index 00000000000..e693a357c22 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/pr80891-3.C @@ -0,0 +1,26 @@ +// PR c++/80891 part 3 +// We were failing to mark OVERLOADS held in template definitions as +// immutable in non-call contexts. + +namespace std { + int endl(); +} + +using std::endl; + +template void test_spots(RealType) +{ + using namespace std; + RealType a; + a << endl; +} + +template +void operator<< (T, int (&)()); + +struct Q {}; +void test_maintest_method() +{ + Q q; + test_spots(q); +} -- 2.30.2