Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Overloading resolved to pointer argument instead of initializer_list #46673

Open Quuxplusone opened 4 years ago

Quuxplusone commented 4 years ago
Bugzilla Link PR47704
Status NEW
Importance P normal
Reported by Paweł Bylica (chfast@gmail.com)
Reported on 2020-10-01 09:38:26 -0700
Last modified on 2020-10-01 14:15:46 -0700
Version trunk
Hardware All All
CC blitzrakete@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, hstong@ca.ibm.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
For the following C++11 code:

#include <initializer_list>

struct V
{
    V(int) {}
};

inline int f(void*) { return 1; }

inline int f(std::initializer_list<V>) { return 2; }

int invoke_test() { return f({0}); }

The function f invocation f({0}) is resolved to f(void*).
GCC does the opposite.
I believe it should be initializer_list because {} is used.
We also get the -Wbraced-scalar-init warning.

warning: braces around scalar initializer [-Wbraced-scalar-init]

int invoke_test() { return f({0}); }

                             ^~~

https://godbolt.org/z/qj5voh
Quuxplusone commented 4 years ago

The choice between the candidates is determined by the rank of the implicit conversion sequences. The standard conversion from a null pointer constant to void * is a better conversion sequence than the user-defined conversion sequence involving the converting constructor.

Quuxplusone commented 4 years ago

Looks like http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467 is relevant.

Quuxplusone commented 4 years ago

The DR1467 wording does not override the selection between a standard conversion sequence and a user-defined conversion sequence.