Bug 593060

Summary: gcc 4.1.2, 4.3.2, 4.4 bug: passing const-reference-to-function
Product: Red Hat Enterprise Linux 5 Reporter: Alan Matsuoka <alanm>
Component: gcc44Assignee: Jakub Jelinek <jakub>
Status: CLOSED ERRATA QA Contact: qe-baseos-tools-bugs
Severity: medium Docs Contact:
Priority: low    
Version: 5.5CC: james.leddy, jason, jwest, mnowak, pmuller
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: gcc44-4.4.4-13.el5 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 593750 653994 (view as bug list) Environment:
Last Closed: 2011-01-14 00:00:55 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 593750, 653994    
Attachments:
Description Flags
patch none

Comment 1 Jason Merrill 2010-05-19 15:54:22 UTC
Created attachment 415175 [details]
patch

Here's a fix for 4.3 and 4.4, and probably 4.1 as well, though I haven't tested it there.  Applying the patch to 4.3 (and presumably 4.1) introduces a testsuite failure on g++.dg/template/qualttp20.C; this is OK, the testcase should be adjusted.

Comment 4 James M. Leddy 2010-07-09 16:00:54 UTC
public facing version of comment 0:

Problem:

The following is the problem description from a developer:

On gcc 4.3.2:

with gcc 4.3.2 and encountered a number of problems some of them I consider
compiler bugs.

One of the bugs I was able to minimize, related to const pointers to functions
(g++ 3.4.6 and Comeau compile this successfully):
bool f(int i) { return i != 5; }

template <class X, class P = bool(X)>
struct Traits
{
 typedef P type;
};

template <class X, class P = typename Traits<X>::type>
struct S
{
 const P& p_;
 S( const P& p ) : p_(p) {} // const reference
};

template <class X>
S<X> make_s(const typename Traits<X>::type & p) // const reference
{
 return S<X>(p); // << HERE
}


int main()
{
 make_s<int>(f);
}

It doesn't compile with the following error (both g++ 4.1.2 and 4.3.2):
[yanchm@qtqa-tko1] msg > g++43 ~/gs/test_func_ref_gcc4.cpp
/home/yanchm/gs/test_func_ref_gcc4.cpp: In function 'S<X, typename Traits<X,
bool ()(X)>::type> make_s(const typename Traits<X, bool ()(X)>::type&) [with X
= int]':
/home/yanchm/gs/test_func_ref_gcc4.cpp:27:   instantiated from here
/home/yanchm/gs/test_func_ref_gcc4.cpp:21: error: no matching function for call
to 'S<int, bool ()(int)>::S(bool (&)(int)const)'
/home/yanchm/gs/test_func_ref_gcc4.cpp:13: note: candidates are: S<X,
P>::S(const P&) [with X = int, P = bool ()(int)]
/home/yanchm/gs/test_func_ref_gcc4.cpp:11: note:                 S<int, bool
()(int)>::S(const S<int, bool ()(int)>&)

If I explicitly remove const from the reference (ugly workaround), it compiles:
 return S<X>( (typename Traits<X>::type &) p); // << HERE

Funny enough, if I cast it to const reference (i.e. casting to the same type):
 return S<X>( (const typename Traits<X>::type &) p); // << HERE
it gives ICE:
[yanchm@qtqa-tko1] msg > g++43 ~/gs/test_func_ref_gcc4.cpp
/home/yanchm/gs/test_func_ref_gcc4.cpp: In function 'S<X, typename Traits<X,
bool ()(X)>::type> make_s(const typename Traits<X, bool ()(X)>::type&) [with X
= int]':
/home/yanchm/gs/test_func_ref_gcc4.cpp:27:   instantiated from here
/home/yanchm/gs/test_func_ref_gcc4.cpp:21: internal compiler error: in
build_c_cast, at cp/typeck.c:5631
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
Preprocessed source stored into /tmp/ccCtpcHR.out file, please attach this to
your bugreport.

Also, const_cast doesn't work for this cast (I didn't check in the Standard,
this might be not a bug):
 return S<X>( const_cast< typename Traits<X>::type & >(p) ); // << HERE
with the following error:
/home/yanchm/gs/test_func_ref_gcc4.cpp: In function 'S<X, typename Traits<X,
bool ()(X)>::type> make_s(const typename Traits<X, bool ()(X)>::type&) [with X
= int]':
/home/yanchm/gs/test_func_ref_gcc4.cpp:27:   instantiated from here
/home/yanchm/gs/test_func_ref_gcc4.cpp:21: error: invalid use of const_cast
with type 'bool (&)(int)', which is a pointer or reference to a function type

On gcc 4.4 (RHEL 5.5.):

Just tested on 5u5, gcc4.4 has the same bug:

[root@fullejo-1 ~]# g++44 /root/test_func_ref_gcc4.cpp
/root/test_func_ref_gcc4.cpp: In function 'S<X, typename Traits<X,
bool(X)>::type> make_s(const typename Traits<X, bool(X)>::type&) [with X =
int]':
/root/test_func_ref_gcc4.cpp:27:   instantiated from here
/root/test_func_ref_gcc4.cpp:21: error: no matching function for call to
'S<int, bool(int)>::S(bool (&)(int)const)'
/root/test_func_ref_gcc4.cpp:13: note: candidates are: S<X, P>::S(const P&)
[with X = int, P = bool(int)]
/root/test_func_ref_gcc4.cpp:11: note:                 S<int,
bool(int)>::S(const S<int, bool(int)>&)

[root@fullejo-1 ~]# g++44 --version
g++44 (GCC) 4.4.0 20090514 (Red Hat 4.4.0-6)

The only difference: the type of the function is now reported better: bool(X)
instead of bool ()(X). But the bug is still here.


IMPACT:

The workarounds are actually quite ugly (cast away constness) and illogical
(just presence of an enum changes compilability of other lines).

The workaround is very ugly (100-character-length cast-away of constness), but
as this GCC version (4.4) is going to be important and will be used by all
teams in the firm, this may result in real business impact.

Test Case:

# cat test_func_ref_gcc4.cpp
bool f(int i) { return i != 5; }

template <class X, class P = bool(X)>
struct Traits
{
 typedef P type;
};

template <class X, class P = typename Traits<X>::type>
struct S
{
 const P& p_;
 S( const P& p )
   : p_(p)
 {}
};

template <class X>
S<X> make_s(const typename Traits<X>::type & p)
{
 return S<X>(p);
}


int main()
{
 make_s<int>(f);
}

Notes:

I'm not sure if this is a well formed program but I think
this could be: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40315

Comment 9 errata-xmlrpc 2011-01-14 00:00:55 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2011-0102.html