Bug 950 - [DR 203] Template problem: decay of pointer-to-member-of-derived to p-o-m-o-base
Summary: [DR 203] Template problem: decay of pointer-to-member-of-derived to p-o-m-o-base
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 2.95.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: monitored, rejects-valid
: 9032 11906 13063 (view as bug list)
Depends on:
Blocks:
 
Reported: 2000-11-30 22:16 UTC by peteb
Modified: 2016-01-14 14:52 UTC (History)
14 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 3.4.4, 4.0.1, 4.1.0, 4.1.2
Last reconfirmed: 2009-11-18 05:24:04


Attachments
patch (920 bytes, patch)
2009-11-18 15:51 UTC, Jason Merrill
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description peteb 2000-11-30 22:16:00 UTC
Strange compile problem with function templates involving pointers to virtual member functions of a derived class.
In the attached test code, compiler doesn't seem to think the virtual functions w::a() and w::b() exists in the derived class unless addresses are first copied into pointer variables.

g++ test.cc -otest
test.cc: In function `int main(unsigned int, const char *const *)':
test.cc:49: no matching function for call to `c<w>::fails_sometimes (int &, void (y::*)(int) const)'
test.cc:50: no matching function for call to `c<w>::fails_sometimes (const char *&, void (y::*)(const char *) const)'
make: *** [test] Error 1

Release:
gcc version 2.95.2 19991024 (release)

Environment:
RedHat Linux 6.2.
Also fails under Redhat 7.0 with unofficial gcc-2.96.

How-To-Repeat:
#include <iostream>


class y
{
public:
  virtual void a (int n) const { }
  virtual void b (const char *s) const { }
};

class w: public y
{
};


template <class m>
class c
{
public:
  template<class d>
  void works (const d& x) const
  { cerr << x << endl; }

  template<class d>
  void fails_sometimes (const d& x, void (m::*func)(d) const) const
  { cerr << x << endl; }
};


int main (unsigned argc, const char *const argv[])
{
  int n = 3;
  const char *s = "hey!";
  c<w> c1;

  // This works OK...
  c1.works(n);
  c1.works(s);

  // This works OK...
  void (w::*a_func)(int) const = &w::a;
  void (w::*b_func)(const char *) const = &w::b;

  // This works OK...
  c1.fails_sometimes(n, a_func);
  c1.fails_sometimes(s, b_func);
  
  // This fails compilation, but should pass...
  c1.fails_sometimes(n, &w::a);
  c1.fails_sometimes(s, &w::b);
}
Comment 1 Kriang Lerdsuwanakij 2001-08-12 09:38:00 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirm as a bug.
Comment 2 Wolfgang Bangerth 2002-11-10 14:46:04 UTC
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: gcc-bugs@gcc.gnu.org, <gcc-gnats@gcc.gnu.org>
Cc:  
Subject: Re: c++/950: Template lookup problem
Date: Sun, 10 Nov 2002 14:46:04 -0600 (CST)

 A reduced testcase for this one is
 --------------------------------------------
 struct B { void a (int n); };
 struct D: public B {};
 
 template <typename T> struct X {
     template<typename Y>
     static void foo (const Y&, void (T::*)(Y));
 };
 
 int main () {
   int n = 3;
   X<D>::foo(n, &D::a);
 }
 --------------------------------------
 The error I get is this one:
 x.cc: In function `int main()':
 x.cc:11: error: no matching function for call to `X<D>::foo(int&, void
    (B::*)(int))'
 
 Thus, the compiler cannot find a match for X::foo, since &D::a is 
 immediately converted to &B::a, i.e. to a pointer to member function of 
 the _base_ class, although we have taken a p-t-m-f of the derived class. I 
 don't know what the standard says on this one, but at least the failure 
 mode is clear now.
 
 The problem can be worked around using a temporary variable of type 
   void (D::*)(int)
 or an explicit cast.
 
 Regards
   Wolfgang
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth              email:           bangerth@ticam.utexas.edu
                                www: http://www.ticam.utexas.edu/~bangerth
 
 

Comment 3 Wolfgang Bangerth 2002-11-14 14:34:53 UTC
From: Wolfgang Bangerth <bangerth@apex68.ticam.utexas.edu>
To: gcc-gnats@gcc.gnu.org
Cc:  
Subject: c++/950: Template lookup problem
Date: Thu, 14 Nov 2002 14:34:53 -0600

 Re-confirmed with 3.3 CVS from 2002-11-10 and 3.2.1 pre from the same date.

Comment 4 Giovanni Bajo 2003-04-10 19:48:23 UTC
From: "Giovanni Bajo" <giovannibajo@libero.it>
To: <gcc-gnats@gcc.gnu.org>,
	<gcc-bugs@gcc.gnu.org>,
	<nobody@gcc.gnu.org>,
	<gcc-prs@gcc.gnu.org>,
	<peteb@sitera.com>
Cc: "Wolfgang Bangerth" <bangerth@ices.utexas.edu>
Subject: Re: c++/950: [2003-01-01] Template lookup problem
Date: Thu, 10 Apr 2003 19:48:23 +0200

 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&p
 r=950
 
 Reconfirmed with 2.95 -> 3.3 20030401.
 
 Giovanni Bajo
Comment 5 Andrew Pinski 2003-05-24 22:28:15 UTC
still happens with the mainline (20030524).

pr950.cc: In function `int main()':
pr950.cc:12: error: no matching function for call to `X<D>::foo(int&, void 
   (B::*)(int))'
Comment 6 Andrew Pinski 2003-08-13 18:45:05 UTC
*** Bug 9032 has been marked as a duplicate of this bug. ***
Comment 7 Andrew Pinski 2003-08-13 18:49:05 UTC
*** Bug 11906 has been marked as a duplicate of this bug. ***
Comment 8 Andrew Pinski 2003-11-16 00:00:20 UTC
*** Bug 13063 has been marked as a duplicate of this bug. ***
Comment 9 Andrew Pinski 2004-11-26 15:34:00 UTC
*** Bug 18681 has been marked as a duplicate of this bug. ***
Comment 10 Richard Biener 2005-09-09 12:42:23 UTC
EDG likes this.
Comment 11 Wolfgang Bangerth 2007-03-29 16:13:53 UTC
Still happens with 4.1.2
Comment 12 Wolfgang Bangerth 2008-09-10 15:26:47 UTC
Still happens with gcc version 4.4.0 20080801 (experimental) [trunk revision 138448]
Comment 13 Jason Merrill 2009-11-18 05:43:00 UTC
5.3.1 [expr.unary.op] paragraph 3:

...If the member is a non-static member of class C of type T, the type of the result is “pointer to member of class C of type T.” [ Example:
     struct A { int i; };
     struct B : A { };
                          // has type int A::*
     ... &B::i ...
   — end example ]

So, the type of &D::a is the same as the type of &B::a, and this is not a bug.
Comment 14 Jason Merrill 2009-11-18 15:51:55 UTC
Created attachment 19035 [details]
patch

If this were a bug, this would be the fix.
Comment 15 Jason Merrill 2009-11-18 21:55:01 UTC
Actually, this is issue 203, so I'll suspend it instead of closing.

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#203
Comment 16 W E Brown 2016-01-14 13:16:03 UTC
(In reply to Jason Merrill from comment #15)
> Actually, this is issue 203, so I'll suspend it instead of closing.
> 
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#203

Issue 203 has been resolved:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#203
Comment 17 Jonathan Wakely 2016-01-14 14:52:11 UTC
Not a bug then.