This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH]: Fix 7964
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org, mark at codesourcery dot com
- Date: Tue, 24 Dec 2002 22:20:48 +0000
- Subject: [C++ PATCH]: Fix 7964
Hi,
I've installed this patch to fix 7964. In instantiating a scoped method
call, we weren't going via the same path as non templated things. Thus
missing a base conversion.
Mark, this possibly impacts the new parser, you might be doing things
differently there.
booted and tested on i686-pc-linux-gnu. I'll be putting this on the 3.3
branch shortly.
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
The voices in my head said this was stupid too
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
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.
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.344
diff -c -3 -p -r1.344 call.c
*** cp/call.c 23 Dec 2002 23:44:47 -0000 1.344
--- cp/call.c 24 Dec 2002 22:13:32 -0000
*************** build_user_type_conversion (tree totype,
*** 2597,2602 ****
--- 2597,2665 ----
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
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.782
diff -c -3 -p -r1.782 cp-tree.h
*** cp/cp-tree.h 23 Dec 2002 23:44:47 -0000 1.782
--- cp/cp-tree.h 24 Dec 2002 22:14:02 -0000
*************** extern tree build_method_call (tree, tre
*** 3547,3552 ****
--- 3547,3553 ----
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);
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.579
diff -c -3 -p -r1.579 decl2.c
*** cp/decl2.c 24 Dec 2002 22:12:15 -0000 1.579
--- cp/decl2.c 24 Dec 2002 22:14:20 -0000
*************** build_expr_from_tree (t)
*** 3241,3256 ****
{
tree ref = TREE_OPERAND (t, 0);
tree name = TREE_OPERAND (ref, 1);
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)));
}
else
{
--- 3241,3258 ----
{
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)));
!
! 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
{
Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parse.y,v
retrieving revision 1.287
diff -c -3 -p -r1.287 parse.y
*** cp/parse.y 22 Dec 2002 21:32:27 -0000 1.287
--- cp/parse.y 24 Dec 2002 22:14:31 -0000
*************** static tree
*** 4115,4186 ****
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);
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));
! }
! }
disallow_virtual = true;
}
else
--- 4115,4133 ----
parse_finish_call_expr (tree fn, tree args, int koenig)
{
bool disallow_virtual;
if (TREE_CODE (fn) == OFFSET_REF)
return build_offset_ref_call_from_tree (fn, args);
if (TREE_CODE (fn) == SCOPE_REF)
{
! 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)
! fn = resolve_scoped_fn_name (scope, name);
disallow_virtual = true;
}
else
*************** parse_finish_call_expr (tree fn, tree ar
*** 4188,4193 ****
--- 4135,4142 ----
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
// { 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>;