]> gcc.gnu.org Git - gcc.git/commitdiff
cp-tree.h (cplus_expand_constant): Declare.
authorMark Mitchell <mark@codesourcery.com>
Sat, 22 May 1999 01:30:11 +0000 (01:30 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 22 May 1999 01:30:11 +0000 (01:30 +0000)
* cp-tree.h (cplus_expand_constant): Declare.
* cvt.c (convert_to_pointer): Expand PTRMEM_CSTs when they're
converted from one pointer-to-object type to another.
* expr.c (cplus_expand_constant): Don't make it static.
* typeck.c (build_component_ref): Don't crash when presented with
a component which is a TEMPLATE_DECL.
(build_ptrmemfunc): Tidy.  Clarify comment.  Make sure that even a
cast from a pointer-to-member constant to its own type does not
result in a valid non-type template argument.

From-SVN: r27092

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/expr.c
gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.pt/crash42.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C

index 6c64408f1db1e3038da29951480071d63e5adca0..39cec74814627534fdbef661e1f661c88cd4c239 100644 (file)
@@ -1,3 +1,15 @@
+1999-05-22  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (cplus_expand_constant): Declare.
+       * cvt.c (convert_to_pointer): Expand PTRMEM_CSTs when they're
+       converted from one pointer-to-object type to another.
+       * expr.c (cplus_expand_constant): Don't make it static.
+       * typeck.c (build_component_ref): Don't crash when presented with
+       a component which is a TEMPLATE_DECL.
+       (build_ptrmemfunc): Tidy.  Clarify comment.  Make sure that even a
+       cast from a pointer-to-member constant to its own type does not
+       result in a valid non-type template argument.
+
 1999-05-21  Mark Mitchell  <mark@codesourcery.com>
             Nathan Sidwell  <nathan@acm.org>
        
index b2b6313fd8583ba4bbeefb4d73104f252092bec9..ec5ef45ba72ad28d914226bc510b3e9fe4adb802 100644 (file)
@@ -3007,6 +3007,7 @@ extern void init_cplus_expand                     PROTO((void));
 extern void fixup_result_decl                  PROTO((tree, struct rtx_def *));
 extern int extract_init                                PROTO((tree, tree));
 extern void do_case                            PROTO((tree, tree));
+extern tree cplus_expand_constant               PROTO((tree));
 
 /* friend.c */
 extern int is_friend                           PROTO((tree, tree));
index 708272660d03484227322fbcb7e9ef62b26697b6..d24dbf1f4ecab598a4afe60b2c0482a759adb0fd 100644 (file)
@@ -179,19 +179,29 @@ cp_convert_to_pointer (type, expr)
 
       if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
        {
-         tree b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type));
-         tree b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype));
-         tree binfo = get_binfo (b2, b1, 1);
-         enum tree_code code = PLUS_EXPR;
+         tree b1; 
+         tree b2;
+         tree binfo;
+         enum tree_code code;
+
+         b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type));
+         b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype));
+         binfo = get_binfo (b2, b1, 1);
 
          if (binfo == NULL_TREE)
            {
              binfo = get_binfo (b1, b2, 1);
              code = MINUS_EXPR;
            }
+         else
+           code = PLUS_EXPR;
 
          if (binfo == error_mark_node)
            return error_mark_node;
+
+         if (TREE_CODE (expr) == PTRMEM_CST)
+           expr = cplus_expand_constant (expr);
+
          if (binfo && ! TREE_VIA_VIRTUAL (binfo))
            expr = size_binop (code, expr, BINFO_OFFSET (binfo));
        }
index 83bdff9eba7649cb3c37cf88308ece8baef7c6f2..d5250ae603ff7b12d7864fe88857843fb2a80a99 100644 (file)
@@ -39,7 +39,7 @@ static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode,
 /* Hook used by output_constant to expand language-specific
    constants.  */
 
-static tree
+tree
 cplus_expand_constant (cst)
      tree cst;
 {
index 17147b909f71014f978569c91adade6990b41d41..1514ed7a9a93fc0409657d6e748ef067064f082c 100644 (file)
@@ -2138,6 +2138,11 @@ build_component_ref (datum, component, basetype_path, protect)
       cp_error ("invalid use of type decl `%#D' as expression", component);
       return error_mark_node;
     }
