Commit 081cebb2 by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/8572 (ICE with external definition of conversion operator to internal…

re PR c++/8572 (ICE with external definition of conversion operator to internal class within template class)

cp:
	PR c++/8572
	* cp-tree.h (grokoptypename): Add SCOPE parameter.
	* decl2.c (grokoptypename): Add SCOPE parameter. tsubst the type
	if in a template scope.
	* parse.y (unoperator): Return the scope.
	(operator_name): Adjust grokoptypename call.
testsuite:
	* g++.dg/parse/conv_op1.C: New test.

From-SVN: r60416
parent 96e13905
2002-12-22 Nathan Sidwell <nathan@codesourcery.com>
PR c++/8572
* cp-tree.h (grokoptypename): Add SCOPE parameter.
* decl2.c (grokoptypename): Add SCOPE parameter. tsubst the type
if in a template scope.
* parse.y (unoperator): Return the scope.
(operator_name): Adjust grokoptypename call.
2002-12-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> 2002-12-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
* cp-tree.h (make_unbound_class_template): Use tsubst_flags_t. * cp-tree.h (make_unbound_class_template): Use tsubst_flags_t.
......
...@@ -3806,7 +3806,7 @@ extern void check_member_template PARAMS ((tree)); ...@@ -3806,7 +3806,7 @@ extern void check_member_template PARAMS ((tree));
extern tree grokfield PARAMS ((tree, tree, tree, tree, tree)); extern tree grokfield PARAMS ((tree, tree, tree, tree, tree));
extern tree grokbitfield PARAMS ((tree, tree, tree)); extern tree grokbitfield PARAMS ((tree, tree, tree));
extern tree groktypefield PARAMS ((tree, tree)); extern tree groktypefield PARAMS ((tree, tree));
extern tree grokoptypename PARAMS ((tree, tree)); extern tree grokoptypename PARAMS ((tree, tree, tree));
extern void cplus_decl_attributes PARAMS ((tree *, tree, int)); extern void cplus_decl_attributes PARAMS ((tree *, tree, int));
extern tree constructor_name_full PARAMS ((tree)); extern tree constructor_name_full PARAMS ((tree));
extern tree constructor_name PARAMS ((tree)); extern tree constructor_name PARAMS ((tree));
......
...@@ -1120,11 +1120,29 @@ grokbitfield (declarator, declspecs, width) ...@@ -1120,11 +1120,29 @@ grokbitfield (declarator, declspecs, width)
return value; return value;
} }
/* Convert a conversion operator name to an identifier. SCOPE is the
scope of the conversion operator, if explicit. */
tree tree
grokoptypename (declspecs, declarator) grokoptypename (declspecs, declarator, scope)
tree declspecs, declarator; tree declspecs, declarator;
tree scope;
{ {
tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL); tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL);
/* Resolve any TYPENAME_TYPEs that refer to SCOPE, before mangling
the name, so that we mangle the right thing. */
if (scope && current_template_parms
&& uses_template_parms (t)
&& uses_template_parms (scope))
{
tree args = current_template_args ();
push_scope (scope);
t = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
pop_scope (scope);
}
return mangle_conv_op_name_for_type (t); return mangle_conv_op_name_for_type (t);
} }
......
...@@ -388,7 +388,7 @@ check_class_key (key, aggr) ...@@ -388,7 +388,7 @@ check_class_key (key, aggr)
%type <ttype> init initlist maybeasm maybe_init defarg defarg1 %type <ttype> init initlist maybeasm maybe_init defarg defarg1
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
%type <ttype> maybe_attribute attributes attribute attribute_list attrib %type <ttype> maybe_attribute attributes attribute attribute_list attrib
%type <ttype> any_word %type <ttype> any_word unoperator
%type <itype> save_lineno %type <itype> save_lineno
%type <ttype> simple_stmt simple_if %type <ttype> simple_stmt simple_if
...@@ -3914,6 +3914,7 @@ unoperator: ...@@ -3914,6 +3914,7 @@ unoperator:
got_object = TREE_VALUE (saved_scopes); got_object = TREE_VALUE (saved_scopes);
looking_for_typename = TREE_LANG_FLAG_0 (saved_scopes); looking_for_typename = TREE_LANG_FLAG_0 (saved_scopes);
saved_scopes = TREE_CHAIN (saved_scopes); saved_scopes = TREE_CHAIN (saved_scopes);
$$ = got_scope;
} }
; ;
...@@ -3985,7 +3986,7 @@ operator_name: ...@@ -3985,7 +3986,7 @@ operator_name:
| operator DELETE '[' ']' unoperator | operator DELETE '[' ']' unoperator
{ $$ = frob_opname (ansi_opname (VEC_DELETE_EXPR)); } { $$ = frob_opname (ansi_opname (VEC_DELETE_EXPR)); }
| operator type_specifier_seq conversion_declarator unoperator | operator type_specifier_seq conversion_declarator unoperator
{ $$ = frob_opname (grokoptypename ($2.t, $3)); } { $$ = frob_opname (grokoptypename ($2.t, $3, $4)); }
| operator error unoperator | operator error unoperator
{ $$ = frob_opname (ansi_opname (ERROR_MARK)); } { $$ = frob_opname (ansi_opname (ERROR_MARK)); }
; ;
......
2002-12-22 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/parse/conv_op1.C: New test.
2002-12-21 Josef Zlomek <zlomekj@suse.cz> 2002-12-21 Josef Zlomek <zlomekj@suse.cz>
* gcc.c-torture/compile/20021220-1.c: Removed until bug fix is * gcc.c-torture/compile/20021220-1.c: Removed until bug fix is
......
// { dg-do compile }
// Copyright (C) 2002 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 21 Dec 2002 <nathan@codesourcery.com>
// PR 8572. ICE with templated conversion operators.
template <typename T> struct A
{
struct B { };
operator B* () const;
B *Foo ();
};
template <typename T> typename A<T>::B *A<T>::Foo ()
{
return 0;
}
template <typename T> A<T>::operator typename A<T>::B* () const
{
return 0;
}
void Foo (A<int> &p)
{
p.Foo ();
static_cast <A<int>::B *> (p);
}
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