From 2bd0a2d6b1b823008e36e1a5833cf520c3807ecc Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 15 Feb 2016 16:14:05 -0500 Subject: [PATCH] =?utf8?q?re=20PR=20c++/69753=20(bogus:=20expected=20prima?= =?utf8?q?ry-expression=20before=20=E2=80=98>=E2=80=99=20token)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit PR c++/69753 * search.c (any_dependent_bases_p): Split out... * name-lookup.c (do_class_using_decl): ...from here. * call.c (build_new_method_call_1): Don't complain about missing object if there are dependent bases. Tweak error. * tree.c (non_static_member_function_p): Remove. * pt.c (type_dependent_expression_p): A member template of a dependent type is dependent. * cp-tree.h: Adjust. From-SVN: r233431 --- gcc/cp/ChangeLog | 12 ++++++++++++ gcc/cp/call.c | 5 ++++- gcc/cp/cp-tree.h | 2 +- gcc/cp/name-lookup.c | 13 +------------ gcc/cp/pt.c | 13 ++++++++++--- gcc/cp/search.c | 18 ++++++++++++++++++ gcc/cp/semantics.c | 23 +---------------------- gcc/cp/tree.c | 17 ----------------- gcc/testsuite/g++.dg/lookup/member3.C | 17 +++++++++++++++++ 9 files changed, 64 insertions(+), 56 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/member3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 85473df23d5..04d55bc60b9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,17 @@ 2016-02-15 Jason Merrill + PR c++/69753 + * semantics.c (finish_call_expr): Implicit 'this' does not make + the call dependent. + * search.c (any_dependent_bases_p): Split out... + * name-lookup.c (do_class_using_decl): ...from here. + * call.c (build_new_method_call_1): Don't complain about missing object + if there are dependent bases. Tweak error. + * tree.c (non_static_member_function_p): Remove. + * pt.c (type_dependent_expression_p): A member template of a + dependent type is dependent. + * cp-tree.h: Adjust. + PR c++/68890 * constexpr.c (verify_ctor_sanity): Remove CONSTRUCTOR_NELTS check. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index cb71176c6ca..db406543522 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8160,7 +8160,7 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, if (permerror (input_location, "cannot call constructor %<%T::%D%> directly", - basetype, name)) + BINFO_TYPE (access_binfo), name)) inform (input_location, "for a function-style cast, remove the " "redundant %<::%D%>", name); call = build_functional_cast (basetype, build_tree_list_vec (user_args), @@ -8377,6 +8377,9 @@ build_new_method_call_1 (tree instance, tree fns, vec **args, we know we really need it. */ cand->first_arg = instance; } + else if (any_dependent_bases_p ()) + /* We can't tell until instantiation time whether we can use + *this as the implicit object argument. */; else { if (complain & tf_error) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3b91089f50d..b7d7bc68502 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6252,6 +6252,7 @@ extern tree adjust_result_of_qualified_name_lookup extern tree copied_binfo (tree, tree); extern tree original_binfo (tree, tree); extern int shared_member_p (tree); +extern bool any_dependent_bases_p (tree = current_nonlambda_class_type ()); /* The representation of a deferred access check. */ @@ -6542,7 +6543,6 @@ extern tree get_first_fn (tree); extern tree ovl_cons (tree, tree); extern tree build_overload (tree, tree); extern tree ovl_scope (tree); -extern bool non_static_member_function_p (tree); extern const char *cxx_printable_name (tree, int); extern const char *cxx_printable_name_translate (tree, int); extern tree build_exception_variant (tree, tree); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 8d6e75a1347..b5961e573f3 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3333,8 +3333,6 @@ do_class_using_decl (tree scope, tree name) /* True if any of the bases of CURRENT_CLASS_TYPE are dependent. */ bool bases_dependent_p; tree binfo; - tree base_binfo; - int i; if (name == error_mark_node) return NULL_TREE; @@ -3371,16 +3369,7 @@ do_class_using_decl (tree scope, tree name) || (IDENTIFIER_TYPENAME_P (name) && dependent_type_p (TREE_TYPE (name)))); - bases_dependent_p = false; - if (processing_template_decl) - for (binfo = TYPE_BINFO (current_class_type), i = 0; - BINFO_BASE_ITERATE (binfo, i, base_binfo); - i++) - if (dependent_type_p (TREE_TYPE (base_binfo))) - { - bases_dependent_p = true; - break; - } + bases_dependent_p = any_dependent_bases_p (current_class_type); decl = NULL_TREE; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a55dc10fdfc..52e60b948b4 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -22904,9 +22904,16 @@ type_dependent_expression_p (tree expression) && DECL_TEMPLATE_INFO (expression)) return any_dependent_template_arguments_p (DECL_TI_ARGS (expression)); - if (TREE_CODE (expression) == TEMPLATE_DECL - && !DECL_TEMPLATE_TEMPLATE_PARM_P (expression)) - return false; + if (TREE_CODE (expression) == TEMPLATE_DECL) + { + if (DECL_CLASS_SCOPE_P (expression) + && dependent_type_p (DECL_CONTEXT (expression))) + /* A template's own parameters don't make it dependent, since those can + be deduced, but the enclosing class does. */ + return true; + if (!DECL_TEMPLATE_TEMPLATE_PARM_P (expression)) + return false; + } if (TREE_CODE (expression) == STMT_EXPR) expression = stmt_expr_value_expr (expression); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 79246118915..49f3bc5ed80 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2842,3 +2842,21 @@ original_binfo (tree binfo, tree here) return result; } +/* True iff TYPE has any dependent bases (and therefore we can't say + definitively that another class is not a base of an instantiation of + TYPE). */ + +bool +any_dependent_bases_p (tree type) +{ + if (!type || !CLASS_TYPE_P (type) || !processing_template_decl) + return false; + + unsigned i; + tree base_binfo; + FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i, base_binfo) + if (BINFO_DEPENDENT_BASE_P (base_binfo)) + return true; + + return false; +} diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0cf5f930b1e..0f6a6b5c539 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2264,17 +2264,7 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, with no type; type_dependent_expression_p recognizes expressions with no type as being dependent. */ if (type_dependent_expression_p (fn) - || any_type_dependent_arguments_p (*args) - /* For a non-static member function that doesn't have an - explicit object argument, we need to specifically - test the type dependency of the "this" pointer because it - is not included in *ARGS even though it is considered to - be part of the list of arguments. Note that this is - related to CWG issues 515 and 1005. */ - || (TREE_CODE (fn) != COMPONENT_REF - && non_static_member_function_p (fn) - && current_class_ref - && type_dependent_expression_p (current_class_ref))) + || any_type_dependent_arguments_p (*args)) { result = build_nt_call_vec (fn, *args); SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location)); @@ -2354,17 +2344,6 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), NULL); - if (processing_template_decl) - { - if (type_dependent_expression_p (object)) - { - tree ret = build_nt_call_vec (orig_fn, orig_args); - release_tree_vector (orig_args); - return ret; - } - object = build_non_dependent_expr (object); - } - result = build_new_method_call (object, fn, args, NULL_TREE, (disallow_virtual ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 3203acaff9e..041facda96a 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2071,23 +2071,6 @@ ovl_scope (tree ovl) ovl = OVL_CHAIN (ovl); return CP_DECL_CONTEXT (OVL_CURRENT (ovl)); } - -/* Return TRUE if FN is a non-static member function, FALSE otherwise. - This function looks into BASELINK and OVERLOAD nodes. */ - -bool -non_static_member_function_p (tree fn) -{ - if (fn == NULL_TREE) - return false; - - if (is_overloaded_fn (fn)) - fn = get_first_fn (fn); - - return (DECL_P (fn) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)); -} - #define PRINT_RING_SIZE 4 diff --git a/gcc/testsuite/g++.dg/lookup/member3.C b/gcc/testsuite/g++.dg/lookup/member3.C new file mode 100644 index 00000000000..f4e097e4719 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/member3.C @@ -0,0 +1,17 @@ +// PR c++/69753 +// { dg-do compile { target c++11 } } + +class A { +public: + template void As(); + static A *FromWebContents(); + A *FromWebContents2(); +}; +template class B : A { + void FromWebContents() { + auto guest = A::FromWebContents(); + guest ? guest->As() : nullptr; + auto guest2 = A::FromWebContents2(); + guest2 ? guest2->As() : nullptr; + } +}; -- 2.30.2