ir.texi: Correct typo.
* ir.texi: Correct typo. * mangle.c (write_expression): Handle non-type template arguments with reference type. * method.c (build_overload_value): Likewise. * pt.c (convert_nontype_argument): Explicitly represent conversion to a reference with an ADDR_EXPR. (unify): Always unify arguments in left-to-right order. From-SVN: r34396
This commit is contained in:
parent
f557989836
commit
0dc09a613b
7 changed files with 63 additions and 13 deletions
|
@ -1,3 +1,13 @@
|
|||
2000-06-04 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* ir.texi: Correct typo.
|
||||
* mangle.c (write_expression): Handle non-type template arguments
|
||||
with reference type.
|
||||
* method.c (build_overload_value): Likewise.
|
||||
* pt.c (convert_nontype_argument): Explicitly represent conversion
|
||||
to a reference with an ADDR_EXPR.
|
||||
(unify): Always unify arguments in left-to-right order.
|
||||
|
||||
2000-06-03 Alex Samuel <samuel@codesourcery.com>
|
||||
Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
|
|
|
@ -1675,7 +1675,7 @@ that of the result, will be either integral, boolean, or floating-point.
|
|||
|
||||
@item ADDR_EXPR
|
||||
These nodes are used to represent the address of an object. (These
|
||||
expression will always have pointer or reference type.) The operand may
|
||||
expressions will always have pointer or reference type.) The operand may
|
||||
be another expression, or it may be a declaration.
|
||||
|
||||
As an extension, G++ allows users to take the address of a label. In
|
||||
|
|
|
@ -1557,6 +1557,15 @@ write_expression (expr)
|
|||
code = TREE_CODE (expr);
|
||||
}
|
||||
|
||||
/* When we bind a variable or function to a non-type template
|
||||
argument with reference type, we create an ADDR_EXPR to show
|
||||
the fact that the entity's address has been taken. But, we
|
||||
don't actually want to output a mangling code for the `&'. */
|
||||
if (TREE_CODE (expr) == ADDR_EXPR
|
||||
&& TREE_TYPE (expr)
|
||||
&& TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE)
|
||||
expr = TREE_OPERAND (expr, 0);
|
||||
|
||||
/* If it wasn't any of those, recursively expand the expression. */
|
||||
write_string (operator_name_info[(int) code].mangled_name);
|
||||
|
||||
|
|
|
@ -827,6 +827,9 @@ build_overload_value (type, value, flags)
|
|||
/* Fall through. */
|
||||
|
||||
case REFERENCE_TYPE:
|
||||
if (TREE_CODE (value) == ADDR_EXPR)
|
||||
value = TREE_OPERAND (value, 0);
|
||||
|
||||
if (TREE_CODE (value) == VAR_DECL)
|
||||
{
|
||||
my_friendly_assert (DECL_NAME (value) != 0, 245);
|
||||
|
|
34
gcc/cp/pt.c
34
gcc/cp/pt.c
|
@ -2762,8 +2762,9 @@ convert_nontype_argument (type, expr)
|
|||
tree e = expr;
|
||||
STRIP_NOPS (e);
|
||||
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE
|
||||
|| TREE_CODE (expr_type) == ARRAY_TYPE)
|
||||
if (TREE_CODE (expr_type) == ARRAY_TYPE
|
||||
|| (TREE_CODE (type) == REFERENCE_TYPE
|
||||
&& TREE_CODE (e) != ADDR_EXPR))
|
||||
referent = e;
|
||||
else
|
||||
{
|
||||
|
@ -2950,6 +2951,15 @@ convert_nontype_argument (type, expr)
|
|||
{
|
||||
tree type_referred_to = TREE_TYPE (type);
|
||||
|
||||
/* If this expression already has reference type, get the
|
||||
underling object. */
|
||||
if (TREE_CODE (expr_type) == REFERENCE_TYPE)
|
||||
{
|
||||
my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
|
||||
expr = TREE_OPERAND (expr, 0);
|
||||
expr_type = TREE_TYPE (expr);
|
||||
}
|
||||
|
||||
if (TREE_CODE (type_referred_to) == FUNCTION_TYPE)
|
||||
{
|
||||
/* For a non-type template-parameter of type reference to
|
||||
|
@ -2957,17 +2967,16 @@ convert_nontype_argument (type, expr)
|
|||
template-argument represents a set of overloaded
|
||||
functions, the matching function is selected from the
|
||||
set (_over.over_). */
|
||||
tree fns = expr;
|
||||
tree fn;
|
||||
|
||||
fn = instantiate_type (type_referred_to, fns, 0);
|
||||
fn = instantiate_type (type_referred_to, expr, 0);
|
||||
|
||||
if (fn == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (!TREE_PUBLIC (fn))
|
||||
{
|
||||
if (really_overloaded_fn (fns))
|
||||
if (really_overloaded_fn (expr))
|
||||
/* Don't issue an error here; we might get a different
|
||||
function if the overloading had worked out
|
||||
differently. */
|
||||
|
@ -2980,7 +2989,7 @@ convert_nontype_argument (type, expr)
|
|||
TREE_TYPE (fn)),
|
||||
0);
|
||||
|
||||
return fn;
|
||||
expr = fn;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2990,15 +2999,16 @@ convert_nontype_argument (type, expr)
|
|||
identical) type of the template-argument. The
|
||||
template-parameter is bound directly to the
|
||||
template-argument, which must be an lvalue. */
|
||||
if ((TYPE_MAIN_VARIANT (expr_type)
|
||||
!= TYPE_MAIN_VARIANT (type_referred_to))
|
||||
if (!same_type_p (TYPE_MAIN_VARIANT (expr_type),
|
||||
TYPE_MAIN_VARIANT (type_referred_to))
|
||||
|| !at_least_as_qualified_p (type_referred_to,
|
||||
expr_type)
|
||||
|| !real_lvalue_p (expr))
|
||||
return error_mark_node;
|
||||
else
|
||||
return expr;
|
||||
expr = error_mark_node;
|
||||
}
|
||||
|
||||
mark_addressable (expr);
|
||||
return build1 (ADDR_EXPR, type, expr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -8589,7 +8599,7 @@ unify (tparms, targs, parm, arg, strict)
|
|||
return 1;
|
||||
if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg))
|
||||
return 1;
|
||||
for (i = TREE_VEC_LENGTH (parm) - 1; i >= 0; i--)
|
||||
for (i = 0; i < TREE_VEC_LENGTH (parm); ++i)
|
||||
if (unify (tparms, targs,
|
||||
TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i),
|
||||
UNIFY_ALLOW_NONE))
|
||||
|
|
|
@ -6,6 +6,12 @@ template <int i> void f()
|
|||
f<i+1>(); // ERROR - excessive recursion
|
||||
}
|
||||
|
||||
// We should never need this specialization because we should issue an
|
||||
// error first about the recursive template instantions. But, in case
|
||||
// the compiler fails to catch the error, this will keep it from
|
||||
// running forever instantiating more and more templates.
|
||||
template <> void f<100>();
|
||||
|
||||
int main()
|
||||
{
|
||||
f<0>(); // ERROR - starting here
|
||||
|
|
12
gcc/testsuite/g++.old-deja/g++.pt/ref2.C
Normal file
12
gcc/testsuite/g++.old-deja/g++.pt/ref2.C
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Build don't link:
|
||||
// Origin: Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
template <class T, T&>
|
||||
class C;
|
||||
|
||||
template <int& I>
|
||||
class C<int, I> {};
|
||||
|
||||
int i;
|
||||
|
||||
C<int, i> c;
|
Loading…
Add table
Reference in a new issue