/* 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.
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");
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);
--- /dev/null
+// { 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;
+}