This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Fix PR/2094


Hello,

this patch adds support for PTRMEM_CST trees to type unification. This was
never implemented in GCC (as far as I can tell), so GCC was unable to deduce
the types for a call which involved pointer to members as
arguments/parameters (it was emitting a sorry()). The unification is very
easy, because we just try to unifiy the PTRMEM_CST_MEMBER of the nodes,
which are FIELD_DECLs. Then, two FIELD_DECLs can be unified only if they are
the same (that is, the pointers match).

This patch has been bootstrapped on i686-pc-cygwin (c, c++, java) and tested
with "make check-g++" with no new regressions. OK for mainline?

Giovanni Bajo


2003-06-25  Giovanni Bajo  <giovannibajo@libero.it>

        PR c++/2094
        * pt.c (unify): Add support for PTRMEM_CST and
        FIELD_DECL unification.

2003-06-25  Giovanni Bajo  <giovannibajo@libero.it>

        PR c++/2094
        * g++.dg/template/ptrmem6.C: New test.


Index: pt.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.697
diff -c -w -p -r1.697 pt.c
*** pt.c        3 Jun 2003 13:01:43 -0000       1.697
--- pt.c        25 Jun 2003 15:38:18 -0000
*************** unify (tparms, targs, parm, arg, strict)
*** 9685,9690 ****
--- 9695,9721 ----
        TREE_VEC_ELT (targs, idx) = arg;
        return 0;

+     case PTRMEM_CST:
+      {
+         /* A pointer-to-member constant can be unified only with
+          another constant.  */
+       if (TREE_CODE (arg) != PTRMEM_CST)
+         return 1;
+
+       /* Just unify the class member. It would be useless (and possibly
+          wrong, depending on the strict flags) to unify also
+          PTRMEM_CST_CLASS, because we want to be sure that both parm and
+          arg refer to the same variable, even if through different
+          classes. For instance:
+
+          struct A { int x; };
+          struct B : A { };
+
+          Unification of &A::x and &B::x must succeed.  */
+       return unify (tparms, targs, PTRMEM_CST_MEMBER (parm),
+                     PTRMEM_CST_MEMBER (arg), strict);
+      }
+
      case POINTER_TYPE:
        {
        if (TREE_CODE (arg) != POINTER_TYPE)
*************** unify (tparms, targs, parm, arg, strict)
*** 9886,9891 ****
--- 9917,9923 ----
        return 1;
        return 0;

+     case FIELD_DECL:
      case TEMPLATE_DECL:
        /* Matched cases are handled by the ARG == PARM test above.  */
        return 1;


// { dg-do compile }
// Origin: <togawa at acm dot arg>
// c++/2094: unsupported 'ptrmem_cst' in type unification

struct R
{
   int i;
};

struct S
{
   int i;
   int j;
};

struct S2 : S
{};

template<int S::*p, typename>
struct X
{
    X ();
    template<typename U> X(const X<p,U> &);
};

X<&S::i,S> x  = X<&S::i,S>();
X<&S::i,S> x2 = X<&S2::i,S>();
X<&S::i,S> y  = X<&S::j,S>();  // { dg-error "" }
X<&S::i,S> z  = X<&R::i,S>();  // { dg-error "" }

template <class T>
struct Foo
{
  void foo(void)
  {
     X<&T::i,T> x  = X<&T::i,T>();
     X<&S::i,S> x2 = X<&S2::i,S>();
     X<&S::i,S> y  = X<&S::j,S>(); // { dg-error "" }
     X<&S::i,S> z  = X<&R::i,S>(); // { dg-error "" }
  }
};

template struct Foo<S>;  // { dg-error "instantiated from" }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]