+  else if (TREE_CODE (component) == TEMPLATE_DECL)
+    {
+      cp_error ("invalid use of template `%#D' as expression", component);
+      return error_mark_node;
+    }
   else
     {
       tree name = component;
@@ -6516,7 +6521,9 @@ build_ptrmemfunc (type, pfn, force)
      int force;
 {
   tree fn;
-  
+  tree pfn_type = TREE_TYPE (pfn);
+  tree to_type = build_ptrmemfunc_type (type);
+
   /* Handle multiple conversions of pointer to member functions.  */
   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn)))
     {
@@ -6526,27 +6533,21 @@ build_ptrmemfunc (type, pfn, force)
       tree npfn = NULL_TREE;
       tree ndelta, ndelta2;
       tree e1, e2, e3, n;
-      tree pfn_type;
 
-      /* Is is already the right type? */
-      if (type == TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)))
-       return pfn;
-
-      pfn_type = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn));
-      if (!force
-         && comp_target_types (type, pfn_type, 1) != 1)
-       cp_error ("conversion to `%T' from `%T'", type, pfn_type);
+      if (!force 
+         && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn))
+       cp_error ("conversion to `%T' from `%T'", 
+                 to_type, pfn_type);
 
       if (TREE_CODE (pfn) == PTRMEM_CST)
        {
          /* We could just build the resulting CONSTRUCTOR now, but we
             don't, relying on the general machinery below, together
             with constant-folding, to do the right thing.  We don't
-            want to return a PTRMEM_CST here, even though we could,
-            because a pointer-to-member constant ceases to be a
-            constant (from the point of view of the language) when it
-            is cast to another type.  */
-
+            want to return a PTRMEM_CST here, since a
+            pointer-to-member constant is no longer a valid template
+            argument once it is cast to any type, including its
+            original type.  */
          expand_ptrmemfunc_cst (pfn, &ndelta, &idx, &npfn, &ndelta2);
          if (npfn)
            /* This constant points to a non-virtual function.
@@ -6554,6 +6555,12 @@ build_ptrmemfunc (type, pfn, force)
               matter since we won't use it anyhow.  */
            ndelta2 = integer_zero_node;
        }
+      else if (same_type_p (to_type, pfn_type))
+       /* We don't have to do any conversion.  Note that we do this
+          after checking for a PTRMEM_CST so that a PTRMEM_CST, cast
+          to its own type, will not be considered a legal non-type
+          template argument.  */
+       return pfn;
       else
        {
          ndelta = cp_convert (ptrdiff_type_node, 
@@ -6565,15 +6572,15 @@ build_ptrmemfunc (type, pfn, force)
          idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0);
        }
 
-      n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (pfn_type)),
-                               TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
+      n = get_delta_difference (TYPE_PTRMEMFUNC_OBJECT_TYPE (pfn_type),
+                               TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type),
                                force);
       delta = build_binary_op (PLUS_EXPR, ndelta, n);
       delta2 = build_binary_op (PLUS_EXPR, ndelta2, n);
       e1 = fold (build (GT_EXPR, boolean_type_node, idx, integer_zero_node));
          
       /* If it's a virtual function, this is what we want.  */
-      e2 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx,
+      e2 = build_ptrmemfunc1 (to_type, delta, idx,
                              NULL_TREE, delta2);
 
       pfn = PFN_FROM_PTRMEMFUNC (pfn);
@@ -6582,7 +6589,7 @@ build_ptrmemfunc (type, pfn, force)
 
       /* But if it's a non-virtual function, or NULL, we use this
         instead.  */
-      e3 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta,
+      e3 = build_ptrmemfunc1 (to_type, delta,
                              idx, npfn, NULL_TREE);
       return build_conditional_expr (e1, e2, e3);
     }
@@ -6591,7 +6598,7 @@ build_ptrmemfunc (type, pfn, force)
   if (integer_zerop (pfn))
     {
       pfn = build_c_cast (type, integer_zero_node);
-      return build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type),
+      return build_ptrmemfunc1 (to_type,
                                integer_zero_node, integer_zero_node,
                                pfn, NULL_TREE);
     }
@@ -6601,7 +6608,7 @@ build_ptrmemfunc (type, pfn, force)
 
   fn = TREE_OPERAND (pfn, 0);
   my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
-  return make_ptrmem_cst (build_ptrmemfunc_type (type), fn);
+  return make_ptrmem_cst (to_type, fn);
 }
 
 /* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST
@@ -6621,8 +6628,7 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2)
   my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 0);
   
   *delta 
-    = get_delta_difference (TYPE_METHOD_BASETYPE 
-                           (TREE_TYPE (fn)),
+    = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (fn)),
                            TYPE_PTRMEMFUNC_OBJECT_TYPE (type),
                            /*force=*/0);
   if (!DECL_VIRTUAL_P (fn))
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash42.C b/gcc/testsuite/g++.old-deja/g++.pt/crash42.C
new file mode 100644 (file)
index 0000000..69df535
--- /dev/null
@@ -0,0 +1,14 @@
+// Build don't link:
+// Origin: Walter Brisken <walterfb@puppsr14.princeton.edu>
+
+template <class T> class list {};
+
+class newtype
+{
+};
+
+void crash()
+{
+  newtype* n;
+  n->list.size (); // ERROR - invalid use of template
+}
index 946e6244f4a95956a8c910f91a3472a979b7b548..e7750ddf969ef41417b820b8cc3d01b254b36dd6 100644 (file)
@@ -23,7 +23,7 @@ int main() {
   h<&A::i>();
   g<&B::f>(); // ERROR - 
   h<&B::j>(); // ERROR - 
-  g<(void (A::*)()) &A::f>(); // ERROR - XFAIL *-*-*
+  g<(void (A::*)()) &A::f>(); // ERROR - 
   h<(int A::*) &A::i>(); // ERROR - 
   g<(void (A::*)()) &B::f>(); // ERROR - 
   h<(int A::*) &B::j>(); // ERROR - 
This page took 0.099464 seconds and 5 git commands to generate.