From 7f2198661f05632316006cd0c9a4b9e88f60bfd7 Mon Sep 17 00:00:00 2001 From: nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue, 24 Dec 2002 22:20:14 +0000 Subject: [PATCH] cp: PR C++/7964 * cp-tree.h (resolve_scoped_fn_name): Prototype. * call.c (resolve_scoped_fn_name): New function. Deal with more template expansion. Broken out of ... * parse.y (parse_finish_call_expr): ... here. Call it. * decl2.c (build_expr_from_tree, CALL_EXPR): Use resolve_scoped_fn_name and build_call_from_tree. testsuite: * g++.dg/lookup/scoped3.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@60483 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 8 ++++ gcc/cp/call.c | 63 +++++++++++++++++++++++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl2.c | 12 ++--- gcc/cp/parse.y | 61 +++----------------------- gcc/testsuite/ChangeLog | 4 +- gcc/testsuite/g++.dg/lookup/scoped3.C | 23 ++++++++++ 7 files changed, 110 insertions(+), 62 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/scoped3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 921550ed4b2f..3f4c1d0319bb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2002-12-24 Nathan Sidwell <nathan@codesourcery.com> + PR C++/7964 + * cp-tree.h (resolve_scoped_fn_name): Prototype. + * call.c (resolve_scoped_fn_name): New function. Deal with + more template expansion. Broken out of ... + * parse.y (parse_finish_call_expr): ... here. Call it. + * decl2.c (build_expr_from_tree, CALL_EXPR): Use + resolve_scoped_fn_name and build_call_from_tree. + PR c++/9053 * decl.c (duplicate_decls): Templates may be disambiguated by return type. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f1d46ba06bf8..088cc1e46e5f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2597,6 +2597,69 @@ build_user_type_conversion (tree totype, tree expr, int flags) return NULL_TREE; } +/* Find the possibly overloaded set of functions corresponding to a + call of the form SCOPE::NAME (...). NAME might be a + TEMPLATE_ID_EXPR, OVERLOAD, _DECL, IDENTIFIER_NODE or LOOKUP_EXPR. */ + +tree +resolve_scoped_fn_name (tree scope, tree name) +{ + tree fn; + tree template_args = NULL_TREE; + bool is_template_id = TREE_CODE (name) == TEMPLATE_ID_EXPR; + + if (is_template_id) + { + template_args = TREE_OPERAND (name, 1); + name = TREE_OPERAND (name, 0); + } + if (TREE_CODE (name) == OVERLOAD) + name = DECL_NAME (get_first_fn (name)); + else if (TREE_CODE (name) == LOOKUP_EXPR) + name = TREE_OPERAND (name, 0); + + if (TREE_CODE (scope) == NAMESPACE_DECL) + fn = lookup_namespace_name (scope, name); + else + { + if (!TYPE_BEING_DEFINED (scope) + && !COMPLETE_TYPE_P (complete_type (scope))) + { + error ("incomplete type '%T' cannot be used to name a scope", + scope); + return error_mark_node; + } + + if (BASELINK_P (name)) + fn = name; + else + fn = lookup_member (scope, name, /*protect=*/1, /*prefer_type=*/0); + if (fn && current_class_type) + fn = (adjust_result_of_qualified_name_lookup + (fn, scope, current_class_type)); + } + + if (!fn) + { + error ("'%D' has no member named '%E'", scope, name); + return error_mark_node; + } + if (is_template_id) + { + tree fns = fn; + + if (BASELINK_P (fn)) + fns = BASELINK_FUNCTIONS (fns); + fns = build_nt (TEMPLATE_ID_EXPR, fns, template_args); + if (BASELINK_P (fn)) + BASELINK_FUNCTIONS (fn) = fns; + else + fn = fns; + } + + return fn; +} + /* Do any initial processing on the arguments to a function call. */ static tree diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 121aabac9e41..b805f976419d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3547,6 +3547,7 @@ extern tree build_method_call (tree, tree, tree, tree, int); extern bool null_ptr_cst_p (tree); extern bool sufficient_parms_p (tree); extern tree type_decays_to (tree); +extern tree resolve_scoped_fn_name (tree, tree); extern tree build_user_type_conversion (tree, tree, int); extern tree build_new_function_call (tree, tree); extern tree build_new_method_call (tree, tree, tree, tree, int); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index afb8693a6b73..3d717e8475b9 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3241,16 +3241,18 @@ build_expr_from_tree (t) { tree ref = TREE_OPERAND (t, 0); tree name = TREE_OPERAND (ref, 1); + tree fn, scope, args; if (TREE_CODE (name) == TEMPLATE_ID_EXPR) name = build_nt (TEMPLATE_ID_EXPR, TREE_OPERAND (name, 0), build_expr_from_tree (TREE_OPERAND (name, 1))); - - return build_member_call - (build_expr_from_tree (TREE_OPERAND (ref, 0)), - name, - build_expr_from_tree (TREE_OPERAND (t, 1))); + + scope = build_expr_from_tree (TREE_OPERAND (ref, 0)); + args = build_expr_from_tree (TREE_OPERAND (t, 1)); + fn = resolve_scoped_fn_name (scope, name); + + return build_call_from_tree (fn, args, 1); } else { diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index bdbee018e5ab..d1f9f4d68b47 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -4115,72 +4115,19 @@ static tree parse_finish_call_expr (tree fn, tree args, int koenig) { bool disallow_virtual; - tree template_args; - tree template_id; - tree f; if (TREE_CODE (fn) == OFFSET_REF) return build_offset_ref_call_from_tree (fn, args); if (TREE_CODE (fn) == SCOPE_REF) { - tree scope; - tree name; - - scope = TREE_OPERAND (fn, 0); - name = TREE_OPERAND (fn, 1); + tree scope = TREE_OPERAND (fn, 0); + tree name = TREE_OPERAND (fn, 1); if (scope == error_mark_node || name == error_mark_node) return error_mark_node; if (!processing_template_decl) - { - if (TREE_CODE (scope) == NAMESPACE_DECL) - fn = lookup_namespace_name (scope, name); - else - { - if (!COMPLETE_TYPE_P (scope) && !TYPE_BEING_DEFINED (scope)) - { - error ("incomplete type '%T' cannot be used to name a scope", - scope); - return error_mark_node; - } - else if (TREE_CODE (name) == TEMPLATE_ID_EXPR) - { - template_id = name; - template_args = TREE_OPERAND (name, 1); - name = TREE_OPERAND (name, 0); - } - else - { - template_id = NULL_TREE; - template_args = NULL_TREE; - } - - if (BASELINK_P (name)) - fn = name; - else - { - if (TREE_CODE (name) == OVERLOAD) - name = DECL_NAME (get_first_fn (name)); - fn = lookup_member (scope, name, /*protect=*/1, - /*prefer_type=*/0); - if (!fn) - { - error ("'%D' has no member named '%E'", scope, name); - return error_mark_node; - } - - if (BASELINK_P (fn) && template_id) - BASELINK_FUNCTIONS (fn) - = build_nt (TEMPLATE_ID_EXPR, - BASELINK_FUNCTIONS (fn), - template_args); - } - if (current_class_type) - fn = (adjust_result_of_qualified_name_lookup - (fn, scope, current_class_type)); - } - } + fn = resolve_scoped_fn_name (scope, name); disallow_virtual = true; } else @@ -4188,6 +4135,8 @@ parse_finish_call_expr (tree fn, tree args, int koenig) if (koenig && TREE_CODE (fn) == IDENTIFIER_NODE) { + tree f; + /* Do the Koenig lookup. */ fn = do_identifier (fn, 2, args); /* If name lookup didn't find any matching declarations, we've diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b40420e24c3d..8196168626b8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2002-12-24 Nathan Sidwell <nathan@codesourcery.com> - + + * g++.dg/lookup/scoped3.C: New test. + * g++.dg/lookup/decl1.C: New test. * g++.dg/lookup/decl2.C: New test. diff --git a/gcc/testsuite/g++.dg/lookup/scoped3.C b/gcc/testsuite/g++.dg/lookup/scoped3.C new file mode 100644 index 000000000000..992f1d128093 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/scoped3.C @@ -0,0 +1,23 @@ + +// { dg-do compile } + +// Copyright (C) 2002 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 24 Dec 2002 <nathan@codesourcery.com> + +// PR 7964. ICE with scoped method call + +struct A { + virtual void ostr() const; +}; + +class B : public virtual A {}; + +template<typename T> +struct C : public B +{ + void ostr() const + { B::ostr(); } +}; + + +template C<int>; -- GitLab