From 0771d9d750576cd36a710a1a99cdd4163efa0164 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 7 Jul 2011 17:53:58 -0400 Subject: [PATCH] re PR c++/49663 ([C++0x] ICE in lookup_base) 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. From-SVN: r176013 --- gcc/cp/ChangeLog | 12 ++++ gcc/cp/class.c | 20 +----- gcc/cp/name-lookup.c | 2 +- gcc/cp/pt.c | 12 +++- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/cpp0x/regress/regress4.C | 62 +++++++++++++++++++ 6 files changed, 92 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/regress/regress4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c5c83d035ae..b926ec947a2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2011-07-07 Jason Merrill + + 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 PR c/49644 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 6aefd684075..7de104d4bc7 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 615e177e1f1..06726da74ea 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 17ca44cde0d..2c64dd4a4c6 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 c57cb97105f..6e17a559e24 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-07-06 Jason Merrill + + PR c++/49663 + * g++.dg/cpp0x/regress/regress4.C: New. + 2011-07-07 Mikael Morin 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 00000000000..b56263ae5ae --- /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 static void once(); + }; + + template + struct tonc : onc + { + tonc() : onc(&grac::once) {} + + static Derived& get(); + }; + + template void grac::once() + { + tonc::get().h(); + } +} + +namespace +{ + template + struct has_R { }; + + template + inline void + setR(T* m, has_R* = 0) + { } + + inline void setR(...) { } +} + +template + struct Qmi + : dx::tonc > + { + void h() + { + setR(&msg); + } + + M msg; + }; + +Qmi x; -- 2.30.2