Commit 0771d9d7 by Jason Merrill Committed by Jason Merrill

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
parent ceeb79a4
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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
}
......
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
......
// 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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment