<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 - [clangd] macro definition causes clangd to assert"
   href="https://bugs.llvm.org/show_bug.cgi?id=45428">45428</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[clangd] macro definition causes clangd to assert
          </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>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Tooling
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>vince.a.bridgers@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>I came across a case in proprietary source code that causes clangd to assert,
and distilled the problem into a a very simple test case that can be applied to
clang/unittests/Tooling/Syntax/TokensTest.cpp. 

I bisected the source tree, and the assert started appearing at git sha
"5e69f27ef7086287519d0c04192108d322bd6e82 - [Syntax] Do not glue multiple empty
PP expansions to a single mapping". 

There is a comment in that patch that appears suspicious ... 

clang/include/clang/Tooling/Syntax/Tokens.h
~L160: +/// FIXME: allow mappings into macro arguments.

Maybe related?

Ilya, could you have a look at this when you get a chance?

Thanks - Vince 


The macro test case is:

#define N 42 
#define M2(a1,...) {__VA_ARGS__;}
#define M1(a2,...) M2(a2,__VA_ARGS__))
#define M0  M1
M0(0,N);

Simple patch ... 
diff --git a/clang/unittests/Tooling/Syntax/TokensTest.cpp
b/clang/unittests/Tooling/Syntax/TokensTest.cpp
index 256096d..e924dea 100644
--- a/clang/unittests/Tooling/Syntax/TokensTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TokensTest.cpp
@@ -484,6 +484,21 @@ file './input.cpp'
     ['EMPTY'_9, 'EMPTY_FUNC'_10) => ['<eof>'_0, '<eof>'_0)
     ['EMPTY_FUNC'_10, '<eof>'_18) => ['<eof>'_0, '<eof>'_0)
 )"},
+      // New issue: Should not crash.
+      // Verification portion of this TBD
+      {R"cpp(
+    #define N 42 
+    #define M2(a1,...) {__VA_ARGS__;}
+    #define M1(a2,...) M2(a2,__VA_ARGS__))
+    #define M0  M1
+    M0(0,N);
+    )cpp",
+       R"(expanded tokens:
+  <empty>
+file './input.cpp'
+  spelled tokens:
+  mappings:
+)"},
       // File ends with a macro replacement.
       {R"cpp(
     #define FOO 10+10;

Obfuscated debug output and assertion message... 

Trying /repo/einvbri/clangd-repro/.clang-format...
Trying /repo/einvbri/clangd-repro/_clang-format...
Trying /repo/einvbri/.clang-format...
Trying /repo/einvbri/_clang-format...
Trying /repo/.clang-format...
Trying /repo/_clang-format...
Trying /.clang-format...
Trying /_clang-format...
Token: Token(`void`, void, length = 4)
Token: Token(`foo`, identifier, length = 3)
Token: Token(`(`, l_paren, length = 1)
Token: Token(`void`, void, length = 4)
Token: Token(`)`, r_paren, length = 1)
Token: Token(`{`, l_brace, length = 1)
Token: Token(`{`, l_brace, length = 1)
Token: Token(`42`, numeric_constant, length = 2)
Token: Token(`;`, semi, length = 1)
Token: Token(`}`, r_brace, length = 1)
Token: Token(`)`, r_paren, length = 1)
Token: Token(`;`, semi, length = 1)
Token: Token(`}`, r_brace, length = 1)
Token: Token(``, eof, length = 0)
clangd: <root>/llvm/clang/lib/Tooling/Syntax/Tokens.cpp:620: void
clang::syntax::TokenCollector::Builder::consumeMapping(clang::syntax::TokenBuffer::MarkedFile&,
unsigned int, unsigned int, unsigned int, unsigned int&): Assertion
`!HitMapping && "recursive macro expansion?"' failed.</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>