OSDN Git Service

cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Jan 2001 09:19:33 +0000 (09:19 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Jan 2001 09:19:33 +0000 (09:19 +0000)
* pt.c (copy_default_args_to_explicit_spec): Preserve
object's CV quals. Reorganize.
testsuite:
* g++.old-deja/g++.pt/spec34.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39127 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.pt/spec34.C [new file with mode: 0644]

index fce2a4d..9a262f1 100644 (file)
@@ -1,3 +1,8 @@
+2001-01-19  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * pt.c (copy_default_args_to_explicit_spec): Preserve
+       object's CV quals. Reorganize.
+
 2001-01-18  Nathan Sidwell  <nathan@codesourcery.com>
 
        * typeck.c (build_modify_expr): Say `initialization' for
index 747df21..33c3f26 100644 (file)
@@ -1207,6 +1207,8 @@ copy_default_args_to_explicit_spec (decl)
   tree old_type;
   tree new_type;
   tree t;
+  tree object_type = NULL_TREE;
+  tree in_charge = NULL_TREE;
 
   /* See if there's anything we need to do.  */
   tmpl = DECL_TI_TEMPLATE (decl);
@@ -1220,40 +1222,43 @@ copy_default_args_to_explicit_spec (decl)
   old_type = TREE_TYPE (decl);
   spec_types = TYPE_ARG_TYPES (old_type);
   
-  /* DECL may contain more parameters than TMPL due to the extra
-     in-charge parameter in constructors and destructors.  */
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
     {
+      /* Remove the this pointer, but remember the object's type for
+         CV quals.  */
+      object_type = TREE_TYPE (TREE_VALUE (spec_types));
       spec_types = TREE_CHAIN (spec_types);
       tmpl_types = TREE_CHAIN (tmpl_types);
+      
       if (DECL_HAS_IN_CHARGE_PARM_P (decl))
-       spec_types = TREE_CHAIN (spec_types);
+        {
+          /* DECL may contain more parameters than TMPL due to the extra
+             in-charge parameter in constructors and destructors.  */
+          in_charge = spec_types;
+         spec_types = TREE_CHAIN (spec_types);
+       }
     }
 
   /* Compute the merged default arguments.  */
   new_spec_types = 
     copy_default_args_to_explicit_spec_1 (spec_types, tmpl_types);
 
-  /* Put the extra parameters back together -- but note that
-     build_cplus_method_type will automatically add the `this'
-     pointer.  */
-  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
-      && DECL_HAS_IN_CHARGE_PARM_P (decl))
+  /* Compute the new FUNCTION_TYPE.  */
+  if (object_type)
     {
-      tree t = TREE_CHAIN (TYPE_ARG_TYPES (old_type));
-      new_spec_types = hash_tree_cons (TREE_PURPOSE (t),
-                                      TREE_VALUE (t),
-                                      new_spec_types);
+      if (in_charge)
+        /* Put the in-charge parameter back.  */
+        new_spec_types = hash_tree_cons (TREE_PURPOSE (in_charge),
+                                        TREE_VALUE (in_charge),
+                                        new_spec_types);
+
+      new_type = build_cplus_method_type (object_type,
+                                         TREE_TYPE (old_type),
+                                         new_spec_types);
     }
-  
-  /* Compute the new FUNCTION_TYPE.  */
-  if (TREE_CODE (old_type) == METHOD_TYPE)
-    new_type = build_cplus_method_type (TYPE_METHOD_BASETYPE (old_type),
-                                       TREE_TYPE (old_type),
-                                       new_spec_types);
   else
     new_type = build_function_type (TREE_TYPE (old_type),
-                                 new_spec_types);
+                                   new_spec_types);
   new_type = build_type_attribute_variant (new_type,
                                           TYPE_ATTRIBUTES (old_type));
   new_type = build_exception_variant (new_type,
@@ -1500,7 +1505,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
       else if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR)
        {
          /* A friend declaration.  We can't do much, because we don't
-          know what this resolves to, yet.  */
+            know what this resolves to, yet.  */
          my_friendly_assert (is_friend != 0, 0);
          my_friendly_assert (!explicit_instantiation, 0);
          SET_DECL_IMPLICIT_INSTANTIATION (decl);
@@ -1641,7 +1646,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
              return tmpl;
            }
 
-         /* If we though that the DECL was a member function, but it
+         /* If we thought that the DECL was a member function, but it
             turns out to be specializing a static member function,
             make DECL a static member function as well.  */
          if (DECL_STATIC_FUNCTION_P (tmpl)
index 3669d46..4ff2124 100644 (file)
@@ -1,3 +1,7 @@
+2001-01-19  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.old-deja/g++.pt/spec34.C: New test.
+
 2001-01-19  "Billinghurst, David (CRTS)" <David.Billinghurst@riotinto.com>
 
        * g77.f-torture/compile/20000601-2.f: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec34.C b/gcc/testsuite/g++.old-deja/g++.pt/spec34.C
new file mode 100644 (file)
index 0000000..3f03dbe
--- /dev/null
@@ -0,0 +1,19 @@
+// Build don't link:
+
+// Copyright (C) 2000 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 17 Jan 2001 <nathan@codesourcery.com>
+
+// Bug 1632. In copying default args from a template to a specialization, we
+// lost the object's CV quals, leading to an utterly confusing error message.
+
+struct X;
+
+template <int dim> struct Y
+{
+  X *f (int i = 0) const;
+};
+
+template <> X *Y<2>::f (int i) const
+{
+  return f (i);
+}