Commit 028d1f20 by Nathan Sidwell Committed by Nathan Sidwell

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
parent 9f724b6a
2001-01-18 Nathan Sidwell <nathan@codesourcery.com> 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. * decl.c (finish_destructor_body): Convert to vbase pointer here.
2001-01-18 Nathan Sidwell <nathan@codesourcery.com> 2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
......
...@@ -86,6 +86,7 @@ static htab_t local_specializations; ...@@ -86,6 +86,7 @@ static htab_t local_specializations;
#define UNIFY_ALLOW_LESS_CV_QUAL 2 #define UNIFY_ALLOW_LESS_CV_QUAL 2
#define UNIFY_ALLOW_DERIVED 4 #define UNIFY_ALLOW_DERIVED 4
#define UNIFY_ALLOW_INTEGER 8 #define UNIFY_ALLOW_INTEGER 8
#define UNIFY_ALLOW_OUTER_LEVEL 16
#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is #define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
virtual, or a base class of a virtual virtual, or a base class of a virtual
...@@ -7874,7 +7875,8 @@ type_unification_real (tparms, targs, parms, args, subr, ...@@ -7874,7 +7875,8 @@ type_unification_real (tparms, targs, parms, args, subr,
switch (strict) switch (strict)
{ {
case DEDUCE_CALL: 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; break;
case DEDUCE_CONV: case DEDUCE_CONV:
...@@ -8413,7 +8415,8 @@ check_cv_quals_for_unify (strict, arg, parm) ...@@ -8413,7 +8415,8 @@ check_cv_quals_for_unify (strict, arg, parm)
UNIFY_ALLOW_NONE: UNIFY_ALLOW_NONE:
Require an exact match between PARM and ARG. Require an exact match between PARM and ARG.
UNIFY_ALLOW_MORE_CV_QUAL: 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: UNIFY_ALLOW_LESS_CV_QUAL:
Allow the deduced ARG to be less cv-qualified than ARG. Allow the deduced ARG to be less cv-qualified than ARG.
UNIFY_ALLOW_DERIVED: UNIFY_ALLOW_DERIVED:
...@@ -8422,7 +8425,14 @@ check_cv_quals_for_unify (strict, arg, parm) ...@@ -8422,7 +8425,14 @@ check_cv_quals_for_unify (strict, arg, parm)
ARG. ARG.
UNIFY_ALLOW_INTEGER: UNIFY_ALLOW_INTEGER:
Allow any integral type to be deduced. See the TEMPLATE_PARM_INDEX 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 static int
unify (tparms, targs, parm, arg, strict) unify (tparms, targs, parm, arg, strict)
...@@ -8432,6 +8442,7 @@ unify (tparms, targs, parm, arg, strict) ...@@ -8432,6 +8442,7 @@ unify (tparms, targs, parm, arg, strict)
int idx; int idx;
tree targ; tree targ;
tree tparm; tree tparm;
int strict_in = strict;
/* I don't think this will do the right thing with respect to types. /* 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 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) ...@@ -8463,9 +8474,15 @@ unify (tparms, targs, parm, arg, strict)
PARM `T' for example, when computing which of two templates PARM `T' for example, when computing which of two templates
is more specialized, for example. */ is more specialized, for example. */
&& TREE_CODE (arg) != TEMPLATE_TYPE_PARM && 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; 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)) switch (TREE_CODE (parm))
{ {
case TYPENAME_TYPE: case TYPENAME_TYPE:
...@@ -8560,7 +8577,7 @@ unify (tparms, targs, parm, arg, strict) ...@@ -8560,7 +8577,7 @@ unify (tparms, targs, parm, arg, strict)
a match unless we are allowing additional qualification. a match unless we are allowing additional qualification.
If ARG is `const int' and PARM is just `T' that's OK; If ARG is `const int' and PARM is just `T' that's OK;
that binds `const int' to `T'. */ 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)) arg, parm))
return 1; return 1;
...@@ -8645,8 +8662,6 @@ unify (tparms, targs, parm, arg, strict) ...@@ -8645,8 +8662,6 @@ unify (tparms, targs, parm, arg, strict)
case POINTER_TYPE: case POINTER_TYPE:
{ {
int sub_strict;
if (TREE_CODE (arg) != POINTER_TYPE) if (TREE_CODE (arg) != POINTER_TYPE)
return 1; return 1;
...@@ -8658,28 +8673,22 @@ unify (tparms, targs, parm, arg, strict) ...@@ -8658,28 +8673,22 @@ unify (tparms, targs, parm, arg, strict)
We pass down STRICT here rather than UNIFY_ALLOW_NONE. We pass down STRICT here rather than UNIFY_ALLOW_NONE.
This will allow for additional cv-qualification of the This will allow for additional cv-qualification of the
pointed-to types if appropriate. In general, this is a bit pointed-to types if appropriate. */
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;
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 /* The derived-to-base conversion only persists through one
level of pointers. */ level of pointers. */
sub_strict &= ~UNIFY_ALLOW_DERIVED; strict |= (strict_in & UNIFY_ALLOW_DERIVED);
return unify (tparms, targs, TREE_TYPE (parm), return unify (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), sub_strict); TREE_TYPE (arg), strict);
} }
case REFERENCE_TYPE: case REFERENCE_TYPE:
if (TREE_CODE (arg) != REFERENCE_TYPE) if (TREE_CODE (arg) != REFERENCE_TYPE)
return 1; return 1;
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
UNIFY_ALLOW_NONE); strict & UNIFY_ALLOW_MORE_CV_QUAL);
case ARRAY_TYPE: case ARRAY_TYPE:
if (TREE_CODE (arg) != ARRAY_TYPE) if (TREE_CODE (arg) != ARRAY_TYPE)
...@@ -8769,7 +8778,7 @@ unify (tparms, targs, parm, arg, strict) ...@@ -8769,7 +8778,7 @@ unify (tparms, targs, parm, arg, strict)
{ {
tree t = NULL_TREE; 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. */ /* First, we try to unify the PARM and ARG directly. */
t = try_class_unification (tparms, targs, t = try_class_unification (tparms, targs,
......
2001-01-18 Nathan Sidwell <nathan@codesourcery.com> 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. * g++.old-deja/g++.abi/vbase1.C: New test.
2001-01-18 Nathan Sidwell <nathan@codesourcery.com> 2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
......
// 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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment