[clang] [LifetimeSafety] Infer [[clang::lifetimebound]] annotation (PR #171081)
Kashika Akhouri via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 9 04:21:07 PST 2025
https://github.com/kashika0112 updated https://github.com/llvm/llvm-project/pull/171081
>From d9e30d12154c68a956bbf8eabb1a56a572e8e118 Mon Sep 17 00:00:00 2001
From: Kashika Akhouri <akhourik at google.com>
Date: Mon, 8 Dec 2025 06:14:28 +0000
Subject: [PATCH 1/4] Add annotation inference
---
clang/lib/Analysis/LifetimeSafety/Checker.cpp | 17 ++++++++++++++++-
.../Sema/warn-lifetime-safety-suggestions.cpp | 12 ++++++++++++
clang/test/Sema/warn-lifetime-safety.cpp | 16 +++++++++++++++-
3 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index 74792768e2c57..f5236f63da34a 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -55,13 +55,14 @@ class LifetimeChecker {
const LiveOriginsAnalysis &LiveOrigins;
const FactManager &FactMgr;
LifetimeSafetyReporter *Reporter;
+ AnalysisDeclContext &AC;
public:
LifetimeChecker(const LoanPropagationAnalysis &LoanPropagation,
const LiveOriginsAnalysis &LiveOrigins, const FactManager &FM,
AnalysisDeclContext &ADC, LifetimeSafetyReporter *Reporter)
: LoanPropagation(LoanPropagation), LiveOrigins(LiveOrigins), FactMgr(FM),
- Reporter(Reporter) {
+ Reporter(Reporter), AC(ADC) {
for (const CFGBlock *B : *ADC.getAnalysis<PostOrderCFGView>())
for (const Fact *F : FactMgr.getFacts(B))
if (const auto *EF = F->getAs<ExpireFact>())
@@ -70,6 +71,7 @@ class LifetimeChecker {
checkAnnotations(OEF);
issuePendingWarnings();
suggestAnnotations();
+ inferAnnotations();
}
/// Checks if an escaping origin holds a placeholder loan, indicating a
@@ -160,6 +162,19 @@ class LifetimeChecker {
for (const auto &[PVD, EscapeExpr] : AnnotationWarningsMap)
Reporter->suggestAnnotation(PVD, EscapeExpr);
}
+
+ void inferAnnotations() {
+ /// NOTE: This currently only adds the attribute to the function definition
+ /// being analyzed. For full inter-procedural inference to work reliably
+ /// (e.g., with out-of-order definitions), this attribute would also need to
+ /// be added to all other redeclarations of the function.
+ for (const auto &[ConstPVD, EscapeExpr] : AnnotationWarningsMap) {
+ ParmVarDecl *PVD = const_cast<ParmVarDecl *>(ConstPVD);
+ ASTContext &Ctx = AC.getASTContext();
+ auto *Attr = LifetimeBoundAttr::CreateImplicit(Ctx, SourceLocation());
+ PVD->addAttr(Attr);
+ }
+ }
};
} // namespace
diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
index c0f675a301d14..087899b9f5d3f 100644
--- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
@@ -89,6 +89,18 @@ void test_getView_on_temporary() {
(void)sv;
}
+//===----------------------------------------------------------------------===//
+// Annotation Inference Test Cases
+//===----------------------------------------------------------------------===//
+
+View return_view_by_func (View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return return_view_directly(a); // expected-note {{param returned here}}
+}
+
+MyObj* return_pointer_by_func (MyObj* a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return return_pointer_object(a); // expected-note {{param returned here}}
+}
+
//===----------------------------------------------------------------------===//
// Negative Test Cases
//===----------------------------------------------------------------------===//
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp
index 1191469e23df1..251324f968acd 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -Wexperimental-lifetime-safety -Wno-dangling -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -Wexperimental-lifetime-safety -Wno-dangling -Wno-experimental-lifetime-safety-suggestions -verify %s
struct MyObj {
int id;
@@ -552,6 +552,20 @@ const int& get_ref_to_local() {
// expected-note at -1 {{returned here}}
}
+View inference_callee_return_identity(View a) {
+ return a;
+}
+
+View inference_caller_forwards_callee(View a) {
+ return inference_callee_return_identity(a);
+}
+
+View inference_top_level_return_stack_view() {
+ MyObj local_stack;
+ return inference_caller_forwards_callee(local_stack); // expected-warning {{address of stack memory is returned later}}
+ // expected-note at -1 {{returned here}}
+}
+
//===----------------------------------------------------------------------===//
// Use-After-Scope & Use-After-Return (Return-Stack-Address) Combined
// These are cases where the diagnostic kind is determined by location
>From cd528bbe55c053500d8055d3ce0d9b336ca1287d Mon Sep 17 00:00:00 2001
From: Kashika Akhouri <akhourik at google.com>
Date: Mon, 8 Dec 2025 12:54:29 +0000
Subject: [PATCH 2/4] Add more unit tests
---
clang/lib/Analysis/LifetimeSafety/Checker.cpp | 18 ++++-----
.../Sema/warn-lifetime-safety-suggestions.cpp | 28 ++++++++++++++
clang/test/Sema/warn-lifetime-safety.cpp | 38 +++++++++++++++++++
3 files changed, 75 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index f5236f63da34a..c8592a623dd2f 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -55,14 +55,14 @@ class LifetimeChecker {
const LiveOriginsAnalysis &LiveOrigins;
const FactManager &FactMgr;
LifetimeSafetyReporter *Reporter;
- AnalysisDeclContext &AC;
+ ASTContext &AC;
public:
LifetimeChecker(const LoanPropagationAnalysis &LoanPropagation,
const LiveOriginsAnalysis &LiveOrigins, const FactManager &FM,
AnalysisDeclContext &ADC, LifetimeSafetyReporter *Reporter)
: LoanPropagation(LoanPropagation), LiveOrigins(LiveOrigins), FactMgr(FM),
- Reporter(Reporter), AC(ADC) {
+ Reporter(Reporter), AC(ADC.getASTContext()) {
for (const CFGBlock *B : *ADC.getAnalysis<PostOrderCFGView>())
for (const Fact *F : FactMgr.getFacts(B))
if (const auto *EF = F->getAs<ExpireFact>())
@@ -164,15 +164,15 @@ class LifetimeChecker {
}
void inferAnnotations() {
- /// NOTE: This currently only adds the attribute to the function definition
- /// being analyzed. For full inter-procedural inference to work reliably
- /// (e.g., with out-of-order definitions), this attribute would also need to
- /// be added to all other redeclarations of the function.
+ // FIXME: To maximise inference propagation, functions should be analyzed in
+ // post-order of the call graph, allowing inferred annotations to propagate
+ // through the call chain
+ // FIXME: Add the inferred attribute to all redeclarations of the function,
+ // not just the definition being analyzed.
for (const auto &[ConstPVD, EscapeExpr] : AnnotationWarningsMap) {
ParmVarDecl *PVD = const_cast<ParmVarDecl *>(ConstPVD);
- ASTContext &Ctx = AC.getASTContext();
- auto *Attr = LifetimeBoundAttr::CreateImplicit(Ctx, SourceLocation());
- PVD->addAttr(Attr);
+ if (!PVD->hasAttr<LifetimeBoundAttr>())
+ PVD->addAttr(LifetimeBoundAttr::CreateImplicit(AC, PVD->getLocation()));
}
}
};
diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
index 087899b9f5d3f..248179e8ba7b6 100644
--- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
@@ -93,6 +93,7 @@ void test_getView_on_temporary() {
// Annotation Inference Test Cases
//===----------------------------------------------------------------------===//
+namespace correct_order_inference {
View return_view_by_func (View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
return return_view_directly(a); // expected-note {{param returned here}}
}
@@ -100,6 +101,33 @@ View return_view_by_func (View a) { // expected-warning {{param should be mar
MyObj* return_pointer_by_func (MyObj* a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
return return_pointer_object(a); // expected-note {{param returned here}}
}
+} // correct_order_inference
+
+namespace incorrect_order_inference_view {
+View return_view_callee(View a);
+
+// FIXME: No lifetime annotation suggestion when functions are not present in the callee-before-caller pattern
+View return_view_caller(View a) {
+ return return_view_callee(a);
+}
+
+View return_view_callee(View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return a; // expected-note {{param returned here}}
+}
+} // incorrect_order_inference_view
+
+namespace incorrect_order_inference_object {
+View return_object_callee(View a);
+
+// FIXME: No lifetime annotation suggestion warning when functions are not present in the callee-before-caller pattern
+View return_object_caller(View a) {
+ return return_object_callee(a);
+}
+
+View return_object_callee(View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return a; // expected-note {{param returned here}}
+}
+} // incorrect_order_inference_object
//===----------------------------------------------------------------------===//
// Negative Test Cases
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp
index 251324f968acd..8cd1bd8bcc54c 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -552,6 +552,7 @@ const int& get_ref_to_local() {
// expected-note at -1 {{returned here}}
}
+namespace simple_annotation_inference {
View inference_callee_return_identity(View a) {
return a;
}
@@ -565,6 +566,43 @@ View inference_top_level_return_stack_view() {
return inference_caller_forwards_callee(local_stack); // expected-warning {{address of stack memory is returned later}}
// expected-note at -1 {{returned here}}
}
+} // simple_annotation_inference
+
+namespace inference_in_order_with_redecls {
+View inference_callee_return_identity(View a);
+View inference_callee_return_identity(View a) {
+ return a;
+}
+
+View inference_caller_forwards_callee(View a);
+View inference_caller_forwards_callee(View a) {
+ return inference_callee_return_identity(a);
+}
+
+View inference_top_level_return_stack_view() {
+ MyObj local_stack;
+ return inference_caller_forwards_callee(local_stack); // expected-warning {{address of stack memory is returned later}}
+ // expected-note at -1 {{returned here}}
+}
+} // namespace inference_in_order_with_redecls
+
+namespace inference_with_templates {
+template<typename T>
+T* template_identity(T* a) {
+ return a;
+}
+
+template<typename T>
+T* template_caller(T* a) {
+ return template_identity(a);
+}
+
+// FIXME: Fails to detect UAR as template instantiations are deferred to the end of the Translation Unit.
+MyObj* test_template_inference_with_stack() {
+ MyObj local_stack;
+ return template_caller(&local_stack);
+}
+} // inference_with_templates
//===----------------------------------------------------------------------===//
// Use-After-Scope & Use-After-Return (Return-Stack-Address) Combined
>From 211667d1e7044f5e8d5584f54d129e8091f93de7 Mon Sep 17 00:00:00 2001
From: Kashika Akhouri <akhourik at google.com>
Date: Tue, 9 Dec 2025 06:50:04 +0000
Subject: [PATCH 3/4] Introduce new frontend flag for annotation inference
---
clang/include/clang/Basic/LangOptions.def | 2 ++
clang/include/clang/Options/Options.td | 8 ++++++++
clang/lib/Analysis/LifetimeSafety/Checker.cpp | 13 +++++++++----
.../test/Sema/warn-lifetime-safety-suggestions.cpp | 8 ++++----
clang/test/Sema/warn-lifetime-safety.cpp | 2 +-
5 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 40fc66ea12e34..a136432993a3c 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -499,6 +499,8 @@ LANGOPT(BoundsSafety, 1, 0, NotCompatible, "Bounds safety extension for C")
LANGOPT(EnableLifetimeSafety, 1, 0, NotCompatible, "Experimental lifetime safety analysis for C++")
+LANGOPT(EnableLifetimeSafetyInference, 1, 0, NotCompatible, "Experimental lifetime safety inference analysis for C++")
+
LANGOPT(PreserveVec3Type, 1, 0, NotCompatible, "Preserve 3-component vector type")
#undef LANGOPT
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index c6841937c8d39..39c5753e50aed 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -1955,6 +1955,14 @@ defm lifetime_safety : BoolFOption<
BothFlags<[], [CC1Option],
" experimental lifetime safety for C++">>;
+defm lifetime_safety_inference
+ : BoolFOption<"experimental-lifetime-safety-inference",
+ LangOpts<"EnableLifetimeSafetyInference">, DefaultFalse,
+ PosFlag<SetTrue, [], [CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [CC1Option], "Disable">,
+ BothFlags<[], [CC1Option],
+ " experimental lifetime safety inference for C++">>;
+
defm addrsig : BoolFOption<"addrsig",
CodeGenOpts<"Addrsig">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Emit">,
diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index c8592a623dd2f..99071d6b46c1e 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -55,14 +55,14 @@ class LifetimeChecker {
const LiveOriginsAnalysis &LiveOrigins;
const FactManager &FactMgr;
LifetimeSafetyReporter *Reporter;
- ASTContext &AC;
+ ASTContext &AST;
public:
LifetimeChecker(const LoanPropagationAnalysis &LoanPropagation,
const LiveOriginsAnalysis &LiveOrigins, const FactManager &FM,
AnalysisDeclContext &ADC, LifetimeSafetyReporter *Reporter)
: LoanPropagation(LoanPropagation), LiveOrigins(LiveOrigins), FactMgr(FM),
- Reporter(Reporter), AC(ADC.getASTContext()) {
+ Reporter(Reporter), AST(ADC.getASTContext()) {
for (const CFGBlock *B : *ADC.getAnalysis<PostOrderCFGView>())
for (const Fact *F : FactMgr.getFacts(B))
if (const auto *EF = F->getAs<ExpireFact>())
@@ -71,7 +71,11 @@ class LifetimeChecker {
checkAnnotations(OEF);
issuePendingWarnings();
suggestAnnotations();
- inferAnnotations();
+ // Annotation inference is currently guarded by a frontend flag. In the
+ // future, this might be replaced by a design that differentiates between
+ // explicit and inferred findings with separate warning groups.
+ if (AST.getLangOpts().EnableLifetimeSafetyInference)
+ inferAnnotations();
}
/// Checks if an escaping origin holds a placeholder loan, indicating a
@@ -172,7 +176,8 @@ class LifetimeChecker {
for (const auto &[ConstPVD, EscapeExpr] : AnnotationWarningsMap) {
ParmVarDecl *PVD = const_cast<ParmVarDecl *>(ConstPVD);
if (!PVD->hasAttr<LifetimeBoundAttr>())
- PVD->addAttr(LifetimeBoundAttr::CreateImplicit(AC, PVD->getLocation()));
+ PVD->addAttr(
+ LifetimeBoundAttr::CreateImplicit(AST, PVD->getLocation()));
}
}
};
diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
index 248179e8ba7b6..592215bf94d4a 100644
--- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -Wexperimental-lifetime-safety-suggestions -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -fexperimental-lifetime-safety-inference -Wexperimental-lifetime-safety-suggestions -verify %s
struct MyObj {
int id;
@@ -117,14 +117,14 @@ View return_view_callee(View a) { // expected-warning {{param should be mark
} // incorrect_order_inference_view
namespace incorrect_order_inference_object {
-View return_object_callee(View a);
+MyObj* return_object_callee(MyObj* a);
// FIXME: No lifetime annotation suggestion warning when functions are not present in the callee-before-caller pattern
-View return_object_caller(View a) {
+MyObj* return_object_caller(MyObj* a) {
return return_object_callee(a);
}
-View return_object_callee(View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+MyObj* return_object_callee(MyObj* a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
return a; // expected-note {{param returned here}}
}
} // incorrect_order_inference_object
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp
index 8cd1bd8bcc54c..b993d4df7b235 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -Wexperimental-lifetime-safety -Wno-dangling -Wno-experimental-lifetime-safety-suggestions -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -fexperimental-lifetime-safety-inference -Wexperimental-lifetime-safety -Wno-dangling -Wno-experimental-lifetime-safety-suggestions -verify %s
struct MyObj {
int id;
>From 75d71d7275d7a86280a978dff55f1f7b974eb3b4 Mon Sep 17 00:00:00 2001
From: Kashika Akhouri <akhourik at google.com>
Date: Tue, 9 Dec 2025 12:20:42 +0000
Subject: [PATCH 4/4] Move inference tests with suggestions
---
.../Sema/warn-lifetime-safety-suggestions.cpp | 64 +++++++++++++++++--
clang/test/Sema/warn-lifetime-safety.cpp | 54 +---------------
2 files changed, 59 insertions(+), 59 deletions(-)
diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
index 592215bf94d4a..9f3ccb7fca770 100644
--- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
+++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -fexperimental-lifetime-safety-inference -Wexperimental-lifetime-safety-suggestions -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -fexperimental-lifetime-safety-inference -Wexperimental-lifetime-safety-suggestions -Wexperimental-lifetime-safety -verify %s
struct MyObj {
int id;
@@ -101,7 +101,7 @@ View return_view_by_func (View a) { // expected-warning {{param should be mar
MyObj* return_pointer_by_func (MyObj* a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
return return_pointer_object(a); // expected-note {{param returned here}}
}
-} // correct_order_inference
+} // namespace correct_order_inference
namespace incorrect_order_inference_view {
View return_view_callee(View a);
@@ -114,7 +114,7 @@ View return_view_caller(View a) {
View return_view_callee(View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
return a; // expected-note {{param returned here}}
}
-} // incorrect_order_inference_view
+} // namespace incorrect_order_inference_view
namespace incorrect_order_inference_object {
MyObj* return_object_callee(MyObj* a);
@@ -124,10 +124,62 @@ MyObj* return_object_caller(MyObj* a) {
return return_object_callee(a);
}
-MyObj* return_object_callee(MyObj* a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
- return a; // expected-note {{param returned here}}
+MyObj* return_object_callee(MyObj* a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return a; // expected-note {{param returned here}}
}
-} // incorrect_order_inference_object
+} // namespace incorrect_order_inference_object
+
+namespace simple_annotation_inference {
+View inference_callee_return_identity(View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return a; // expected-note {{param returned here}}
+}
+
+View inference_caller_forwards_callee(View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return inference_callee_return_identity(a); // expected-note {{param returned here}}
+}
+
+View inference_top_level_return_stack_view() {
+ MyObj local_stack;
+ return inference_caller_forwards_callee(local_stack); // expected-warning {{address of stack memory is returned later}}
+ // expected-note at -1 {{returned here}}
+}
+} // namespace simple_annotation_inference
+
+namespace inference_in_order_with_redecls {
+View inference_callee_return_identity(View a);
+View inference_callee_return_identity(View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return a; // expected-note {{param returned here}}
+}
+
+View inference_caller_forwards_callee(View a);
+View inference_caller_forwards_callee(View a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return inference_callee_return_identity(a); // expected-note {{param returned here}}
+}
+
+View inference_top_level_return_stack_view() {
+ MyObj local_stack;
+ return inference_caller_forwards_callee(local_stack); // expected-warning {{address of stack memory is returned later}}
+ // expected-note at -1 {{returned here}}
+}
+} // namespace inference_in_order_with_redecls
+
+namespace inference_with_templates {
+template<typename T>
+T* template_identity(T* a) { // expected-warning {{param should be marked [[clang::lifetimebound]]}}.
+ return a; // expected-note {{param returned here}}
+}
+
+template<typename T>
+T* template_caller(T* a) {
+ return template_identity(a); // expected-note {{in instantiation of function template specialization 'inference_with_templates::template_identity<MyObj>' requested here}}
+}
+
+// FIXME: Fails to detect UAR as template instantiations are deferred to the end of the Translation Unit.
+MyObj* test_template_inference_with_stack() {
+ MyObj local_stack;
+ return template_caller(&local_stack); // expected-note {{in instantiation of function template specialization 'inference_with_templates::template_caller<MyObj>' requested here}}
+}
+} // namespace inference_with_templates
//===----------------------------------------------------------------------===//
// Negative Test Cases
diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp
index b993d4df7b235..ee68b60ec567e 100644
--- a/clang/test/Sema/warn-lifetime-safety.cpp
+++ b/clang/test/Sema/warn-lifetime-safety.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -fexperimental-lifetime-safety-inference -Wexperimental-lifetime-safety -Wno-dangling -Wno-experimental-lifetime-safety-suggestions -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fexperimental-lifetime-safety -Wexperimental-lifetime-safety -Wno-dangling -Wno-experimental-lifetime-safety-suggestions -verify %s
struct MyObj {
int id;
@@ -552,58 +552,6 @@ const int& get_ref_to_local() {
// expected-note at -1 {{returned here}}
}
-namespace simple_annotation_inference {
-View inference_callee_return_identity(View a) {
- return a;
-}
-
-View inference_caller_forwards_callee(View a) {
- return inference_callee_return_identity(a);
-}
-
-View inference_top_level_return_stack_view() {
- MyObj local_stack;
- return inference_caller_forwards_callee(local_stack); // expected-warning {{address of stack memory is returned later}}
- // expected-note at -1 {{returned here}}
-}
-} // simple_annotation_inference
-
-namespace inference_in_order_with_redecls {
-View inference_callee_return_identity(View a);
-View inference_callee_return_identity(View a) {
- return a;
-}
-
-View inference_caller_forwards_callee(View a);
-View inference_caller_forwards_callee(View a) {
- return inference_callee_return_identity(a);
-}
-
-View inference_top_level_return_stack_view() {
- MyObj local_stack;
- return inference_caller_forwards_callee(local_stack); // expected-warning {{address of stack memory is returned later}}
- // expected-note at -1 {{returned here}}
-}
-} // namespace inference_in_order_with_redecls
-
-namespace inference_with_templates {
-template<typename T>
-T* template_identity(T* a) {
- return a;
-}
-
-template<typename T>
-T* template_caller(T* a) {
- return template_identity(a);
-}
-
-// FIXME: Fails to detect UAR as template instantiations are deferred to the end of the Translation Unit.
-MyObj* test_template_inference_with_stack() {
- MyObj local_stack;
- return template_caller(&local_stack);
-}
-} // inference_with_templates
-
//===----------------------------------------------------------------------===//
// Use-After-Scope & Use-After-Return (Return-Stack-Address) Combined
// These are cases where the diagnostic kind is determined by location
More information about the cfe-commits
mailing list