Bug 695567 - "cannot be used as a function" error when calling pointer-to-member functions in a template
Summary: "cannot be used as a function" error when calling pointer-to-member functions...
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: 14
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-04-12 02:45 UTC by r6144
Modified: 2011-04-14 10:21 UTC (History)
2 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2011-04-14 10:21:14 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
File demonstrating the problem (778 bytes, text/x-c++src)
2011-04-12 02:45 UTC, r6144
no flags Details
rh695567.C (5.53 KB, text/plain)
2011-04-12 11:23 UTC, Jakub Jelinek
no flags Details


Links
System ID Private Priority Status Summary Last Updated
GNU Compiler Collection 48594 0 None None None Never

Description r6144 2011-04-12 02:45:48 UTC
Created attachment 491398 [details]
File demonstrating the problem

Description of problem:

The attached phoenix-bug.cpp does not compile with g++.  Specifically, (vp->*push_back_)(tria1) gives the error "vp->*push_back_ cannot be used as a function", although assigning vp->*push_back_ to a local variable fp and calling fp(tria1) does work.  If the function f() is not a template, there is no problem.  clang has no problem compiling the code either.

Version-Release number of selected component (if applicable):
gcc-c++-4.5.1-4.fc14.x86_64
boost-devel-1.44.0-7.fc14.x86_64
clang-2.8-10.fc14.x86_64

How reproducible:
Always

Steps to Reproduce:
1. g++ -o phoenix-bug phoenix-bug.cpp
  
Actual results:
phoenix-bug.cpp: In function ‘void f(T)’:
phoenix-bug.cpp:20:26: error: ‘vp->*push_back_’ cannot be used as a function

Expected results:
Should compile.

This program does compile correctly with clang:
clang -o phoenix-bug phoenix-bug.cpp -lstdc++


Additional info:

Comment 1 Jakub Jelinek 2011-04-12 11:21:51 UTC
Jason, is this valid?

#include <vector>
#include <boost/spirit/include/phoenix.hpp>
namespace ph = boost::phoenix;
struct Triangle {};
extern ph::actor<ph::value<std::vector<Triangle> *> > vp;
#ifndef WORKS2
template<typename T>
#endif
void foo ()
{
  void (std::vector<Triangle>::*const p)(const Triangle&)
    = &std::vector<Triangle>::push_back;
  Triangle tria1;
#ifdef WORKS
   auto fp = vp->*p;
   fp(tria1);
#else
   (vp->*p)(tria1);
#endif
}
#ifndef WORKS2
void bar ()
{
  foo<int> ();
}
#endif

Comment 2 Jakub Jelinek 2011-04-12 11:23:46 UTC
Created attachment 491460 [details]
rh695567.C

Somewhat delta reduced, hope I haven't elided anything important for the testcase.

Comment 3 Jakub Jelinek 2011-04-12 11:33:17 UTC
Failed that way already in r130000 and already in r90000 (up to r129XXX ) failed with
error: ‘#‘member_ref’ not supported by dump_expr#<expression error>’ cannot be used as a function
error instead of
error: ‘vp->*p’ cannot be used as a function
But compiles fine with g++ 3.2-RH and 3.3.

Comment 4 Jason Merrill 2011-04-13 18:28:35 UTC
This is indeed a bug.  Reduced:

struct A { } a;

typedef void (*pfn)();
pfn operator->* (A, int);

template <class T>
void f()
{  
  (a->*1)();
}


Note You need to log in before you can comment on or make changes to this bug.