[clang] [Sema] Skip ExternalSource query and clear DeleteExprs in incremental mode (PR #192856)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 19 09:46:29 PDT 2026
https://github.com/lucasvallejoo updated https://github.com/llvm/llvm-project/pull/192856
>From b98a1d03542b45ea23412a7f254469c59d24236c Mon Sep 17 00:00:00 2001
From: lucasvallejoo <lucas.valfac at gmail.com>
Date: Sun, 19 Apr 2026 18:46:14 +0200
Subject: [PATCH] [Sema] Skip ExternalSource query and clear DeleteExprs in
incremental mode
In incremental compilation (e.g. ROOT/Cling REPL), ActOnEndOfTranslationUnit()
is called once per user input line rather than once at program end. This caused
two performance issues:
1. ReadMismatchingDeleteExpressions() queried the ExternalSource (PCH/modules)
on every cycle, causing redundant disk I/O that severely degraded performance
in long REPL sessions.
2. DeleteExprs accumulated entries across cycles without being cleared, leading
to unbounded memory growth and O(N^2) redundant AST traversals.
This patch guards the ExternalSource query by checking that incremental processing
is NOT enabled, and adds DeleteExprs.clear() after each analysis pass, following
the same pattern used elsewhere in ActOnEndOfTranslationUnit() for REPL mode.
A regression test is included to verify that warn_mismatched_delete_new
continues to fire correctly in incremental mode after this change.
Patch by Axel Naumann.
Note: This upstreaming effort is part of the preparation for the compiler fellowship program.
---
clang/lib/Sema/Sema.cpp | 7 ++++---
.../SemaCXX/warn-mismatched-delete-incremental.cpp | 12 ++++++++++++
2 files changed, 16 insertions(+), 3 deletions(-)
create mode 100644 clang/test/SemaCXX/warn-mismatched-delete-incremental.cpp
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index ef45d5842c795..6f539a8fbd7b5 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -686,12 +686,12 @@ void Sema::PrintStats() const {
void Sema::diagnoseNullableToNonnullConversion(QualType DstType,
QualType SrcType,
SourceLocation Loc) {
- std::optional<NullabilityKind> ExprNullability = SrcType->getNullability();
+ NullabilityKindOrNone ExprNullability = SrcType->getNullability();
if (!ExprNullability || (*ExprNullability != NullabilityKind::Nullable &&
*ExprNullability != NullabilityKind::NullableResult))
return;
- std::optional<NullabilityKind> TypeNullability = DstType->getNullability();
+ NullabilityKindOrNone TypeNullability = DstType->getNullability();
if (!TypeNullability || *TypeNullability != NullabilityKind::NonNull)
return;
@@ -1670,7 +1670,7 @@ void Sema::ActOnEndOfTranslationUnit() {
}
if (!Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation())) {
- if (ExternalSource)
+ if (ExternalSource && !PP.isIncrementalProcessingEnabled())
ExternalSource->ReadMismatchingDeleteExpressions(DeleteExprs);
for (const auto &DeletedFieldInfo : DeleteExprs) {
for (const auto &DeleteExprLoc : DeletedFieldInfo.second) {
@@ -1678,6 +1678,7 @@ void Sema::ActOnEndOfTranslationUnit() {
DeleteExprLoc.second);
}
}
+ DeleteExprs.clear();
}
AnalysisWarnings.IssueWarnings(Context.getTranslationUnitDecl());
diff --git a/clang/test/SemaCXX/warn-mismatched-delete-incremental.cpp b/clang/test/SemaCXX/warn-mismatched-delete-incremental.cpp
new file mode 100644
index 0000000000000..aba924bae59a1
--- /dev/null
+++ b/clang/test/SemaCXX/warn-mismatched-delete-incremental.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fincremental-extensions -verify %s
+// Regression test for incremental-mode handling of warn_mismatched_delete_new
+// in Sema::ActOnEndOfTranslationUnit(). Ensures the diagnostic fires correctly
+// in incremental mode and that DeleteExprs does not accumulate stale entries
+// across EndOfTU cycles.
+
+struct S {
+ int *p;
+ S() : p(new int[10]) {}
+ ~S() { delete p; } // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
+ // expected-note at -2 {{allocated with 'new[]' here}}
+};
\ No newline at end of file
More information about the cfe-commits
mailing list