diff options
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/ir.texi | 2 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 9 | ||||
-rw-r--r-- | gcc/cp/method.c | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/infinite1.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/ref2.C | 12 |
7 files changed, 63 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ce7b48e6d43..87cea7059bc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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> diff --git a/gcc/cp/ir.texi b/gcc/cp/ir.texi index 61165b7fa80..429c1554112 100644 --- a/gcc/cp/ir.texi +++ b/gcc/cp/ir.texi @@ -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 diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index d4bd066cd09..2bba09f518b 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -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); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index f6c006a0860..495c47b3d5d 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f3c7989b13b..48df27f3815 100644 --- a/gcc/cp/pt.c +++ b/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)) diff --git a/gcc/testsuite/g++.old-deja/g++.pt/infinite1.C b/gcc/testsuite/g++.old-deja/g++.pt/infinite1.C index 90a2b75cc22..22f00739c87 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/infinite1.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/infinite1.C @@ -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 diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ref2.C b/gcc/testsuite/g++.old-deja/g++.pt/ref2.C new file mode 100644 index 00000000000..ee684981e70 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/ref2.C @@ -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; |