aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2001-01-18 09:56:46 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2001-01-18 09:56:46 +0000
commit028d1f20f7547f48b7370209d1e446398f2bb4b1 (patch)
tree4fedead3ac4c81c3a4b67bf00c1fdc7b53de0ca8 /gcc
parent9f724b6ae48e21f50e0b00461ba30b8c20b43d5a (diff)
downloadgcc-028d1f20f7547f48b7370209d1e446398f2bb4b1.zip
gcc-028d1f20f7547f48b7370209d1e446398f2bb4b1.tar.gz
gcc-028d1f20f7547f48b7370209d1e446398f2bb4b1.tar.bz2
pt.c (UNIFY_ALLOW_OUTER_LEVEL): New unify flag.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/pt.c47
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/unify8.C18
4 files changed, 56 insertions, 19 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 56b8483..8409ce3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
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.
2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1463dbe..747df21 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3064360..5579084 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
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.
2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
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
index 0000000..4e2f392
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/unify8.C
@@ -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
+}