[Bug c++/70737] Invalid C++ code compiles when using explicit template conversions
matteo at mitalia dot net
gcc-bugzilla@gcc.gnu.org
Fri May 13 12:17:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70737
Matteo Italia <matteo at mitalia dot net> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |matteo at mitalia dot net
--- Comment #2 from Matteo Italia <matteo at mitalia dot net> ---
Templates don't seem to have a relevant role here, I found that this simpler
test case exhibits the same problem:
struct A {
explicit operator bool();
operator int();
operator double();
};
bool foo(A& a) {
return a;
}
bool bar(A& a) {
return bool(a);
}
As in Andrea's example, `foo`'s code is not valid, since `operator bool` is
disabled (it's marked as explicit), and it's ambiguous whether `operator int`
or `operator double` should be invoked.
clang correctly refuses to compile this snippet (https://godbolt.org/g/lZa2Qx),
while all gcc>=4.6 (and <=6.1) I tried on gcc.godbolt.org compile `foo` to a
no-op function (`rep ret` on x86), thus leading to garbage being returned:
foo(A&):
rep ret
bar(A&):
jmp A::operator bool()
(https://godbolt.org/g/xmrMGN)
(here -O3 optimizes the tail call and removes some stack setup/cleanup noise,
but the problem is present at all optimization levels)
So, the core of the bug seems to be that gcc discards completely a conversion
that becomes ambiguous once the "obvious" candidate is discarded for being
marked as `explicit`.
The gcc 4 series at least issued a dubious "warning: control reaches end of
non-void function [-Wreturn-type]", from gcc 5 onwards even this warning
disappeared (although, this may save you in this artificial example, in my
original code gcc dropped a conditional assignment to an already-initialized
variable, so the issue was completely silent).
More information about the Gcc-bugs
mailing list