aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2002-01-02 11:32:34 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2002-01-02 11:32:34 +0000
commit4542128ef1545dc28cf4e3a2e4232f6058267c1c (patch)
treea3bb69f29f4f3a59bc319decb285e61679f8d216
parent903c623438e8f4ce15639fffed80f9ced73a8bf7 (diff)
downloadgcc-4542128ef1545dc28cf4e3a2e4232f6058267c1c.zip
gcc-4542128ef1545dc28cf4e3a2e4232f6058267c1c.tar.gz
gcc-4542128ef1545dc28cf4e3a2e4232f6058267c1c.tar.bz2
re PR c++/4379 (Member pointer to member reference not allowed when declared directly, but allowed as template parameter.)
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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/typeck.c30
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/other/ptrmem1.C66
-rw-r--r--gcc/testsuite/g++.dg/other/ptrmem2.C36
5 files changed, 141 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a6ecc50..14194c7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
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
* decl2.c (reparse_absdcl_as_casts): Don't digest_init if we
are processing a template decl.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 1ad9de2..9fdd168 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1e0e603..e75984c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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.
2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
diff --git a/gcc/testsuite/g++.dg/other/ptrmem1.C b/gcc/testsuite/g++.dg/other/ptrmem1.C
new file mode 100644
index 0000000..fa9115e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/ptrmem1.C
@@ -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
index 0000000..ec451be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/ptrmem2.C
@@ -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;
+}