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
This commit is contained in:
parent
903c623438
commit
4542128ef1
5 changed files with 141 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
66
gcc/testsuite/g++.dg/other/ptrmem1.C
Normal file
66
gcc/testsuite/g++.dg/other/ptrmem1.C
Normal file
|
@ -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;
|
||||
|
||||
}
|
36
gcc/testsuite/g++.dg/other/ptrmem2.C
Normal file
36
gcc/testsuite/g++.dg/other/ptrmem2.C
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue