Bug 33990 - bug in lookup of member template conversion operator for pointer to member functions
Summary: bug in lookup of member template conversion operator for pointer to member fu...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks: pmf, ptmf
  Show dependency treegraph
 
Reported: 2007-11-03 21:59 UTC by Sumant Tambe
Modified: 2023-12-17 18:52 UTC (History)
8 users (show)

See Also:
Host: Linux i686
Target:
Build:
Known to work:
Known to fail: 2.95, 4.2.1
Last reconfirmed: 2021-07-23 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sumant Tambe 2007-11-03 21:59:59 UTC
In the code snippet below, the comparison (nullptr == pmf) in main should compile but on gcc it fails to compile. Compiler fails to find appropriate conversion operator and gives error saying:
error: no match for operator== in nullptr == pmf

class nullptr_t 
{
  public:
      template<class T>
      operator T*() const // convertible to any type of null non-member pointer...
    { return 0; }

    template<class C, class T>
    operator T C::*() const   // or any type of null member pointer...
    { return 0; }
} nullptr = {};
struct C
{
  void func ();
};
int main(void)
{
  char * ch = nullptr;
  void (C::*pmf)() = nullptr; 
  if (nullptr == ch) {}       // Compiles successfully
  if (nullptr == pmf) {}      // Should compile but does not compile on gcc 4.1.1
}
Comment 1 Sumant Tambe 2007-11-05 00:05:39 UTC
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux
Thread model: posix
gcc version 4.1.1 20070105 (Red Hat 4.1.1-51)
Comment 2 Wolfgang Bangerth 2007-11-15 04:33:52 UTC
Confirmed with 2.95 and 4.2.1.
W.
Comment 3 Yuriy Lalym 2009-10-04 15:33:31 UTC
(In reply to comment #0)
There is a makeshift.

File a.cpp
#include <stdio.h>

const class nullptr_t
{
public:
  template<class T> operator T*() const { return 0; }
  template<class C, class T> operator T C::*() const { return 0; }

  // void (C::*pmf)() = nullptr;	// Ok
  // if (nullptr == pmf) {}		// Ok
  template<class C, class T> bool operator == (C (T::*p)()) const
    { return  p == 0; }

  private:
    void operator&() const;

    // const int n = 0;
    // if (nullptr == n) {}		// Error
    bool operator == (long) const;
}
nullptr = {};

struct C
{
  void func();
};

int main(void)
{
  void (C::*pmf)() = nullptr;
  if (nullptr == pmf) {printf("Ok\n");}

  // If there are sentences - send !!!!!!!!
  // if (pmf == nullptr) {printf("Ok\n");} // Error
}

> g++ a.cpp
> ./a.out
Ok
>
Comment 4 Pawel Sikora 2010-06-27 09:45:17 UTC
current 4.5 rejects all conversions:

$ cat t.cpp
const                        // this is a const object...
class {
public:
  template<class T>          // convertible to any type
    operator T*() const      // of null non-member
    { return 0; }            // pointer...
  template<class C, class T> // or any type of null
    operator T C::*() const  // member pointer...
    { return 0; }
private:
  void operator&() const;    // whose address can't be taken
} nullptr = {};              // and whose name is nullptr

extern void* p;
struct A
{
  void foo();
};
extern void (A::*pmf)();
int main()
{
  return ( ( p != nullptr ) && ( pmf != nullptr ) );
}


$ g++ t.cpp -std=c++0x -c
t.cpp: In function 'int main()':
t.cpp:22:19: error: no match for 'operator!=' in 'p != nullptr'
t.cpp:22:41: error: no match for 'operator!=' in 'pmf != nullptr'
Comment 5 Jonathan Wakely 2010-06-27 10:26:02 UTC
N.B. nullptr is a keyword in c++0x, and proper nullptr support has been added to 4.6 anyway, but those covnersions should still work
Comment 6 Pawel Sikora 2010-06-28 09:47:53 UTC
(In reply to comment #5)
> N.B. nullptr is a keyword in c++0x, and proper nullptr support has been added
> to 4.6 anyway, but those covnersions should still work

gcc <= 4.4 rejects only operator!=(pmf,nullptr):

$ g++44 t.cpp -Wall -c -std=c++0x
t.cpp: In function 'int main()':
t.cpp:21: error: no match for 'operator!=' in 'pmf != nullptr'

gcc >= 4.5 rejects also operator!=(p,nullptr):

$ g++45 t.cpp -Wall -c -std=c++0x
t.cpp: In function 'int main()':
t.cpp:21:19: error: no match for 'operator!=' in 'p != nullptr'
t.cpp:21:41: error: no match for 'operator!=' in 'pmf != nullptr'