re PR c++/7964 (ICE in build_base_path)

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.

From-SVN: r60483
This commit is contained in:
Nathan Sidwell 2002-12-24 22:20:14 +00:00 committed by Nathan Sidwell
parent b9201622ae
commit 3e14cd301c
7 changed files with 110 additions and 62 deletions

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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
{

View File

@ -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

View File

@ -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.

View File

@ -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>;