summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-20 03:07:58 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-20 03:07:58 +0000
commitbbb1e488ddd263ca6a4fa4f50ff5b545846e20ec (patch)
treece8c5bfa7c9da0c60a66b1fa7ea7ce89663aebd0 /gcc
parent632ec4423a86716aebfe3f6d45889027bf7f8a49 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/name-lookup.c99
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/inherit/using5.C2
-rw-r--r--gcc/testsuite/g++.dg/template/using10.C11
-rw-r--r--gcc/testsuite/g++.dg/template/using11.C8
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;
+};