<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 - Instantiation backtrace omits important element"
   href="https://bugs.llvm.org/show_bug.cgi?id=47713">47713</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Instantiation backtrace omits important element
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </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>bballo@mozilla.com
          </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>Given the following (invalid) code:

  struct Noncopyable {
    Noncopyable(const Noncopyable&) = delete;
  };

  template <class T>
  struct Wrapper2 {
    T storage;
    Wrapper2(const T& val) : storage{val} {}
  };

  template <class T>
  struct Wrapper {
    Wrapper2<T> storage;
    constexpr Wrapper(const T& val) : storage{val} {}
  };

  Wrapper<Noncopyable> foo(Noncopyable& a) { return Wrapper<Noncopyable>(a); }

compiling with clang (any recent version including trunk) with -std=c++17 gives
the following errors:

  test.cpp:8:28: error: call to deleted constructor of 'Noncopyable'
    Wrapper2(const T& val) : storage{val} {}
                           ^      ~~~~~
  test.cpp:14:37: note: in instantiation of member function
'Wrapper2<Noncopyable>::Wrapper2' requested here
    constexpr Wrapper(const T& val) : storage{val} {}
                                    ^
  test.cpp:2:3: note: 'Noncopyable' has been explicitly marked deleted here
    Noncopyable(const Noncopyable&) = delete;
    ^

Observe that the backtrace omits a key element, the one that points to the
point of instantiation of Wrapper<Noncopyable> on the last line of the file.

If you image the wrapper classes being defined in utility headers, and the
point of instantiation being somewhere in a large translation unit, seeing this
error can leave you searching for a long time to find the point of
instantiation that you need to actually fix.

Making any of the following changes makes the desired backtrace element appear:

  * Making the constructor of Wrapper not constexpr
  * Making the constructor of Wrapper2 constexpr
  * Using -std=c++14 rather than -std=c++17</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>