This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH]: Fix bug 1981
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ PATCH]: Fix bug 1981
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Thu, 01 Mar 2001 14:15:08 +0000
- Organization: Codesourcery LLC
Hi,
I've installed the attached on both the mainline and 3.0 branch.
It fixes bug 1981, and we now honour using declarations inside template
functions. This is a regression from 2.95 when the used namespace is std.
previously we didn't honour std, so `using std::foo' was a NOP. Now
it is not.
built & tested on i686-pc-linux-gnu, approved by Mark.
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-02-27 Nathan Sidwell <nathan@codesourcery.com>
Implement using decls inside template functions.
* decl2.c (validate_nonmember_using_decl): Don't special case
fake_std_node in the global namespace. Don't reject early when
processing a template.
(do_local_using_decl): Add to statement tree. Don't do further
processing when building a template.
* pt.c (tsubst_expr, DECL_STMT case): Deal with USING_DECLs.
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.443
diff -c -3 -p -r1.443 decl2.c
*** decl2.c 2001/02/19 21:47:08 1.443
--- decl2.c 2001/02/27 15:28:13
*************** validate_nonmember_using_decl (decl, sco
*** 5032,5047 ****
if (TREE_CODE (decl) == SCOPE_REF
&& TREE_OPERAND (decl, 0) == fake_std_node)
{
- if (namespace_bindings_p ()
- && current_namespace == global_namespace)
- /* There's no need for a using declaration at all, here,
- since `std' is the same as `::'. We can't just pass this
- on because we'll complain later about declaring something
- in the same scope as a using declaration with the same
- name. We return NULL_TREE which indicates to the caller
- that there's no need to do any further processing. */
- return NULL_TREE;
-
*scope = global_namespace;
*name = TREE_OPERAND (decl, 1);
}
--- 5032,5037 ----
*************** validate_nonmember_using_decl (decl, sco
*** 5054,5060 ****
A using-declaration for a class member shall be a
member-declaration. */
! if (TREE_CODE (*scope) != NAMESPACE_DECL)
{
if (TYPE_P (*scope))
cp_error ("`%T' is not a namespace", *scope);
--- 5044,5051 ----
A using-declaration for a class member shall be a
member-declaration. */
! if (!processing_template_decl
! && TREE_CODE (*scope) != NAMESPACE_DECL)
{
if (TYPE_P (*scope))
cp_error ("`%T' is not a namespace", *scope);
*************** do_local_using_decl (decl)
*** 5211,5216 ****
--- 5202,5213 ----
decl = validate_nonmember_using_decl (decl, &scope, &name);
if (decl == NULL_TREE)
+ return;
+
+ if (building_stmt_tree ()
+ && at_function_scope_p ())
+ add_decl_stmt (decl);
+ if (processing_template_decl)
return;
oldval = lookup_name_current_level (name);
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.522
diff -c -3 -p -r1.522 pt.c
*** pt.c 2001/02/18 20:31:43 1.522
--- pt.c 2001/02/27 15:28:26
*************** tsubst_expr (t, args, complain, in_decl)
*** 7315,7320 ****
--- 7315,7328 ----
decl = DECL_STMT_DECL (t);
if (TREE_CODE (decl) == LABEL_DECL)
finish_label_decl (DECL_NAME (decl));
+ else if (TREE_CODE (decl) == USING_DECL)
+ {
+ tree scope = DECL_INITIAL (decl);
+ tree name = DECL_NAME (decl);
+
+ scope = tsubst_expr (scope, args, complain, in_decl);
+ do_local_using_decl (build_nt (SCOPE_REF, scope, name));
+ }
else
{
init = DECL_INITIAL (decl);
// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 26 Feb 2001 <nathan@codesourcery.com>
// Bug 1981. using declarations in namespace scope were not remembered.
namespace A
{
void swap () {}
};
template <class T> void f()
{
using A::swap;
}
template void f<float> ();
namespace B
{
int foo (int) { return 1;}
template <class T> int baz ()
{
using ::foo;
return foo (1);
}
template int baz<float> ();
};
int foo (int) { return 0;}
int main ()
{
return B::baz<float> ();
}