<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 - define of <=> spaceship causes spurious warning with Wc++2a-compat"
   href="https://bugs.llvm.org/show_bug.cgi?id=36925">36925</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>define of <=> spaceship causes spurious warning with Wc++2a-compat
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>6.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </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>karkhaz@karkhaz.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Clang emits this warning when compiling C++ code that contains a define for the
spaceship operator:

    foo.cpp:4:12: warning: '<=>' is a single token in C++2a; add a space to 
    avoid a change in behavior [-Wc++2a-compat]
    #define op <=>
              ^

Reproduce by compiling this code:

    #include <cstring>
    #include <cassert>

    #define op <=>
    #define xstr(s) str(s)
    #define str(s) #s

    const char *s1 = xstr(op);
    const char *s2 = "<=>";

    int main(int argc, char *argv[])
    {
      assert(strcmp(s1, s2) == 0);
      return 0;
    }

I do not expect this code to emit that warning, because the #define should be
preprocessed away. When the spaceship is used in the code (in the assignment to
s1), it has been stringified, so clang should not treat it as an operator.

Although a warning is emitted, the code compiles correctly (i.e. the string s1
is set to "<=>" and thus the assertion succeeds). So although clang is warning
about <=> being a token, it still knows to preprocess it to a string.

When only preprocessing the file using `clang -E`, the warning is still emitted
(I do not expect this behaviour), and the two declarations are compiled to the
following (as expected):

      const char *s1 = "<=>";
      const char *s2 = "<=>";

I have reproduced this behaviour with both the 6.0 release of Clang, and ToT as
of 2018-03-28 (LLVM 2c3af0c1 and clang 60cec38f) on Linux.

I found it difficult to bisect because Clang and LLVM are in different
repositories, even using a script similar to this one [0]. I would be happy to
bisect if somebody could point me to a maintained combined LLVM+clang
repository (using submodules or whatever) or let me know what your approach to
bisecting is.

The commit that introduced the warning and preprocessor code is is daf599b1b13,
so I'm copying in Richard Smith.

Thank you!

[0] <a href="https://lists.llvm.org/pipermail/llvm-dev/2014-July/074489.html">https://lists.llvm.org/pipermail/llvm-dev/2014-July/074489.html</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>