https://github.com/AZero13 updated 
https://github.com/llvm/llvm-project/pull/221102

>From 536b616a3df156247daa1db7e10d19c83f8584fc Mon Sep 17 00:00:00 2001
From: AZero13 <[email protected]>
Date: Thu, 3 Sep 2026 19:44:13 -0400
Subject: [PATCH] [Clang][Parse] Fix heap-use-after-free when cleaning up
 TemplateIds

When parsing deeply nested statement expressions, the preprocessor
may exit caching mode while the parser's current token is still
an `annot_template_id`. When `MaybeDestroyTemplateIds()` runs at
the end of a statement, it aggressively destroyed all template ID
annotations because caching mode was off. This left the current
token holding a dangling pointer to a freed `TemplateIdAnnotation`,
causing a crash during error recovery when extracting the
`TemplateNameLoc`.

This patch adds a check to ensure we don't destroy `TemplateIds` if
the parser is actively holding onto an `annot_template_id` in `Tok`.

Fixes #175702
---
 clang/include/clang/Lex/Preprocessor.h        |  6 +-
 .../cxx-template-id-tentative-uaf-crash.cpp   | 81 +++++++++++++++++++
 2 files changed, 85 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Parser/cxx-template-id-tentative-uaf-crash.cpp

diff --git a/clang/include/clang/Lex/Preprocessor.h 
b/clang/include/clang/Lex/Preprocessor.h
index d94f3d2cbe8ed..c1c4e84771dcf 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -2051,9 +2051,11 @@ class Preprocessor {
                             void *AnnotationVal);
 
   /// Determine whether it's possible for a future call to Lex to produce an
-  /// annotation token created by a previous call to EnterAnnotationToken.
+  /// annotation token created by a previous call to EnterAnnotationToken,
+  /// or if the parser is currently holding an annotation token that was just
+  /// retrieved from the cache.
   bool mightHavePendingAnnotationTokens() {
-    return CurLexerCallback != CLK_Lexer;
+    return CurLexerCallback != CLK_Lexer || !CachedTokens.empty();
   }
 
   /// Update the current token to represent the provided
diff --git a/clang/test/Parser/cxx-template-id-tentative-uaf-crash.cpp 
b/clang/test/Parser/cxx-template-id-tentative-uaf-crash.cpp
new file mode 100644
index 0000000000000..3e7d309c7d312
--- /dev/null
+++ b/clang/test/Parser/cxx-template-id-tentative-uaf-crash.cpp
@@ -0,0 +1,81 @@
+// RUN: not %clang_cc1 -fsyntax-only -Wno-everything %s
+
+
+int main() {
+  typedef struct tree_el node i, sum = 0;
+  for (i = 1; i <= LAST; i++) {
+    sum += i;
+  }
+  printf("sum = %d\n", sum);
+  return printout(printf(printf(
+                    i < cnt, cnt & (printout(printf(printf(
+                                 i < cnt,
+                                 0x5b * printf(i < cnt,
+                                               0x5b * (({ cnt & (printf(printf(
+                                                                    i < cnt,
+                                                                    0x5b * (1 
/ (1 / (cnt & (printout(
+                                                                               
          printf(i < cnt, 0x5b * (1 / (({
+                                                                               
                         if ("%f%f%f")
+                                                                               
                           break;
+                                                                               
                         -((0.0 / (0xaf >> 3 &
+                                                                               
                                   (((0xaf >> 3 &
+                                                                               
                                      (({ for (i = 0, bi = i < 10; i < length;
+                                                                               
                                             ++i, ++bi)
+                                                                               
                                           if (cnt < (0xaf >> 3 & 1) >> 3)
+                                                                               
                                             break;
+                                                                               
                                         cnt < (0xaf >> 3 & 1) >> 3;
+                                                                               
                                       })))
+                                                                               
                                     >> 0xb9 & 1)
+                                                                               
                                    >> 0xb9 & 1)))))
+                                                                               
                           ;
+                                                                               
                       })))
+                                                                               
                  ) >>
+                                                                               
              3 &
+                                                                               
          1)))
+                                                                               
)))) >>
+                                                               3 &
+                                                           1)))
+                                                      ) >>
+                                                  3 &
+                                              1);
+  return 0;
+  i;
+  return (node())->val;
+})))
+                                                ))),
+                                  sum) >>
+                              3 &
+                          1);
+  return ((((({ cnt & (printf(printf(
+                      i < cnt,
+                      0x5b * (({ cnt & (printf(printf(
+                                           i < cnt,
+                                           0x5b * (1 / (1 / (cnt & (printout(
+                                                                printf(i < 
cnt, 0x5b * (1 / (({
+                                                                               
if ("%f%f%f")
+                                                                               
  break;
+                                                                               
-((0.0 / (0xaf >> 3 &
+                                                                               
          (((0xaf >> 3 &
+                                                                               
             (({ for (i = 0, bi = i < 10; i < length; ++i, ++bi)
+                                                                               
                  if (cnt < (0xaf >> 3 & 1) >> 3)
+                                                                               
                    break;
+                                                                               
                cnt < (0xaf >> 3 & 1) >> 3;
+                                                                               
              })))
+                                                                               
            >> 0xb9 & 1)
+                                                                               
           >> 0xb9 & 1)))))
+                                                                               
  ;
+                                                                             
})))
+                                                                    ) >>
+                                                                3 &
+                                                            1)))
+                                                      )))) >>
+                                      3 &
+                                  1)))
+                         ) >>
+                     3 &
+                 1)))
+          ,
+          sum)) >>
+      3 &
+  1)));
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to