From: Jason Merrill Date: Wed, 6 Sep 2006 01:15:09 +0000 (-0400) Subject: re PR c++/26102 ("using Base::member" nonsense) X-Git-Tag: releases/gcc-4.2.0~1525 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b01e6d2b91976fb7a4efd0147090f743cec7bbcf;p=thirdparty%2Fgcc.git re PR c++/26102 ("using Base::member" nonsense) PR c++/26102 * name-lookup.c (do_class_using_decl): Try to find the base even if bases_dependent_p. * pt.c (type_dependent_expression_p): A USING_DECL is dependent. PR c++/19809 * pt.c (tsubst_friend_function): Set DECL_INITIAL before pushdecl. From-SVN: r116709 --- diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index e794232131d3..3016bb0ad560 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2824,18 +2824,19 @@ do_class_using_decl (tree scope, tree name) class type. However, if all of the base classes are non-dependent, then we can avoid delaying the check until instantiation. */ - if (!scope_dependent_p && !bases_dependent_p) + if (!scope_dependent_p) { base_kind b_kind; - tree binfo; binfo = lookup_base (current_class_type, scope, ba_any, &b_kind); if (b_kind < bk_proper_base) { - error_not_base_type (scope, current_class_type); - return NULL_TREE; + if (!bases_dependent_p) + { + error_not_base_type (scope, current_class_type); + return NULL_TREE; + } } - - if (!name_dependent_p) + else if (!name_dependent_p) { decl = lookup_member (binfo, name, 0, false); if (!decl) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 79d9de4e4ce7..d278b00448ee 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5333,6 +5333,10 @@ tsubst_friend_function (tree decl, tree args) else new_friend_result_template_info = NULL_TREE; + /* Make the init_value nonzero so pushdecl knows this is a defn. */ + if (new_friend_is_defn) + DECL_INITIAL (new_friend) = error_mark_node; + /* Inside pushdecl_namespace_level, we will push into the current namespace. However, the friend function should go into the namespace of the template. */ @@ -12862,7 +12866,8 @@ type_dependent_expression_p (tree expression) return false; /* An unresolved name is always dependent. */ - if (TREE_CODE (expression) == IDENTIFIER_NODE) + if (TREE_CODE (expression) == IDENTIFIER_NODE + || TREE_CODE (expression) == USING_DECL) return true; /* Some expression forms are never type-dependent. */ diff --git a/gcc/testsuite/g++.dg/template/friend47.C b/gcc/testsuite/g++.dg/template/friend47.C new file mode 100644 index 000000000000..612173950a7e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend47.C @@ -0,0 +1,11 @@ +// PR c++/19809 + +template +struct n{ + friend void foo(){ } // { dg-error "defin" } +}; + +int main(){ + n<1> n1; + n<2> n2; +} diff --git a/gcc/testsuite/g++.dg/template/using14.C b/gcc/testsuite/g++.dg/template/using14.C new file mode 100644 index 000000000000..d10494877325 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using14.C @@ -0,0 +1,21 @@ +// PR c++/26102 + +template struct B1 { int i(); }; + +struct B2 { int i(); }; + +template struct C : public B1, public B2 +{ + using B2::i; + void f() + { + i(); // should be accepted + i.i(); // { dg-error "" } + } +}; + +int main() +{ + C c; + c.f(); // { dg-error "instantiated" } +}