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

>From f1b5bdc3c76abfb86675ee0d95a6c4e9f83420a7 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/Parse/Parser.h            |  3 +-
 .../cxx-template-id-tentative-uaf-crash.cpp   | 81 +++++++++++++++++++
 2 files changed, 83 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Parser/cxx-template-id-tentative-uaf-crash.cpp

diff --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 6913c42884a36..79f62c2e8d028 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -7964,7 +7964,8 @@ class Parser : public CodeCompletionHandler {
     if (DelayTemplateIdDestruction)
       return;
     if (!TemplateIds.empty() &&
-        (Tok.is(tok::eof) || !PP.mightHavePendingAnnotationTokens()))
+        (Tok.is(tok::eof) || !PP.mightHavePendingAnnotationTokens()) &&
+        Tok.isNot(tok::annot_template_id))
       DestroyTemplateIds();
   }
   void DestroyTemplateIds();
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