<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 - Attributes on templates are mishandled"
   href="https://bugs.llvm.org/show_bug.cgi?id=38302">38302</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Attributes on templates are mishandled
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>trunk
          </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++
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>arthur.j.odwyer@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>cat >test.cc <<EOF
// <a href="https://godbolt.org/g/pqog4L">https://godbolt.org/g/pqog4L</a>
template<class T>
[[noreturn]] void one();

template<>
void one<int>() {}

template<class T>
void two();

template<>
[[noreturn]] void two<int>() {}

EOF
clang++ -std=c++2a -c test.cc

As far as I can tell, this program produces bogus diagnostics in both
directions.
First, the explicit specialization `one<int>` seems to be inheriting
`[[noreturn]]` from the primary template; I believe this is unwanted behavior.

    test.cc:2:18: warning: function declared 'noreturn' should not return
[-Winvalid-noreturn]
    void one<int>() {}
                     ^

Second, Clang complains that the explicit specialization `two<int>` is marked
`[[noreturn]]` when its "first declaration" is not so marked. Clang seems to be
considering the primary template as the "first" declaration of every
specialization (even though the accompanying note nonsensically points to the
specialization's own declaration). This is problematic, because maybe the
programmer wants to apply `[[noreturn]]` NOT to ALL possible instantiations of
the primary template, but only to this one explicit specialization.

    test.cc:9:3: error: function declared '[[noreturn]]' after its first
declaration
    [[noreturn]] void two<int>() {}
      ^
    test.cc:9:19: note: declaration missing '[[noreturn]]' attribute is here
    [[noreturn]] void two<int>() {}
                      ^

After some discussion on Slack, I think what ought to happen here is that the
attribute on the primary template ought to be applied only to instantiations
that come directly from that primary (unspecialized) template; and the
attribute on the explicit specialization ought to be applied only to that
explicit specialization. But we see that Clang doesn't do either of those
things.

This is highly relevant to my interests because of P1144
[[trivially_relocatable]], and I'd love to put together a patch to fix it, but
at least at the moment I'm completely lost as to where I would even start
looking.

See also: <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - clang accepts new dll attributes on explicit instantiation of already instantiated templates"
   href="show_bug.cgi?id=20758">https://bugs.llvm.org/show_bug.cgi?id=20758</a></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>