re PR c++/8572 (ICE with external definition of conversion operator to internal class...
authorNathan Sidwell <nathan@codesourcery.com>
Sun, 22 Dec 2002 21:32:28 +0000 (21:32 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Sun, 22 Dec 2002 21:32:28 +0000 (21:32 +0000)
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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/parse.y
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/conv_op1.C [new file with mode: 0644]

index af16d67138d77c1e2588264ff0dd3499258fb2a0..c268c106b1c69636a858046e6e117680ade0d7fc 100644 (file)
@@ -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.
index 0752bd025264351c00991c1c8ff573f2034d1b60..65f9df00b61a93b09a1a4226abdf87dfa41fd893 100644 (file)
@@ -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));
index f33ba8d211b2f3129e046ee4007f1360d85ed756..d305ee5813e52ab2c0cb267df238d1ff55ba3e16 100644 (file)
@@ -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);
 }
 
index 4f628412a9b87764660fd911b400179803710391..bdbee018e5ab9672137abbb4820de259d0cf43c5 100644 (file)
@@ -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)); }
        ;
index 6f316d38930bab4787ff0042f9b5e11db92d2934..db2e5f57900fbc6ed3ef30e7f3847a19d030a07a 100644 (file)
@@ -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 (file)
index 0000000..e892f01
--- /dev/null
@@ -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);
+}