[clang] [LifetimeSafety] Fix crash on explicit object member functions (PR #212154)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 26 22:15:29 PDT 2026
https://github.com/arhwx updated https://github.com/llvm/llvm-project/pull/212154
>From ef4a173b0d6a9c13a7fe99a490e34b09e4e2aa83 Mon Sep 17 00:00:00 2001
From: arhwx <arahwrm at gmail.com>
Date: Sun, 26 Jul 2026 18:08:56 -0400
Subject: [PATCH 1/2] [LifetimeSafety] Fix crash on explicit object member
functions
handleMovedArgsInCall assumed the object argument is absent
from FunctionDecl::parameters() and applied a one parameter
offset. An explicit object parameter is a regular
ParmVarDecl, so the offset misaligned arguments with
parameters and the assert dereferenced a null OriginList.
Fixes #204210
---
.../Analysis/LifetimeSafety/FactsGenerator.cpp | 3 ++-
.../explicit-object-param-no-crash.cpp | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
create mode 100644 clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 466bb2185c6d8..e858e0b54688b 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -911,7 +911,8 @@ void FactsGenerator::handleMovedArgsInCall(const FunctionDecl *FD,
ArrayRef<const Expr *> Args) {
unsigned IsInstance = 0;
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD);
- MD && MD->isInstance() && !isa<CXXConstructorDecl>(FD)) {
+ MD && !isa<CXXConstructorDecl>(FD) &&
+ MD->isImplicitObjectMemberFunction()) {
IsInstance = 1;
// std::unique_ptr::release() transfers ownership.
// Treat it as a move to prevent false-positive warnings when the unique_ptr
diff --git a/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp b/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
new file mode 100644
index 0000000000000..56615437ab1ae
--- /dev/null
+++ b/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -std=c++23 -verify -fsyntax-only -Wlifetime-safety
+
+// expected-no-diagnostics
+
+// Explicit object member functions must not be treated as having an implicit
+// object argument.
+struct Foo {
+ template <typename T>
+ int get(this Foo &&self, T) {
+ return self.field;
+ }
+
+ int field;
+};
+
+void call() {
+ Foo().get(0);
+}
>From 549b8ce565201f3839f43de668de0a3982251c87 Mon Sep 17 00:00:00 2001
From: arhwx <arahwrm at gmail.com>
Date: Mon, 27 Jul 2026 01:15:03 -0400
Subject: [PATCH 2/2] [LifetimeSafety] Add explicit object parameter test
coverage
---
.../explicit-object-param-no-crash.cpp | 32 +++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp b/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
index 56615437ab1ae..159c342f15527 100644
--- a/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
+++ b/clang/test/Sema/LifetimeSafety/explicit-object-param-no-crash.cpp
@@ -13,6 +13,38 @@ struct Foo {
int field;
};
+struct Base {};
+struct Derived : Base {
+ int base(this Base &&, int);
+};
+
+template <typename T>
+struct Crtp {
+ template <typename Self>
+ int deduced(this Self &&self, T) {
+ return self.field;
+ }
+};
+
+struct Widget : Crtp<int> {
+ int field;
+};
+
+struct NoMove {
+ NoMove() = default;
+ NoMove(NoMove &&) = delete;
+ NoMove(const NoMove &) = delete;
+
+ int get(this NoMove &&self, int) {
+ return self.field;
+ }
+
+ int field;
+};
+
void call() {
Foo().get(0);
+ Derived().base(0);
+ Widget().deduced(0);
+ NoMove().get(0);
}
More information about the cfe-commits
mailing list