[clang] [clang] Fix alias declaration fix-it location for token-split '>>' (PR #184555)

via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 3 23:04:44 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: 张之阳 (luoliwoshang)

<details>
<summary>Changes</summary>

Fixes #<!-- -->184425

When parsing an alias declaration like:

```c++
using A = X<int>>;
```

clang splits `>>` into two `>` tokens while parsing templates. In this token-split case, `Lexer::getLocForEndOfToken` was advancing past the already-correct expansion end location, which moved the fix-it insertion point too far right (at `;` instead of before the second `>`).

This patch detects token-split expansion ranges and returns the expansion end location directly after `isAtEndOfMacroExpansion`, avoiding the extra token-length advance.

Also adds a regression test in `clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp` that checks the fix-it insertion location is `{4:17-4:17}` for the example above.

Local validation:
- `tools/clang/lib/Lex/CMakeFiles/obj.clangLex.dir/Lexer.cpp.o` builds successfully
- full `clang` build/test still in progress


---
Full diff: https://github.com/llvm/llvm-project/pull/184555.diff


2 Files Affected:

- (modified) clang/lib/Lex/Lexer.cpp (+9) 
- (added) clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp (+7) 


``````````diff
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index cbf0c77232db7..f9f9a57330ac3 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -862,8 +862,17 @@ SourceLocation Lexer::getLocForEndOfToken(SourceLocation Loc, unsigned Offset,
     return {};
 
   if (Loc.isMacroID()) {
+    // Token-split expansion ranges (for example, when splitting '>>' into two
+    // '>' tokens while parsing templates) are character ranges, so the
+    // expansion end location already points just past the split token.
+    const bool IsTokenSplitRange =
+        !SM.getSLocEntry(SM.getFileID(Loc))
+             .getExpansion()
+             .isExpansionTokenRange();
     if (Offset > 0 || !isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc))
       return {}; // Points inside the macro expansion.
+    if (IsTokenSplitRange)
+      return Loc;
   }
 
   unsigned Len = Lexer::MeasureTokenLength(Loc, SM, LangOpts);
diff --git a/clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp b/clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp
new file mode 100644
index 0000000000000..fc683431a958a
--- /dev/null
+++ b/clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp
@@ -0,0 +1,7 @@
+// RUN: not %clang_cc1 -fsyntax-only -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+template <typename> struct X {};
+using A = X<int>>;
+
+// CHECK: error: expected ';' after alias declaration
+// CHECK: fix-it:"{{.*}}":{4:17-4:17}:";"

``````````

</details>


https://github.com/llvm/llvm-project/pull/184555


More information about the cfe-commits mailing list