pt.c (UNIFY_ALLOW_OUTER_LEVEL): New unify flag.
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 18 Jan 2001 09:56:46 +0000 (09:56 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 18 Jan 2001 09:56:46 +0000 (09:56 +0000)
cp:
* pt.c (UNIFY_ALLOW_OUTER_LEVEL): New unify flag.
(type_unification_real): Set it.
(unify): Use it.
testsuite:
* g++.old-deja/g++.pt/unify8.C: New test.

From-SVN: r39115

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

index 56b84835a42ea8e578a590c62b337b0a1fd1762a..8409ce3eb6be8009c6a49aad484b586c6280bcc2 100644 (file)
@@ -1,3 +1,9 @@
+2001-01-18  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * pt.c (UNIFY_ALLOW_OUTER_LEVEL): New unify flag.
+       (type_unification_real): Set it.
+       (unify): Use it.
+
 2001-01-18  Nathan Sidwell  <nathan@codesourcery.com>
 
        * decl.c (finish_destructor_body): Convert to vbase pointer here.
index 1463dbeff1a0f1f51d2060145d1072fb93fb5fcb..747df21ef674cd25b1328ed18421f5910f70252f 100644 (file)
@@ -86,6 +86,7 @@ static htab_t local_specializations;
 #define UNIFY_ALLOW_LESS_CV_QUAL 2
 #define UNIFY_ALLOW_DERIVED 4
 #define UNIFY_ALLOW_INTEGER 8
+#define UNIFY_ALLOW_OUTER_LEVEL 16
 
 #define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
                             virtual, or a base class of a virtual
@@ -7874,7 +7875,8 @@ type_unification_real (tparms, targs, parms, args, subr,
   switch (strict)
     {
     case DEDUCE_CALL:
-      sub_strict = UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_DERIVED;
+      sub_strict = (UNIFY_ALLOW_OUTER_LEVEL | UNIFY_ALLOW_MORE_CV_QUAL
+                    | UNIFY_ALLOW_DERIVED);
       break;
       
     case DEDUCE_CONV:
@@ -8413,7 +8415,8 @@ check_cv_quals_for_unify (strict, arg, parm)
      UNIFY_ALLOW_NONE:
        Require an exact match between PARM and ARG.
      UNIFY_ALLOW_MORE_CV_QUAL:
-       Allow the deduced ARG to be more cv-qualified than ARG.
+       Allow the deduced ARG to be more cv-qualified (by qualification
+       conversion) than ARG.
      UNIFY_ALLOW_LESS_CV_QUAL:
        Allow the deduced ARG to be less cv-qualified than ARG.
      UNIFY_ALLOW_DERIVED:
@@ -8422,7 +8425,14 @@ check_cv_quals_for_unify (strict, arg, parm)
        ARG.
      UNIFY_ALLOW_INTEGER:
        Allow any integral type to be deduced.  See the TEMPLATE_PARM_INDEX
-       case for more information.  */
+       case for more information. 
+     UNIFY_ALLOW_OUTER_LEVEL:
+       This is the outermost level of a deduction. Used to determine validity
+       of qualification conversions. A valid qualification conversion must
+       have const qualified pointers leading up to the inner type which
+       requires additional CV quals, except at the outer level, where const
+       is not required [conv.qual]. It would be normal to set this flag in
+       addition to setting UNIFY_ALLOW_MORE_CV_QUAL.  */
 
 static int
 unify (tparms, targs, parm, arg, strict)
@@ -8432,6 +8442,7 @@ unify (tparms, targs, parm, arg, strict)
   int idx;
   tree targ;
   tree tparm;
+  int strict_in = strict;
 
   /* I don't think this will do the right thing with respect to types.
      But the only case I've seen it in so far has been array bounds, where
@@ -8463,9 +8474,15 @@ unify (tparms, targs, parm, arg, strict)
         PARM `T' for example, when computing which of two templates
         is more specialized, for example.  */
       && TREE_CODE (arg) != TEMPLATE_TYPE_PARM
-      && !check_cv_quals_for_unify (strict, arg, parm))
+      && !check_cv_quals_for_unify (strict_in, arg, parm))
     return 1;
 
+  if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
+      && TYPE_P (arg) && !CP_TYPE_CONST_P (arg))
+    strict &= ~UNIFY_ALLOW_MORE_CV_QUAL;
+  strict &= ~UNIFY_ALLOW_OUTER_LEVEL;
+  strict &= ~UNIFY_ALLOW_DERIVED;
+  
   switch (TREE_CODE (parm))
     {
     case TYPENAME_TYPE:
@@ -8560,7 +8577,7 @@ unify (tparms, targs, parm, arg, strict)
             a match unless we are allowing additional qualification.
             If ARG is `const int' and PARM is just `T' that's OK;
             that binds `const int' to `T'.  */
-         if (!check_cv_quals_for_unify (strict | UNIFY_ALLOW_LESS_CV_QUAL, 
+         if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL, 
                                         arg, parm))
            return 1;
 
@@ -8645,8 +8662,6 @@ unify (tparms, targs, parm, arg, strict)
 
     case POINTER_TYPE:
       {
-       int sub_strict;
-
        if (TREE_CODE (arg) != POINTER_TYPE)
          return 1;
        
@@ -8658,28 +8673,22 @@ unify (tparms, targs, parm, arg, strict)
 
           We pass down STRICT here rather than UNIFY_ALLOW_NONE.
           This will allow for additional cv-qualification of the
-          pointed-to types if appropriate.  In general, this is a bit
-          too generous; we are only supposed to allow qualification
-          conversions and this method will allow an ARG of char** and
-          a deduced ARG of const char**.  However, overload
-          resolution will subsequently invalidate the candidate, so
-          this is probably OK.  */
-       sub_strict = strict;
+          pointed-to types if appropriate.  */
        
-       if (TREE_CODE (TREE_TYPE (arg)) != RECORD_TYPE)
+       if (TREE_CODE (TREE_TYPE (arg)) == RECORD_TYPE)
          /* The derived-to-base conversion only persists through one
             level of pointers.  */
-         sub_strict &= ~UNIFY_ALLOW_DERIVED;
+         strict |= (strict_in & UNIFY_ALLOW_DERIVED);
 
        return unify (tparms, targs, TREE_TYPE (parm), 
-                     TREE_TYPE (arg), sub_strict);
+                     TREE_TYPE (arg), strict);
       }
 
     case REFERENCE_TYPE:
       if (TREE_CODE (arg) != REFERENCE_TYPE)
        return 1;
       return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
