OSDN Git Service

* ir.texi: Correct typo.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Jun 2000 01:42:22 +0000 (01:42 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Jun 2000 01:42:22 +0000 (01:42 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@34396 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/ir.texi
gcc/cp/mangle.c
gcc/cp/method.c
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.pt/infinite1.C
gcc/testsuite/g++.old-deja/g++.pt/ref2.C [new file with mode: 0644]

index ce7b48e..87cea70 100644 (file)
@@ -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>
 
index 61165b7..429c155 100644 (file)
@@ -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
index d4bd066..2bba09f 100644 (file)
@@ -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);
 
index f6c006a..495c47b 100644 (file)
@@ -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);
index f3c7989..48df27f 100644 (file)
@@ -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))
index 90a2b75..22f0073 100644 (file)
@@ -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 (file)
index 0000000..ee68498
--- /dev/null
@@ -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;