diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-20 03:07:58 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-20 03:07:58 +0000 |
commit | bbb1e488ddd263ca6a4fa4f50ff5b545846e20ec (patch) | |
tree | ce8c5bfa7c9da0c60a66b1fa7ea7ce89663aebd0 /gcc | |
parent | 632ec4423a86716aebfe3f6d45889027bf7f8a49 (diff) | |
download | gcc-bbb1e488ddd263ca6a4fa4f50ff5b545846e20ec.tar.gz |
PR c++/22136
* name-lookup.c (do_class_using_decl): Don't try to look up base
classes in templates with dependent base types.
PR c++/22136
* g++.dg/template/using10.C: New test.
* g++.dg/temlpate/using11.C: Likewise.
* g++.dg/inherit/using5.C: Tweak error messages.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110017 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 99 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/inherit/using5.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/using10.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/using11.C | 8 |
6 files changed, 95 insertions, 38 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 53b2953320a..5fabf49df71 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2006-01-19 Mark Mitchell <mark@codesourcery.com> + + PR c++/22136 + * name-lookup.c (do_class_using_decl): Don't try to look up base + classes in templates with dependent base types. + 2006-01-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de> PR c++/25854 diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 4a2482f5880..190ae24cd94 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2722,9 +2722,21 @@ push_class_level_binding (tree name, tree x) tree do_class_using_decl (tree scope, tree name) { - tree value, decl, binfo; - base_kind b_kind; - bool dependent_p; + /* The USING_DECL returned by this function. */ + tree value; + /* The declaration (or declarations) name by this using + declaration. NULL if we are in a template and cannot figure out + what has been named. */ + tree decl; + /* True if SCOPE is a dependent type. */ + bool scope_dependent_p; + /* True if SCOPE::NAME is dependent. */ + bool name_dependent_p; + /* True if any of the bases of CURRENT_CLASS_TYPE are dependent. */ + bool bases_dependent_p; + tree binfo; + tree base_binfo; + int i; if (!scope || !TYPE_P (scope)) { @@ -2732,25 +2744,6 @@ do_class_using_decl (tree scope, tree name) return NULL_TREE; } - /* Make sure the scope is a base. */ - dependent_p = dependent_type_p (scope); - if (!dependent_p) - binfo = lookup_base (current_class_type, scope, ba_any, &b_kind); - else - { - binfo = NULL; - if (same_type_p (current_class_type, scope)) - b_kind = bk_same_type; - else - b_kind = bk_proper_base; - } - - if (b_kind < bk_proper_base) - { - error_not_base_type (scope, current_class_type); - return NULL_TREE; - } - /* Make sure the name is not invalid */ if (TREE_CODE (name) == BIT_NOT_EXPR) { @@ -2769,32 +2762,64 @@ do_class_using_decl (tree scope, tree name) return NULL_TREE; } - if (!dependent_p - && IDENTIFIER_OPNAME_P (name) && dependent_type_p (TREE_TYPE (name))) - dependent_p = 1; + scope_dependent_p = dependent_type_p (scope); + name_dependent_p = (scope_dependent_p + || (IDENTIFIER_OPNAME_P (name) + && dependent_type_p (TREE_TYPE (name)))); + + bases_dependent_p = false; + if (processing_template_decl) + for (binfo = TYPE_BINFO (current_class_type), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); + i++) + if (dependent_type_p (TREE_TYPE (base_binfo))) + { + bases_dependent_p = true; + break; + } - /* See if there are any members of the base. */ - if (!dependent_p) - { - decl = lookup_member (binfo, name, 0, false); + decl = NULL_TREE; + + /* From [namespace.udecl]: - if (!decl) + A using-declaration used as a member-declaration shall refer to a + member of a base class of the class being defined. + + In general, we cannot check this constraint in a template because + we do not know the entire set of base classes of the current + 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) + { + base_kind b_kind; + tree binfo; + binfo = lookup_base (current_class_type, scope, ba_any, &b_kind); + if (b_kind < bk_proper_base) { - error ("no members matching %<%T::%D%> in %q#T", scope, name, scope); + error_not_base_type (scope, current_class_type); return NULL_TREE; } - if (BASELINK_P (decl)) - /* Ignore base type this came from. */ - decl = BASELINK_FUNCTIONS (decl); + if (!name_dependent_p) + { + decl = lookup_member (binfo, name, 0, false); + if (!decl) + { + error ("no members matching %<%T::%D%> in %q#T", scope, name, + scope); + return NULL_TREE; + } + /* The binfo from which the functions came does not matter. */ + if (BASELINK_P (decl)) + decl = BASELINK_FUNCTIONS (decl); + } } - else - decl = NULL_TREE; value = build_lang_decl (USING_DECL, name, NULL_TREE); USING_DECL_DECLS (value) = decl; USING_DECL_SCOPE (value) = scope; - DECL_DEPENDENT_P (value) = dependent_p; + DECL_DEPENDENT_P (value) = !decl; return value; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cc736693be3..b41928e4d82 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2006-01-19 Mark Mitchell <mark@codesourcery.com> + + PR c++/22136 + * g++.dg/template/using10.C: New test. + * g++.dg/temlpate/using11.C: Likewise. + * g++.dg/inherit/using5.C: Tweak error messages. + 2006-01-20 Alan Modra <amodra@bigpond.net.au> * gcc.target/powerpc/rs6000-ldouble-1.c: Tweak powerpc linux diff --git a/gcc/testsuite/g++.dg/inherit/using5.C b/gcc/testsuite/g++.dg/inherit/using5.C index 896c2d461de..89c7ca03ba6 100644 --- a/gcc/testsuite/g++.dg/inherit/using5.C +++ b/gcc/testsuite/g++.dg/inherit/using5.C @@ -6,7 +6,7 @@ template<int> struct A { - A::A; // { dg-error "not a base" } + A::A; // { dg-error "constructor" } }; struct B diff --git a/gcc/testsuite/g++.dg/template/using10.C b/gcc/testsuite/g++.dg/template/using10.C new file mode 100644 index 00000000000..8f0cbda2a88 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using10.C @@ -0,0 +1,11 @@ +// PR c++/22136 + +struct B { + void foo(); +}; + +template <typename T> class I : public B {}; + +template <typename T> class D : private I<T> { + I<T>::B::foo; +}; diff --git a/gcc/testsuite/g++.dg/template/using11.C b/gcc/testsuite/g++.dg/template/using11.C new file mode 100644 index 00000000000..21cc5d2ef2d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using11.C @@ -0,0 +1,8 @@ +struct X { + void f(); +}; + +template <typename T> +struct S : public T { + using X::f; +}; |