-                   UNIFY_ALLOW_NONE);
+                   strict & UNIFY_ALLOW_MORE_CV_QUAL);
 
     case ARRAY_TYPE:
       if (TREE_CODE (arg) != ARRAY_TYPE)
@@ -8769,7 +8778,7 @@ unify (tparms, targs, parm, arg, strict)
        {
          tree t = NULL_TREE;
 
-         if (strict & UNIFY_ALLOW_DERIVED)
+         if (strict_in & UNIFY_ALLOW_DERIVED)
            {
              /* First, we try to unify the PARM and ARG directly.  */
              t = try_class_unification (tparms, targs,
index 30643601bffd5a8370a0132fe7213705b62dafc2..55790841cb5598b864c7034de2a25bd05273bfae 100644 (file)
@@ -1,3 +1,7 @@
+2001-01-18  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.old-deja/g++.pt/unify8.C: New test.
+
 2001-01-18  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.old-deja/g++.abi/vbase1.C: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/unify8.C b/gcc/testsuite/g++.old-deja/g++.pt/unify8.C
new file mode 100644 (file)
index 0000000..4e2f392
--- /dev/null
@@ -0,0 +1,18 @@
+// Build don't link:
+
+// Copyright (C) 2000 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 12 Jan 2001 <nathan@codesourcery.com>
+
+// Bug 1630. Template deduction at a call allowed conversions more lenient than
+// qualification conversions. That would lead to misleading diagnostics during
+// overload resolution.
+
+
+template <typename T> void Foo (T const **);
+void Foo (int);       // ERROR - candidate
+void Foo (float);     // ERROR - candidate
+
+void baz (int **p1)
+{
+  Foo (p1);   // ERROR - no such function
+}