https://github.com/steakhal created 
https://github.com/llvm/llvm-project/pull/191058

This is a use-after-free.
Codegen would drop the AST before starting the optimizations on the LLVM IR 
level. This means that the ASTConsumers of the SSAF extractors only had 
dangling TU Decls etc.

For now, let's override this option to force-keep the AST alive. Note that 
PluginActions already did the same if their consumers were added after the main 
frontend-action.
See:
https://github.com/llvm/llvm-project/blob/69e0367e8221b8002b5d438fb70ff3daf36257fc/clang/lib/Frontend/FrontendAction.cpp#L470
```c++
CI.getCodeGenOpts().ClearASTBeforeBackend = false;
```

Long term, we could think about the stability implications of running the 
extractors before codegen to be able to drop the AST, thus save memory for 
codegen.
However, that would mean that if any of the virtual callbacks of the 
ASTConsumers (extractors) would crash/fail, it would drag down the whole 
process.
If extractors would only use the HandleTranslationUnitDecl callback, then we 
could wrap our `TUSummaryRunner` multiplexer in a crash-safe 
`CrashRecoveryContext` - which would ensure that only the runner would fail, 
but would continue for codegen.

Personally, I don't really like this continue-after-extractors-crash, because 
I'd not put my life on the binary generated such an event. And if that's the 
case, then what's the point...

Nevertheless, let's force keep the AST for now.

From a7886e46055f73f370ff72bd6c14440e2cf982f6 Mon Sep 17 00:00:00 2001
From: Balazs Benics <[email protected]>
Date: Wed, 8 Apr 2026 22:11:10 +0100
Subject: [PATCH] [clang][ssaf] Preserve AST in after codegen for SSAF
 extractors

This is a use-after-free.
Codegen would drop the AST before starting the optimizations on the
LLVM IR level. This means that the ASTConsumers of the SSAF extractors
only had dangling TU Decls etc.

For now, let's override this option to force-keep the AST alive.
Note that PluginActions already did the same if their consumers were
added after the main frontend-action.
See:
https://github.com/llvm/llvm-project/blob/69e0367e8221b8002b5d438fb70ff3daf36257fc/clang/lib/Frontend/FrontendAction.cpp#L470
```
CI.getCodeGenOpts().ClearASTBeforeBackend = false;
```

Long term, we could think about the stability implications of running
the extractors before codegen to be able to drop the AST, thus save
memory for codegen.
However, that would mean that if any of the virtual callbacks of the
ASTConsumers (extractors) would crash/fail, it would drag down the whole
process.
If extractors would only use the HandleTranslationUnitDecl callback,
then we could wrap our `TUSummaryRunner` multiplexer in a crash-safe
`CrashRecoveryContext` - which would ensure that only the runner would
fail, but would continue for codegen.

Personally, I don't really like this continue-after-extractors-crash,
because I'd not put my life on the binary generated such an event.
And if that's the case, then what's the point...

Nevertheless, let's force keep the AST for now.
---
 .../TUSummaryExtractorFrontendAction.cpp         |  1 +
 .../extraction-works-alongside-compilation.cpp   | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)
 create mode 100644 
clang/test/Analysis/Scalable/extraction-works-alongside-compilation.cpp

diff --git 
a/clang/lib/ScalableStaticAnalysisFramework/Frontend/TUSummaryExtractorFrontendAction.cpp
 
b/clang/lib/ScalableStaticAnalysisFramework/Frontend/TUSummaryExtractorFrontendAction.cpp
index d4bf8d4a63fa4..1c5170e354fb5 100644
--- 
a/clang/lib/ScalableStaticAnalysisFramework/Frontend/TUSummaryExtractorFrontendAction.cpp
+++ 
b/clang/lib/ScalableStaticAnalysisFramework/Frontend/TUSummaryExtractorFrontendAction.cpp
@@ -175,6 +175,7 @@ 
TUSummaryExtractorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
     return nullptr;
 
   if (auto Runner = TUSummaryRunner::create(CI, InFile)) {
+    CI.getCodeGenOpts().ClearASTBeforeBackend = false;
     std::vector<std::unique_ptr<ASTConsumer>> Consumers;
     Consumers.reserve(2);
     Consumers.push_back(std::move(WrappedConsumer));
diff --git 
a/clang/test/Analysis/Scalable/extraction-works-alongside-compilation.cpp 
b/clang/test/Analysis/Scalable/extraction-works-alongside-compilation.cpp
new file mode 100644
index 0000000000000..0077d557e31bc
--- /dev/null
+++ b/clang/test/Analysis/Scalable/extraction-works-alongside-compilation.cpp
@@ -0,0 +1,16 @@
+// DEFINE: %{filecheck} = FileCheck %s --match-full-lines --check-prefix
+// DEFINE: %{codegen} = %clang -c %s -o %t.o -mllvm -debug-only=codegenaction 
2>&1
+
+// The codegen action should not clear the AST before running codegen.
+// Codegen should otherwise clear the AST if ran without extraction.
+
+// RUN: rm -rf %t.o %t.json
+// RUN: %{codegen} | grep "Clearing AST"
+
+// RUN: rm -rf %t.o %t.json
+// RUN: %{codegen} \
+// RUN:   --ssaf-extract-summaries=CallGraph \
+// RUN:   --ssaf-tu-summary-file=%t.json \
+// RUN: | not grep "Clearing AST"
+
+void empty() {}

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

Reply via email to