aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>2006-09-05 21:15:09 -0400
committerJason Merrill <jason@gcc.gnu.org>2006-09-05 21:15:09 -0400
commitb01e6d2b91976fb7a4efd0147090f743cec7bbcf (patch)
treefc0bf5d8a95f07ff8fe2c9161eeb3812c9ecbd7b
parent6dd0d2f48454187c94e2b14cc7eaf99ced15a94d (diff)
downloadgcc-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.c13
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/testsuite/g++.dg/template/friend47.C11
-rw-r--r--gcc/testsuite/g++.dg/template/using14.C21
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" }
+}