[clang] Fix compiler crash with `static operator()` when lifetime safety is enabled (PR #187853)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Mar 21 04:13:40 PDT 2026
https://github.com/NeKon69 created https://github.com/llvm/llvm-project/pull/187853
This PR removes the first argument from the `Args` list (which is `S()`) before doing lifetime safety checks to ensure correct indexing.
It also adds a test to prevent regressions in the future
Fixes #187426
<details>
<summary>Bug details</summary>
When calling a `static operator()` directly (with `S()(...)`), we also store `S()` in `Args` as the first argument, so all indexing is off by one. The most interesting part is that `S::operator()(...)` works correctly and does not add `S()` at the beginning of the argument list, so it does not crash during lifetime checks.
This solution is probably not the cleanest, but I would love to hear feedback on where to put it!
</details>
>From 43a4f3b73d719a30a65d2ee3f033953566b6c9e7 Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Sat, 21 Mar 2026 11:57:27 +0300
Subject: [PATCH 1/2] apply basic fix
---
clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 3259505584c9f..954f051914989 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -20,6 +20,7 @@
#include "clang/Analysis/Analyses/LifetimeSafety/Origins.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/CFG.h"
+#include "clang/Basic/OperatorKinds.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Casting.h"
@@ -655,6 +656,13 @@ void FactsGenerator::handleFunctionCall(const Expr *Call,
// All arguments to a function are a use of the corresponding expressions.
for (const Expr *Arg : Args)
handleUse(Arg);
+
+ if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(Call);
+ OCE && OCE->getOperator() == OO_Call && FD->isStatic()) {
+ // Ignore first element
+ Args = Args.slice(1);
+ }
+
handleInvalidatingCall(Call, FD, Args);
handleMovedArgsInCall(FD, Args);
if (!CallList)
>From 8a828b75150c4f05ab0e33df93495e78298d7b2b Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Sat, 21 Mar 2026 13:33:40 +0300
Subject: [PATCH 2/2] add test
---
clang/test/Sema/warn-lifetime-safety.cpp | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp
index bd09bb70e9a11..974a0b4a32b2a 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -2101,4 +2101,13 @@ void pointer_in_array_use_after_scope() {
(void)*arr[0]; // Should warn.
}
+struct S {
+ static S operator()(int, int&&);
+};
+
+void indexing_with_static_operator() {
+ // no warnings expected
+ S()(1, 2);
+}
+
} // namespace array
More information about the cfe-commits
mailing list