mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
b9201622ae
commit
3e14cd301c
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
Loading…
Reference in New Issue