Commit c888c93b by Mark Mitchell Committed by Mark Mitchell

re PR c++/25836 (G++ does not allow a conversion of templated types)

	PR c++/25836
	* cp-tree.h (push_class_stack): New function.
	(pop_class_stack): Likewise.
	* class.c (class_stack_node): Add hidden field.
	(pushclass): Clear it.
	(push_class_stack): New function.
	(pop_class_stack): Likewise.
	(currently_open_class): Ignore hidden classes.
	(currently_open_derived_class): Likewise.
	* name-lookup.c (push_to_top_level): Call push_class_stack.
	(pop_from_top_level): Call pop_class_stack.
	PR c++/25836
	* g++.dg/template/init6.C: New test.

From-SVN: r109945
parent e79b9d54
2006-01-18 Mark Mitchell <mark@codesourcery.com>
PR c++/25836
* cp-tree.h (push_class_stack): New function.
(pop_class_stack): Likewise.
* class.c (class_stack_node): Add hidden field.
(pushclass): Clear it.
(push_class_stack): New function.
(pop_class_stack): Likewise.
(currently_open_class): Ignore hidden classes.
(currently_open_derived_class): Likewise.
* name-lookup.c (push_to_top_level): Call push_class_stack.
(pop_from_top_level): Call pop_class_stack.
2006-01-18 Kazu Hirata <kazu@codesourcery.com> 2006-01-18 Kazu Hirata <kazu@codesourcery.com>
* tree.c (find_tree_t, find_tree): Remove. * tree.c (find_tree_t, find_tree): Remove.
......
...@@ -60,6 +60,10 @@ typedef struct class_stack_node { ...@@ -60,6 +60,10 @@ typedef struct class_stack_node {
/* If were defining TYPE, the names used in this class. */ /* If were defining TYPE, the names used in this class. */
splay_tree names_used; splay_tree names_used;
/* Nonzero if this class is no longer open, because of a call to
push_to_top_level. */
size_t hidden;
}* class_stack_node_t; }* class_stack_node_t;
typedef struct vtbl_init_data_s typedef struct vtbl_init_data_s
...@@ -5387,6 +5391,8 @@ restore_class_cache (void) ...@@ -5387,6 +5391,8 @@ restore_class_cache (void)
void void
pushclass (tree type) pushclass (tree type)
{ {
class_stack_node_t csn;
type = TYPE_MAIN_VARIANT (type); type = TYPE_MAIN_VARIANT (type);
/* Make sure there is enough room for the new entry on the stack. */ /* Make sure there is enough room for the new entry on the stack. */
...@@ -5399,10 +5405,12 @@ pushclass (tree type) ...@@ -5399,10 +5405,12 @@ pushclass (tree type)
} }
/* Insert a new entry on the class stack. */ /* Insert a new entry on the class stack. */
current_class_stack[current_class_depth].name = current_class_name; csn = current_class_stack + current_class_depth;
current_class_stack[current_class_depth].type = current_class_type; csn->name = current_class_name;
current_class_stack[current_class_depth].access = current_access_specifier; csn->type = current_class_type;
current_class_stack[current_class_depth].names_used = 0; csn->access = current_access_specifier;
csn->names_used = 0;
csn->hidden = 0;
current_class_depth++; current_class_depth++;
/* Now set up the new type. */ /* Now set up the new type. */
...@@ -5459,6 +5467,24 @@ popclass (void) ...@@ -5459,6 +5467,24 @@ popclass (void)
splay_tree_delete (current_class_stack[current_class_depth].names_used); splay_tree_delete (current_class_stack[current_class_depth].names_used);
} }
/* Mark the top of the class stack as hidden. */
void
push_class_stack (void)
{
if (current_class_depth)
++current_class_stack[current_class_depth - 1].hidden;
}
/* Mark the top of the class stack as un-hidden. */
void
pop_class_stack (void)
{
if (current_class_depth)
--current_class_stack[current_class_depth - 1].hidden;
}
/* Returns 1 if current_class_type is either T or a nested type of T. /* Returns 1 if current_class_type is either T or a nested type of T.
We start looking from 1 because entry 0 is from global scope, and has We start looking from 1 because entry 0 is from global scope, and has
no type. */ no type. */
...@@ -5469,10 +5495,14 @@ currently_open_class (tree t) ...@@ -5469,10 +5495,14 @@ currently_open_class (tree t)
int i; int i;
if (current_class_type && same_type_p (t, current_class_type)) if (current_class_type && same_type_p (t, current_class_type))
return 1; return 1;
for (i = 1; i < current_class_depth; ++i) for (i = current_class_depth - 1; i > 0; --i)
if (current_class_stack[i].type {
&& same_type_p (current_class_stack [i].type, t)) if (current_class_stack[i].hidden)
return 1; break;
if (current_class_stack[i].type
&& same_type_p (current_class_stack [i].type, t))
return 1;
}
return 0; return 0;
} }
...@@ -5496,8 +5526,12 @@ currently_open_derived_class (tree t) ...@@ -5496,8 +5526,12 @@ currently_open_derived_class (tree t)
return current_class_type; return current_class_type;
for (i = current_class_depth - 1; i > 0; --i) for (i = current_class_depth - 1; i > 0; --i)
if (DERIVED_FROM_P (t, current_class_stack[i].type)) {
return current_class_stack[i].type; if (current_class_stack[i].hidden)
break;
if (DERIVED_FROM_P (t, current_class_stack[i].type))
return current_class_stack[i].type;
}
return NULL_TREE; return NULL_TREE;
} }
......
...@@ -3748,6 +3748,8 @@ extern tree cp_fold_obj_type_ref (tree, tree); ...@@ -3748,6 +3748,8 @@ extern tree cp_fold_obj_type_ref (tree, tree);
extern void set_linkage_according_to_type (tree, tree); extern void set_linkage_according_to_type (tree, tree);
extern void determine_key_method (tree); extern void determine_key_method (tree);
extern void check_for_override (tree, tree); extern void check_for_override (tree, tree);
extern void push_class_stack (void);
extern void pop_class_stack (void);
/* in cvt.c */ /* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree); extern tree convert_to_reference (tree, tree, int, int, tree);
......
...@@ -4938,6 +4938,7 @@ push_to_top_level (void) ...@@ -4938,6 +4938,7 @@ push_to_top_level (void)
current_lang_base = VEC_alloc (tree, gc, 10); current_lang_base = VEC_alloc (tree, gc, 10);
current_lang_name = lang_name_cplusplus; current_lang_name = lang_name_cplusplus;
current_namespace = global_namespace; current_namespace = global_namespace;
push_class_stack ();
skip_evaluation = 0; skip_evaluation = 0;
timevar_pop (TV_NAME_LOOKUP); timevar_pop (TV_NAME_LOOKUP);
} }
...@@ -4953,6 +4954,7 @@ pop_from_top_level (void) ...@@ -4953,6 +4954,7 @@ pop_from_top_level (void)
/* Clear out class-level bindings cache. */ /* Clear out class-level bindings cache. */
if (previous_class_level) if (previous_class_level)
invalidate_class_lookup_cache (); invalidate_class_lookup_cache ();
pop_class_stack ();
current_lang_base = 0; current_lang_base = 0;
......
2006-01-18 Mark Mitchell <mark@codesourcery.com>
PR c++/25836
* g++.dg/template/init6.C: New test.
2006-01-18 Daniel Berlin <dberlin@dberlin.org> 2006-01-18 Daniel Berlin <dberlin@dberlin.org>
* gcc.dg/tree-ssa/pr24287.c: New test * gcc.dg/tree-ssa/pr24287.c: New test
// PR c++/25836
template <class T>
class Iter {};
template <class T>
class SubIter : public Iter<T> {
void insert(T);
};
class GraphBase {
public:
class Node;
};
template<class T>
class Graph : public GraphBase {
class Inner {
Iter<typename Graph<T>::Node*> *get();
};
};
template<class T>
Iter<typename Graph<T>::Node*> *Graph<T>::Inner::get() {
SubIter<typename Graph<T>::Node*> *iter;
iter->insert(0);
}
int main() {
Iter<Graph<int>::Node*> *n2_iter = new SubIter<Graph<int>::Node*>();
}
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