[llvm-bugs] [Bug 35207] New: call to conversion operator instead of converting constructor in c++17 during overload resolution

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Nov 5 04:58:49 PST 2017


https://bugs.llvm.org/show_bug.cgi?id=35207

            Bug ID: 35207
           Summary: call to conversion operator instead of converting
                    constructor in c++17 during overload resolution
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: bruno.bugs.contact at gmail.com
                CC: dgregor at apple.com, llvm-bugs at lists.llvm.org

This code compiled by clang trunk with std=c++17 returns 1 
instead of the expected 0 since D::operator C() is called instead of the
apparently better match C::C(const D&). Compiling the code with std=c++14
make this behaviour disappear and 0 is returned as expected.

clang 5 do not have this behaviour.
gcc 7.2 also has this behaviour but 6.4 do not.


Rationale for why 0 should be returned instead of 1 :
(copied from the original post on stackoverflow)

Tentative reading of the standard (latest draft N4687) :

C c(d) is a direct-initialization which is not a copy elision
([dcl.init]/17.6.1). [dcl.init]/17.6.2 tells us that applicable constructors
are enumerated and that the best one is chosen by overload resolution.
[over.match.ctor] tells us that the applicable constructors are in this case
all the constructors.

In this case : C(), C(const C&) and C(const D&) (no move ctor). C() is clearly
not viable and thus is discarded from the overload set. ([over.match.viable])

Constructors have no implicit object parameter and so C(const C&) and C(const
D&) both take exactly one parameter. ([over.match.funcs]/2)

We now go to [over.match.best]. Here we find that we need to determine which of
these two implicit conversion sequences (ICS) is better. The ICS of C(const D&)
only involves a standard conversion sequence, but the ICS of C(const C&)
involves a user-defined conversion sequence.

Therefore C(const D&) should be selected instead of C(const C&).


See the discussion on stackoverflow:
https://stackoverflow.com/questions/47110853/call-to-conversion-operator-instead-of-converting-constructor-in-c17-during-ov

static int ret;
struct D;
struct C {
    C() {}
    C(const C&) {}
    C(const D&) {}
};
struct D {
    operator C() { ret = 1; return C();}
};

int main(){
    D d;
    C c(d);
    return ret;
}


clang++ -v output :

/home/bruno/software/llvm-build/bin/clang++ -v -O0 -g -std=c++17 -Wall -Wextra
-Wno-unused -pedantic bug_DoperatorC_CconstDref_minimal.cpp -o
bug_DoperatorC_CconstDref_minimal && ./bug_DoperatorC_CconstDref_minimal 
clang version 6.0.0 (trunk 317422)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/bruno/software/llvm-build/bin
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/7.2.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.7.4
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.4
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.4.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.2.0
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.2.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
 "/home/bruno/software/llvm-build/bin/clang-6.0" -cc1 -triple
x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -main-file-name
bug_DoperatorC_CconstDref_minimal.cpp -mrelocation-model static -mthread-model
posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases
-munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info
-debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -v -resource-dir
/home/bruno/software/llvm-build/lib/clang/6.0.0 -internal-isystem
/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0
-internal-isystem
/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/x86_64-linux-gnu/c++/7.2.0
-internal-isystem
/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/x86_64-linux-gnu/c++/7.2.0
-internal-isystem
/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0/backward
-internal-isystem /usr/local/include -internal-isystem
/home/bruno/software/llvm-build/lib/clang/6.0.0/include
-internal-externc-isystem /usr/include/x86_64-linux-gnu
-internal-externc-isystem /include -internal-externc-isystem /usr/include -O0
-Wall -Wextra -Wno-unused -pedantic -std=c++17 -fdeprecated-macro
-fdebug-compilation-dir /home/bruno/computer_science/c++/c++learning
-ferror-limit 19 -fmessage-length 168 -fobjc-runtime=gcc -fcxx-exceptions
-fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o
/tmp/bug_DoperatorC_CconstDref_minimal-a28d4c.o -x c++
bug_DoperatorC_CconstDref_minimal.cpp
clang -cc1 version 6.0.0 based upon LLVM 6.0.0svn default target
x86_64-unknown-linux-gnu
ignoring nonexistent directory "/include"
ignoring duplicate directory
"/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/x86_64-linux-gnu/c++/7.2.0"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0

/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/x86_64-linux-gnu/c++/7.2.0
 /usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../include/c++/7.2.0/backward
 /usr/local/include
 /home/bruno/software/llvm-build/lib/clang/6.0.0/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
 "/usr/bin/ld" -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64
-dynamic-linker /lib64/ld-linux-x86-64.so.2 -o
bug_DoperatorC_CconstDref_minimal
/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../x86_64-linux-gnu/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/7.2.0/crtbegin.o
-L/usr/lib/gcc/x86_64-linux-gnu/7.2.0
-L/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../x86_64-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../../lib64 -L/lib/x86_64-linux-gnu
-L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64
-L/usr/lib/x86_64-linux-gnu/../../lib64
-L/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../..
-L/home/bruno/software/llvm-build/bin/../lib -L/lib -L/usr/lib
/tmp/bug_DoperatorC_CconstDref_minimal-a28d4c.o -lstdc++ -lm -lgcc_s -lgcc -lc
-lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/7.2.0/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/7.2.0/../../../x86_64-linux-gnu/crtn.o

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20171105/e8377773/attachment.html>


More information about the llvm-bugs mailing list