diff options
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 20 | ||||
-rw-r--r-- | gcc/cp/parse.y | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/conv_op1.C | 30 |
6 files changed, 66 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index af16d67..c268c10 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +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> * cp-tree.h (make_unbound_class_template): Use tsubst_flags_t. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0752bd0..65f9df0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3806,7 +3806,7 @@ extern void check_member_template PARAMS ((tree)); extern tree grokfield PARAMS ((tree, tree, tree, tree, tree)); extern tree grokbitfield PARAMS ((tree, 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 tree constructor_name_full PARAMS ((tree)); extern tree constructor_name PARAMS ((tree)); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index f33ba8d..d305ee5 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1120,11 +1120,29 @@ grokbitfield (declarator, declspecs, width) return value; } +/* Convert a conversion operator name to an identifier. SCOPE is the + scope of the conversion operator, if explicit. */ + tree -grokoptypename (declspecs, declarator) +grokoptypename (declspecs, declarator, scope) tree declspecs, declarator; + tree scope; { 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); } diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 4f62841..bdbee01 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -388,7 +388,7 @@ check_class_key (key, aggr) %type <ttype> init initlist maybeasm maybe_init defarg defarg1 %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers %type <ttype> maybe_attribute attributes attribute attribute_list attrib -%type <ttype> any_word +%type <ttype> any_word unoperator %type <itype> save_lineno %type <ttype> simple_stmt simple_if @@ -3914,6 +3914,7 @@ unoperator: got_object = TREE_VALUE (saved_scopes); looking_for_typename = TREE_LANG_FLAG_0 (saved_scopes); saved_scopes = TREE_CHAIN (saved_scopes); + $$ = got_scope; } ; @@ -3985,7 +3986,7 @@ operator_name: | operator DELETE '[' ']' unoperator { $$ = frob_opname (ansi_opname (VEC_DELETE_EXPR)); } | operator type_specifier_seq conversion_declarator unoperator - { $$ = frob_opname (grokoptypename ($2.t, $3)); } + { $$ = frob_opname (grokoptypename ($2.t, $3, $4)); } | operator error unoperator { $$ = frob_opname (ansi_opname (ERROR_MARK)); } ; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6f316d3..db2e5f5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-12-22 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/parse/conv_op1.C: New test. + 2002-12-21 Josef Zlomek <zlomekj@suse.cz> * gcc.c-torture/compile/20021220-1.c: Removed until bug fix is diff --git a/gcc/testsuite/g++.dg/parse/conv_op1.C b/gcc/testsuite/g++.dg/parse/conv_op1.C new file mode 100644 index 0000000..e892f01 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/conv_op1.C @@ -0,0 +1,30 @@ + +// { 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); +} |