re PR c++/4379 (Member pointer to member reference not allowed when declared directly...
authorNathan Sidwell <nathan@codesourcery.com>
Wed, 2 Jan 2002 11:32:34 +0000 (11:32 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 2 Jan 2002 11:32:34 +0000 (11:32 +0000)
cp:
PR c++/4379
* typeck.c (build_x_unary_op): Don't destroy the OFFSET_REF on a
single non-static member.
(unary_complex_lvalue): If it cannot be a pointer to member, don't
make it so. Check it is not pointer to reference.
testsuite:
* g++.dg/other/ptrmem1.C: New test.
* g++.dg/other/ptrmem2.C: New test.

From-SVN: r48465

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/ptrmem1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/ptrmem2.C [new file with mode: 0644]

index a6ecc50a3a5f4b0a6d709b06df2571c3a1b323b5..14194c7eb55e9bbd078bbfb5e2dda26e53bceda9 100644 (file)
@@ -1,3 +1,11 @@
+2002-01-02  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/4379
+       * typeck.c (build_x_unary_op): Don't destroy the OFFSET_REF on a
+       single non-static member.
+       (unary_complex_lvalue): If it cannot be a pointer to member, don't
+       make it so. Check it is not pointer to reference.
+
 2002-01-02  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR c++/5132
index 1ad9de21136310973f790806baa6b99a69483867..9fdd168343c74ed82f1ef583e26eef2c69af397b 100644 (file)
@@ -1,6 +1,6 @@
 /* Build expressions with type checking for C++ compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -4286,9 +4286,15 @@ build_x_unary_op (code, xarg)
           
           if (!ptrmem && !flag_ms_extensions
               && TREE_CODE (TREE_TYPE (TREE_OPERAND (xarg, 1))) == METHOD_TYPE)
-            /* A single non-static member, make sure we don't allow a
-               pointer-to-member.  */
-            xarg = ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE);
+           {
+             /* A single non-static member, make sure we don't allow a
+                 pointer-to-member.  */
+             xarg = build (OFFSET_REF, TREE_TYPE (xarg),
+                           TREE_OPERAND (xarg, 0),
+                           ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE));
+             PTRMEM_OK_P (xarg) = ptrmem;
+           }
+             
         }
       else if (TREE_CODE (xarg) == TARGET_EXPR)
        warning ("taking address of temporary");
@@ -4849,6 +4855,22 @@ unary_complex_lvalue (code, arg)
              error ("taking address of bound pointer-to-member expression");
              return error_mark_node;
            }
+         if (!PTRMEM_OK_P (arg))
+           {
+             /* This cannot form a pointer to method, so we must
+                resolve the offset ref, and take the address of the
+                result.  For instance,
+                       &(C::m)       */
+             arg = resolve_offset_ref (arg);
+
+             return build_unary_op (code, arg, 0);
+           }
+         
+         if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
+           {
+             error ("cannot create pointer to reference member `%D'", t);
+             return error_mark_node;
+           }
 
          type = build_offset_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t));
          type = build_pointer_type (type);
index 1e0e603837183af2fe391b5368dccb77b17240f1..e75984c11eaf93f7c358547a00e6a32cbbb2f5e1 100644 (file)
@@ -1,3 +1,8 @@
+2002-01-02  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.dg/other/ptrmem1.C: New test.
+       * g++.dg/other/ptrmem2.C: New test.
+
 2002-01-02  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.dg/template/ctor1.C: New test.
diff --git a/gcc/testsuite/g++.dg/other/ptrmem1.C b/gcc/testsuite/g++.dg/other/ptrmem1.C
new file mode 100644 (file)
index 0000000..fa9115e
--- /dev/null
@@ -0,0 +1,66 @@
+// { dg-do run }
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 31 Dec 2001 <nathan@codesourcery.com>
+
+// PR 4379. We created pointers to member references and pointers to
+// member fields when we shouldn't have.
+
+int gs;
+int gm;
+
+struct D {
+  D () :m (gm) {}
+  
+  int &m;
+  static int &s;
+  
+  int Foo ();
+};
+
+int &D::s = gs;
+
+template<class T> int f1(T x)
+{
+  return x != &gm;
+}
+template<class T> int f2(T x) 
+{
+  return x != &gs;
+}
+
+int D::Foo ()
+{
+  int r;
+  
+  if (f1( &(D::m)))
+    return 3;
+  
+  if (f2( &D::s))
+    return 1;
+  if (f2( &(D::s)))
+    return 2;
+  return 0;
+}
+
+int Foo ()
+{
+  if (f2( &D::s))
+    return 4;
+  if (f2( &(D::s)))
+    return 5;
+  return 0;
+}
+
+int main ()
+{
+  D d;
+  int r = d.Foo ();
+  if (r)
+    return r;
+  r = Foo ();
+  if (r)
+    return r;
+  return 0;
+  
+}
diff --git a/gcc/testsuite/g++.dg/other/ptrmem2.C b/gcc/testsuite/g++.dg/other/ptrmem2.C
new file mode 100644 (file)
index 0000000..ec451be
--- /dev/null
@@ -0,0 +1,36 @@
+// { dg-do compile }
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 31 Dec 2001 <nathan@codesourcery.com>
+
+// PR 4379. We created pointers to member references and pointers to
+// member fields when we shouldn't have.
+
+struct D {
+  
+  int &m;   // { dg-error "member `D::m' is non-static" "" }
+  static int &s;
+  
+  int Foo ();
+};
+
+template<class T> int f1(T x);
+template<class T> int f2(T x);
+
+int D::Foo ()
+{
+  f1( &D::m);   // { dg-error "cannot create pointer to ref" "" }
+  f1( &(D::m));        // ok
+  f2( &D::s);   // ok
+  f2( &(D::s)); // ok
+  return 0;
+}
+
+int Foo ()
+{
+  f1( &D::m);    // { dg-error "cannot create pointer to ref" "" }
+  f1( &(D::m));  // { dg-error "at this point" "" }
+  f2( &D::s);    // ok
+  f2( &(D::s));  // ok
+  return 0;
+}