aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Klose <doko@ubuntu.com>2009-01-17 16:48:11 +0000
committerMatthias Klose <doko@ubuntu.com>2009-01-17 16:48:11 +0000
commit3e30fb345ec91e360cce3a25b4c4cf64ad5852af (patch)
tree4ba68916a3a7a1c0c28fd20c84856343ff38f6a6
parent75cab0cb3ee9c992f1a9375d0a96a4f93697edf2 (diff)
svn merge -r143239:143470 svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_2-branchubuntu/gcc-4_2-branch
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ubuntu/gcc-4_2-branch@143471 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/name-lookup.c34
-rw-r--r--gcc/cp/pt.c48
-rw-r--r--gcc/testsuite/ChangeLog15
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class12.C24
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class13.C25
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class14.C23
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class15.C30
-rw-r--r--gcc/testsuite/g++.dg/lookup/hidden-class16.C27
-rw-r--r--gcc/testsuite/g++.dg/template/koenig6.C29
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C6
13 files changed, 275 insertions, 7 deletions
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 9a6be213020..4f4c252b9d1 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20090110
+20090117
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 172ccf76b9e..742f90f75dc 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,20 @@
+2009-01-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/38850
+ * pt.c (tsubst_copy_and_build): Tell finish_call_expr to
+ accept hidden friends.
+
+2009-01-12 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/36019
+ * pt.c (parameter_of_template_p): New function.
+ * pt.c (get_template_info): Ditto.
+ * cp-tree.h: Declare those.
+ * name-lookup.c (binding_to_template_parms_of_scope_p): New
+ function.
+ (outer_binding): Take template parameters in account when looking for
+ a name binding.
+
2008-11-19 Dodji Seketeli <dodji@redhat.com>
PR c++/37142
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 48d8de8ff20..576fc28d79c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4163,6 +4163,8 @@ extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree);
extern bool explicit_class_specialization_p (tree);
extern tree outermost_tinst_level (void);
+extern tree get_template_info (tree t);
+extern bool parameter_of_template_p (tree, tree);
/* in repo.c */
extern void init_repo (void);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index f02bf269fad..f990a3bd616 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3850,9 +3850,33 @@ qualified_lookup_using_namespace (tree name, tree scope,
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
}
+/* Subroutine of outer_binding.
+ Returns TRUE if BINDING is a binding to a template parameter of SCOPE,
+ FALSE otherwise. */
+static bool
+binding_to_template_parms_of_scope_p (cxx_binding *binding,
+ cxx_scope *scope)
+{
+ tree binding_value;
+
+ if (!binding || !scope)
+ return false;
+
+ binding_value = binding->value ? binding->value : binding->type;
+
+ return (scope
+ && scope->this_entity
+ && get_template_info (scope->this_entity)
+ && parameter_of_template_p (binding_value,
+ TI_TEMPLATE (get_template_info \
+ (scope->this_entity))));
+}
+
/* Return the innermost non-namespace binding for NAME from a scope
- containing BINDING, or, if BINDING is NULL, the current scope. If
- CLASS_P is false, then class bindings are ignored. */
+ containing BINDING, or, if BINDING is NULL, the current scope.
+ Please note that for a given template, the template parameters are
+ considered to be in the scope containing the current scope.
+ If CLASS_P is false, then class bindings are ignored. */
cxx_binding *
outer_binding (tree name,
@@ -3900,6 +3924,12 @@ outer_binding (tree name,
return class_binding;
}
}
+ /* If SCOPE is a template and if NAME binds to one of its template parameters
+ return the binding, otherwise we might miss it. */
+ if (outer_scope && outer_scope->kind == sk_template_parms
+ && binding_to_template_parms_of_scope_p (outer, scope))
+ return outer;
+
scope = scope->level_chain;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 67654df9d91..260229f15ad 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -251,6 +251,25 @@ finish_member_template_decl (tree decl)
return error_mark_node;
}
+/* Return the template info node corresponding to T, whatever T is. */
+
+tree
+get_template_info (tree t)
+{
+ tree tinfo = NULL_TREE;
+
+ if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
+ tinfo = DECL_TEMPLATE_INFO (t);
+
+ if (!tinfo && TREE_CODE (t) == TYPE_DECL)
+ t = TREE_TYPE (t);
+
+ if (TAGGED_TYPE_P (t))
+ tinfo = TYPE_TEMPLATE_INFO (t);
+
+ return tinfo;
+}
+
/* Returns the template nesting level of the indicated class TYPE.
For example, in:
@@ -5327,6 +5346,30 @@ outermost_tinst_level (void)
return tree_last (current_tinst_level);
}
+/* Returns TRUE if PARM is a parameter of the template TEMPL. */
+
+bool
+parameter_of_template_p (tree parm, tree templ)
+{
+ tree parms;
+ int i;
+
+ if (!parm || !templ)
+ return false;
+
+ gcc_assert (DECL_TEMPLATE_PARM_P (parm));
+ gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL);
+
+ parms = DECL_TEMPLATE_PARMS (templ);
+ parms = INNERMOST_TEMPLATE_PARMS (parms);
+
+ for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
+ if (parm == TREE_VALUE (TREE_VEC_ELT (parms, i)))
+ return true;
+
+ return false;
+}
+
/* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the
vector of template arguments, as for tsubst.
@@ -9274,9 +9317,12 @@ tsubst_copy_and_build (tree t,
qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
/*fn_p=*/NULL));
}
+ /* Pass true for koenig_p so that build_new_function_call will
+ allow hidden friends found by arg-dependent lookup at template
+ parsing time. */
return finish_call_expr (function, call_args,
/*disallow_virtual=*/qualified_p,
- koenig_p);
+ /*koenig_p*/true);
}
case COND_EXPR:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 268fbe0e151..fc8d3f5c080 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,18 @@
+2009-01-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/38850
+ * g++.dg/template/koenig6.C: New test.
+
+2009-01-12 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/36019
+ * g++.dg/lookup/hidden-class12.C: New test.
+ * g++.dg/lookup/hidden-class13.C: New test.
+ * g++.dg/lookup/hidden-class14.C: New test.
+ * g++.dg/lookup/hidden-class15.C: New test.
+ * g++.dg/lookup/hidden-class16.C: New test.
+ * gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C: Adjust testcase.
+
2008-12-05 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/union-5.c: Run only on x86 and x86-64.
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class12.C b/gcc/testsuite/g++.dg/lookup/hidden-class12.C
new file mode 100644
index 00000000000..4a3f2d7618b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class12.C
@@ -0,0 +1,24 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int x = 0;
+};
+
+struct A {
+ template <typename A>
+ static int f ()
+ {
+ return A::x;
+ }
+};
+
+
+int
+main ()
+{
+ int i = A::f<F> ();
+ return i;
+}
+
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class13.C b/gcc/testsuite/g++.dg/lookup/hidden-class13.C
new file mode 100644
index 00000000000..2f685b2cb36
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class13.C
@@ -0,0 +1,25 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int x = 0;
+};
+
+struct B {
+ template <typename B>
+ struct C
+ {
+ static int f ()
+ {
+ return B::x;
+ }
+ };
+};
+
+int
+main ()
+{
+ int j = B::C<F>::f ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class14.C b/gcc/testsuite/g++.dg/lookup/hidden-class14.C
new file mode 100644
index 00000000000..99bd6731b1b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class14.C
@@ -0,0 +1,23 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int x = 0;
+ typedef int A;
+};
+
+struct A {
+ template <typename A>
+ struct G : public F
+ {
+ static const A i = 0;
+ };
+};
+
+int
+main ()
+{
+ return A::G<F>::i ;
+}
+
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class15.C b/gcc/testsuite/g++.dg/lookup/hidden-class15.C
new file mode 100644
index 00000000000..b0ed660a6a3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class15.C
@@ -0,0 +1,30 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int y = 0;
+};
+
+struct A {
+ static const int x = 0;
+};
+
+struct B : public A {
+ template <typename A>
+ struct C
+ {
+ static int f ()
+ {
+ return A::x; // { dg-error "'x' is not a member of 'F'" }
+ }
+ };
+};
+
+int
+main ()
+{
+ int j = B::C<F>::f ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class16.C b/gcc/testsuite/g++.dg/lookup/hidden-class16.C
new file mode 100644
index 00000000000..25cc4029408
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class16.C
@@ -0,0 +1,27 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/36019
+// { dg-do compile }
+
+struct F {
+ static const int y = 0;
+};
+
+struct A {
+ static const int x = 0;
+};
+
+struct B : public A {
+ template <typename A>
+ static int f ()
+ {
+ return A::x; // { dg-error "'x' is not a member of 'F'" }
+ }
+};
+
+int
+main ()
+{
+ int j = B::f<F> ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/template/koenig6.C b/gcc/testsuite/g++.dg/template/koenig6.C
new file mode 100644
index 00000000000..8f93a653a7b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/koenig6.C
@@ -0,0 +1,29 @@
+// PR c++/38850
+
+template <typename VType>
+class Vector2 {
+ private:
+ VType c_[2];
+ public:
+ typedef Vector2<VType> Self;
+
+ Vector2(const VType x, const VType y) {
+ c_[0] = x;
+ c_[1] = y;
+ }
+
+ friend inline Self Max(const Self &v1, const Self &v2) {
+ return Self(v1.c_[0], v1.c_[1]);
+ }
+};
+
+template <class T>
+Vector2<float> foo(T x) {
+ Vector2<float> y(0,0);
+ return Max(y, y);
+}
+
+int main() {
+ foo(3);
+ return 0;
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C b/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C
index 73b99659e12..791850366df 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/tem03.C
@@ -83,7 +83,7 @@ public:
template <class T10, int i> struct Xfour {// { dg-error "" } .*
int T10; // { dg-error "" } .*
void f(){
- char T10;
+ char T10; // { dg-error "declaration of 'char T10'" }
}
};
@@ -126,8 +126,8 @@ public:
template <class T161>
friend bool foo(T161 u)
{
- Xseven<T161, 5, int> obj; // { dg-error "" } .*
- return (obj.inst == u.inst); // { dg-error "" } .*
+ Xseven<T161, 5, int> obj;
+ return (obj.inst == u.inst);
}
};