diff options
author | Jason Merrill <jason@gcc.gnu.org> | 2006-09-05 21:15:09 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2006-09-05 21:15:09 -0400 |
commit | b01e6d2b91976fb7a4efd0147090f743cec7bbcf (patch) | |
tree | fc0bf5d8a95f07ff8fe2c9161eeb3812c9ecbd7b | |
parent | 6dd0d2f48454187c94e2b14cc7eaf99ced15a94d (diff) | |
download | gcc-b01e6d2b91976fb7a4efd0147090f743cec7bbcf.zip gcc-b01e6d2b91976fb7a4efd0147090f743cec7bbcf.tar.gz gcc-b01e6d2b91976fb7a4efd0147090f743cec7bbcf.tar.bz2 |
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
-rw-r--r-- | gcc/cp/name-lookup.c | 13 | ||||
-rw-r--r-- | gcc/cp/pt.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/friend47.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/using14.C | 21 |
4 files changed, 45 insertions, 7 deletions
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index e794232..3016bb0 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 79d9de4..d278b00 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 0000000..6121739 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend47.C @@ -0,0 +1,11 @@ +// PR c++/19809 + +template<int i> +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 0000000..d104948 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using14.C @@ -0,0 +1,21 @@ +// PR c++/26102 + +template <class T> struct B1 { int i(); }; + +struct B2 { int i(); }; + +template <class T> struct C : public B1<T>, public B2 +{ + using B2::i; + void f() + { + i(); // should be accepted + i.i(); // { dg-error "" } + } +}; + +int main() +{ + C<int> c; + c.f(); // { dg-error "instantiated" } +} |