aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/class.c20
-rw-r--r--gcc/cp/name-lookup.c2
-rw-r--r--gcc/cp/pt.c12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/regress/regress4.C62
6 files changed, 92 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c5c83d0..b926ec9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2011-07-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/49663
+ * pt.c (push_deduction_access_scope): Preserve
+ processing_template_decl across push_to_top_level.
+ And revert:
+ * class.c (pushclass): Accept NULL argument.
+ (popclass): Deal with popping null class.
+ * pt.c (push_access_scope, pop_access_scope): Use them rather than
+ push_to_top_level/pop_from_top_level.
+ * name-lookup.c (lookup_name_real_1): Check current_class_type.
+
2011-07-07 Jakub Jelinek <jakub@redhat.com>
PR c/49644
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 6aefd68..7de104d 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6125,9 +6125,6 @@ restore_class_cache (void)
So that we may avoid calls to lookup_name, we cache the _TYPE
nodes of local TYPE_DECLs in the TREE_TYPE field of the name.
- For use by push_access_scope, we allow TYPE to be null to temporarily
- push out of class scope. This does not actually change binding levels.
-
For multiple inheritance, we perform a two-pass depth-first search
of the type lattice. */
@@ -6136,6 +6133,8 @@ pushclass (tree type)
{
class_stack_node_t csn;
+ type = TYPE_MAIN_VARIANT (type);
+
/* Make sure there is enough room for the new entry on the stack. */
if (current_class_depth + 1 >= current_class_stack_size)
{
@@ -6154,15 +6153,6 @@ pushclass (tree type)
csn->hidden = 0;
current_class_depth++;
- if (type == NULL_TREE)
- {
- current_class_name = current_class_type = NULL_TREE;
- csn->hidden = true;
- return;
- }
-
- type = TYPE_MAIN_VARIANT (type);
-
/* Now set up the new type. */
current_class_name = TYPE_NAME (type);
if (TREE_CODE (current_class_name) == TYPE_DECL)
@@ -6207,11 +6197,7 @@ invalidate_class_lookup_cache (void)
void
popclass (void)
{
- if (current_class_type)
- poplevel_class ();
- else
- gcc_assert (current_class_depth
- && current_class_stack[current_class_depth - 1].hidden);
+ poplevel_class ();
current_class_depth--;
current_class_name = current_class_stack[current_class_depth].name;
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 615e177..06726da 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4473,7 +4473,7 @@ lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p,
/* Conversion operators are handled specially because ordinary
unqualified name lookup will not find template conversion
operators. */
- if (IDENTIFIER_TYPENAME_P (name) && current_class_type)
+ if (IDENTIFIER_TYPENAME_P (name))
{
struct cp_binding_level *level;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 17ca44c..2c64dd4 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -214,7 +214,7 @@ push_access_scope (tree t)
else if (DECL_CLASS_SCOPE_P (t))
push_nested_class (DECL_CONTEXT (t));
else
- pushclass (NULL_TREE);
+ push_to_top_level ();
if (TREE_CODE (t) == FUNCTION_DECL)
{
@@ -239,7 +239,7 @@ pop_access_scope (tree t)
if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t))
pop_nested_class ();
else
- popclass ();
+ pop_from_top_level ();
}
/* Do any processing required when DECL (a member template
@@ -13843,7 +13843,13 @@ static void
push_deduction_access_scope (tree tmpl)
{
if (cxx_dialect >= cxx0x)
- push_access_scope (DECL_TEMPLATE_RESULT (tmpl));
+ {
+ int ptd = processing_template_decl;
+ push_access_scope (DECL_TEMPLATE_RESULT (tmpl));
+ /* Preserve processing_template_decl across push_to_top_level. */
+ if (ptd && !processing_template_decl)
+ ++processing_template_decl;
+ }
else
push_deferring_access_checks (dk_no_check);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c57cb97..6e17a55 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-07-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/49663
+ * g++.dg/cpp0x/regress/regress4.C: New.
+
2011-07-07 Mikael Morin <mikael.morin@sfr.fr>
PR fortran/49648
diff --git a/gcc/testsuite/g++.dg/cpp0x/regress/regress4.C b/gcc/testsuite/g++.dg/cpp0x/regress/regress4.C
new file mode 100644
index 0000000..b56263a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/regress/regress4.C
@@ -0,0 +1,62 @@
+// PR c++/49663
+// { dg-options -std=c++0x }
+
+struct Nosm
+{
+ int m_R;
+};
+
+namespace dx {
+
+ struct onc
+ {
+ typedef void(*Cb)();
+
+ onc(Cb cb);
+ };
+
+ struct grac
+ {
+ template<class Derived> static void once();
+ };
+
+ template<class Derived>
+ struct tonc : onc
+ {
+ tonc() : onc(&grac::once<Derived>) {}
+
+ static Derived& get();
+ };
+
+ template<class Derived> void grac::once()
+ {
+ tonc<Derived>::get().h();
+ }
+}
+
+namespace
+{
+ template<typename T, int = sizeof(&T::m_R)>
+ struct has_R { };
+
+ template<typename T>
+ inline void
+ setR(T* m, has_R<T>* = 0)
+ { }
+
+ inline void setR(...) { }
+}
+
+template<typename M>
+ struct Qmi
+ : dx::tonc<Qmi<M> >
+ {
+ void h()
+ {
+ setR(&msg);
+ }
+
+ M msg;
+ };
+
+Qmi<Nosm> x;