mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-11 03:50:27 +08:00
re PR c++/48884 (decltype's operand doesn't consider friend declaration)
PR c++/48884 * 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. (push_deduction_access_scope, pop_defarg_context): New. (fn_type_unification): Use them. * name-lookup.c (lookup_name_real_1): Check current_class_type. From-SVN: r174139
This commit is contained in:
parent
78be79d534
commit
235fe6b449
@ -1,3 +1,14 @@
|
||||
2011-05-24 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/48884
|
||||
* 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.
|
||||
(push_deduction_access_scope, pop_defarg_context): New.
|
||||
(fn_type_unification): Use them.
|
||||
* name-lookup.c (lookup_name_real_1): Check current_class_type.
|
||||
|
||||
2011-05-24 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
* decl.c (grokdeclarator): Use current_class_name.
|
||||
|
@ -6082,6 +6082,9 @@ 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. */
|
||||
|
||||
@ -6090,8 +6093,6 @@ 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)
|
||||
{
|
||||
@ -6110,6 +6111,15 @@ 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)
|
||||
@ -6154,7 +6164,11 @@ invalidate_class_lookup_cache (void)
|
||||
void
|
||||
popclass (void)
|
||||
{
|
||||
poplevel_class ();
|
||||
if (current_class_type)
|
||||
poplevel_class ();
|
||||
else
|
||||
gcc_assert (current_class_depth
|
||||
&& current_class_stack[current_class_depth - 1].hidden);
|
||||
|
||||
current_class_depth--;
|
||||
current_class_name = current_class_stack[current_class_depth].name;
|
||||
|
@ -4469,7 +4469,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))
|
||||
if (IDENTIFIER_TYPENAME_P (name) && current_class_type)
|
||||
{
|
||||
struct cp_binding_level *level;
|
||||
|
||||
|
35
gcc/cp/pt.c
35
gcc/cp/pt.c
@ -212,7 +212,7 @@ push_access_scope (tree t)
|
||||
else if (DECL_CLASS_SCOPE_P (t))
|
||||
push_nested_class (DECL_CONTEXT (t));
|
||||
else
|
||||
push_to_top_level ();
|
||||
pushclass (NULL_TREE);
|
||||
|
||||
if (TREE_CODE (t) == FUNCTION_DECL)
|
||||
{
|
||||
@ -237,7 +237,7 @@ pop_access_scope (tree t)
|
||||
if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t))
|
||||
pop_nested_class ();
|
||||
else
|
||||
pop_from_top_level ();
|
||||
popclass ();
|
||||
}
|
||||
|
||||
/* Do any processing required when DECL (a member template
|
||||
@ -13820,6 +13820,30 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* We're going to do deduction substitution on the type of TMPL, a function
|
||||
template. In C++11 mode, push into that access scope. In C++03 mode,
|
||||
disable access checking. */
|
||||
|
||||
static void
|
||||
push_deduction_access_scope (tree tmpl)
|
||||
{
|
||||
if (cxx_dialect >= cxx0x)
|
||||
push_access_scope (DECL_TEMPLATE_RESULT (tmpl));
|
||||
else
|
||||
push_deferring_access_checks (dk_no_check);
|
||||
}
|
||||
|
||||
/* And pop back out. */
|
||||
|
||||
static void
|
||||
pop_deduction_access_scope (tree tmpl)
|
||||
{
|
||||
if (cxx_dialect >= cxx0x)
|
||||
pop_access_scope (DECL_TEMPLATE_RESULT (tmpl));
|
||||
else
|
||||
pop_deferring_access_checks ();
|
||||
}
|
||||
|
||||
/* The FN is a TEMPLATE_DECL for a function. ARGS is an array with
|
||||
NARGS elements of the arguments that are being used when calling
|
||||
it. TARGS is a vector into which the deduced template arguments
|
||||
@ -13958,7 +13982,9 @@ fn_type_unification (tree fn,
|
||||
incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
|
||||
|
||||
processing_template_decl += incomplete;
|
||||
push_deduction_access_scope (fn);
|
||||
fntype = deduction_tsubst_fntype (fn, converted_args);
|
||||
pop_deduction_access_scope (fn);
|
||||
processing_template_decl -= incomplete;
|
||||
|
||||
if (fntype == error_mark_node)
|
||||
@ -14029,7 +14055,10 @@ fn_type_unification (tree fn,
|
||||
substitution results in an invalid type, as described above,
|
||||
type deduction fails. */
|
||||
{
|
||||
tree substed = deduction_tsubst_fntype (fn, targs);
|
||||
tree substed;
|
||||
push_deduction_access_scope (fn);
|
||||
substed = deduction_tsubst_fntype (fn, targs);
|
||||
pop_deduction_access_scope (fn);
|
||||
if (substed == error_mark_node)
|
||||
return 1;
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-05-24 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/template/access21.C: New.
|
||||
* g++.dg/template/access22.C: New.
|
||||
|
||||
2011-05-24 Michael Matz <matz@gcc.gnu.org>
|
||||
|
||||
PR rtl-optimization/48633
|
||||
|
23
gcc/testsuite/g++.dg/template/access21.C
Normal file
23
gcc/testsuite/g++.dg/template/access21.C
Normal file
@ -0,0 +1,23 @@
|
||||
// PR c++/48884
|
||||
|
||||
class X
|
||||
{
|
||||
static const int I = 42;
|
||||
friend struct Y;
|
||||
};
|
||||
|
||||
template <int I> struct A { };
|
||||
|
||||
struct Y
|
||||
{
|
||||
template <typename T>
|
||||
static A<T::I> f(T t)
|
||||
{
|
||||
return A<T::I>();
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Y::f(X());
|
||||
}
|
15
gcc/testsuite/g++.dg/template/access22.C
Normal file
15
gcc/testsuite/g++.dg/template/access22.C
Normal file
@ -0,0 +1,15 @@
|
||||
template <int I> struct B { };
|
||||
|
||||
template <class T>
|
||||
B<T::I> f();
|
||||
|
||||
class A
|
||||
{
|
||||
static const int I = 42;
|
||||
template <class T> friend B<T::I> f();
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
f<A>();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user