<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Incorrect overload resolution when performing direct initialization"
   href="https://bugs.llvm.org/show_bug.cgi?id=48598">48598</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Incorrect overload resolution when performing direct initialization
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>11.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++17
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>karzh@mail.ru
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider direct initialization of an object of type B with an lvalue of type A
as an initializer. The following example compiles successfully as C++14 but
fails to compile as C++17 (<a href="https://godbolt.org/z/dhs3Wv">https://godbolt.org/z/dhs3Wv</a>):
---------------------------
struct A;

struct B
{
    B(const A&) { }
    B(const B&) { }
};

struct A
{
    operator B () = delete;
};

int main()
{
    A a;
    B&& b = B(a);
}
---------------------------

In C++17 mode clang reports the access to deleted operator and presents a list
of candidate functions:
---------------------------
<source>:17:13: error: functional-style cast from 'A' to 'B' uses deleted
function
    B&& b = B(a);
            ^~~
<source>:11:5: note: candidate function has been explicitly deleted
    operator B () = delete;
    ^
<source>:5:5: note: candidate constructor
    B(const A&) { }
    ^
<source>:6:5: note: candidate constructor
    B(const B&) { }
    ^
---------------------------

According to [over.match.ctor]:
"When objects of class type are direct-initialized, ..., overload resolution
selects the constructor. For direct-initialization ... the candidate functions
are all the constructors of the class of the object being initialized".

Therefore, the operator in the above example should not be included in the
candidate list. When considering constructors, the first one (taking const A&)
should win, since it doesn't require user-defined conversion.

A similar problem occurs when using an rvalue of type A as an initializer.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>