Bug 58923 - g++ does not use provided conversion function for implicit conversion to another type
Summary: g++ does not use provided conversion function for implicit conversion to anot...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: 5.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-30 11:49 UTC by André Ritter
Modified: 2015-03-24 17:28 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Source file with complete test case (136 bytes, text/plain)
2013-10-30 11:49 UTC, André Ritter
Details

Note You need to log in before you can comment on or make changes to this bug.
Description André Ritter 2013-10-30 11:49:05 UTC
Created attachment 31112 [details]
Source file with complete test case

g++ is not able to compile the following test case which you also can find in the attachment (file: 'cast.cc').

struct A
{
	virtual void do_it() const = 0;
};

struct B :  A
{
	virtual void do_it() const {}
};

struct C
{
	operator B() const { return B(); }
};

void do_it(const A& a) { a.do_it(); }

int main()
{
	C c;
	do_it(c);
	return 0;
}


When compiling this test case with clang++ (version 3.3) or the intel c++ compiler (versions 12.1 and 13.1), compilation succeeds without errors. When compiling the same test case with g++ (version 4.8.1 from MacPorts, running OSX Mavericks) the following errors are shown:

cast.cc: In function 'int main()':
cast.cc:21:9: error: cannot allocate an object of abstract type 'A'
 do_it(c);
        ^
cast.cc:1:8: note:   because the following virtual functions are pure within 'A':
struct A
       ^
cast.cc:3:15: note: 	virtual void A::do_it() const
 virtual void do_it() const = 0;

              ^

I get the same errors when i try to compile the test case with g++ (versions 4.8.1, 4.7.0, 4.6.1, 4.3.4, 3.3.6) running on SUSE Linux.

Basically I have an abstract base class A and some implementation B. Another class C provides a conversion operator to B. When passing instances of C to functions that take const references of A clang++ and icpc is able to find the conversion to B and is then able to convert the temporary instance of B to a const reference of A. I think, in the same case, g++ tries to make a temporary instance of A initialized with the instance of C which is not possible. 

A workaround for this problem is to explicitly convert the instance of C to B like this:

do_it((B)c);

But then it would be nice if this is not necessary.

Here is the output of gcc-mp-4.8 -v
Using built-in specs.
COLLECT_GCC=gcc-mp-4.8
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin13/4.8.1/lto-wrapper
Target: x86_64-apple-darwin13
Configured with: /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_lang_gcc48/gcc48/work/gcc-4.8.1/configure --prefix=/opt/local --build=x86_64-apple-darwin13 --enable-languages=c,c++,objc,obj-c++,lto,fortran,java --libdir=/opt/local/lib/gcc48 --includedir=/opt/local/include/gcc48 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-4.8 --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-4.8 --with-gxx-include-dir=/opt/local/include/gcc48/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --with-cloog=/opt/local --enable-cloog-backend=isl --disable-cloog-version-check --enable-stage1-checking --disable-multilib --enable-lto --enable-libstdcxx-time --with-as=/opt/local/bin/as --with-ld=/opt/local/bin/ld --with-ar=/opt/local/bin/ar --with-bugurl=https://trac.macports.org/newticket --with-pkgversion='MacPorts gcc48 4.8.1_3'
Thread model: posix
gcc version 4.8.1 (MacPorts gcc48 4.8.1_3)
Comment 1 Daniel Krügler 2013-10-30 13:09:50 UTC
This is related to the core language issues

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1650
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1604

See also bug 57610. It seems that after bringing forward the example code from the submitter of bug 57610 that the committee decided to leave the current wording and this would make the here discussed example well-formed.
Comment 2 Paolo Carlini 2015-03-24 16:53:42 UTC
And indeed current trunk accepts it. I'm adding the testcase and closing the bug.
Comment 3 paolo@gcc.gnu.org 2015-03-24 17:22:58 UTC
Author: paolo
Date: Tue Mar 24 17:22:27 2015
New Revision: 221640

URL: https://gcc.gnu.org/viewcvs?rev=221640&root=gcc&view=rev
Log:
2015-03-24  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58923
	* g++.dg/other/virtual3.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/other/virtual3.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 4 Paolo Carlini 2015-03-24 17:28:25 UTC
Done.