[llvm-branch-commits] [clang] [analyzer] Correctly highlight the variables' range in UseAfterLifetimeEnd reports (PR #215905)

Benedek Kaibas via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Aug 13 06:58:06 PDT 2026


https://github.com/benedekaibas updated https://github.com/llvm/llvm-project/pull/215905

>From 9bbf16ef73266a9f1e86e13ecfbb3f7b6e22dffb Mon Sep 17 00:00:00 2001
From: benedekaibas <kaibas01 at allegheny.edu>
Date: Wed, 12 Aug 2026 22:31:23 +0200
Subject: [PATCH 1/3] [analyzer] Highilght variables range in emitted reports
 from UseAfterLifetimeEnd

---
 .../Checkers/UseAfterLifetimeEnd.cpp          |  6 ++--
 clang/test/Analysis/lifetime-bound.cpp        | 28 +++++++++++++++++++
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/UseAfterLifetimeEnd.cpp b/clang/lib/StaticAnalyzer/Checkers/UseAfterLifetimeEnd.cpp
index de89836ee5dc2..f10da977172c0 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UseAfterLifetimeEnd.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UseAfterLifetimeEnd.cpp
@@ -98,8 +98,10 @@ void UseAfterLifetimeEnd::checkEndFunction(const ReturnStmt *RS,
 }
 
 static SourceRange getRegionDeclRange(const MemRegion *Source) {
-  if (const auto *VR = dyn_cast_or_null<VarRegion>(Source))
-    return VR->getDecl()->getSourceRange();
+  if (const auto *VR = dyn_cast_or_null<VarRegion>(Source)) {
+    const VarDecl *VD = VR->getDecl();
+    return SourceRange(VD->getLocation());
+  }
   return SourceRange();
 }
 
diff --git a/clang/test/Analysis/lifetime-bound.cpp b/clang/test/Analysis/lifetime-bound.cpp
index d54116bc65314..47c83ef9a5383 100644
--- a/clang/test/Analysis/lifetime-bound.cpp
+++ b/clang/test/Analysis/lifetime-bound.cpp
@@ -435,3 +435,31 @@ int test_multi_param_highlight() {
   // CHECK: return multi_params_annotated(&local_one, &local_two);
   // CHECK-NEXT:                                      ^~~~~~~~~~
 }
+
+int test_multi_local_bound_to_param_highlight() {
+  int j = 4, k = 5;
+  // expected-note at -1 {{'j' initialized here}}
+  // expected-note at -2 {{'k' initialized here}}
+  return multi_params_annotated(&j, &k);
+  // expected-warning at -1 {{address of stack memory associated with local variable 'j' returned}}
+  // expected-warning at -2 {{address of stack memory associated with local variable 'k' returned}}
+  // expected-warning at -3 {{Returning value bound to 'j' that will go out of scope}}
+  // expected-note at -4    {{Value's lifetime bound to the lifetime of 'j' here}}
+  // expected-note at -5    {{Lifetime of 'j' ended here}}
+  // expected-warning at -6 {{Returning value bound to 'k' that will go out of scope}}
+  // expected-note at -7    {{Value's lifetime bound to the lifetime of 'k' here}}
+  // expected-note at -8    {{Lifetime of 'k' ended here}}
+  
+  // CHECK: note: Value's lifetime bound to the lifetime of 'j' here
+  // CHECK-NEXT: int j = 4, k = 5;
+  // CHECK-NEXT:     ~
+  // CHECK: note: Lifetime of 'j' ended here
+  // CHECK-NEXT: int j = 4, k = 5;
+  // CHECK-NEXT:     ~
+  // CHECK: note: Value's lifetime bound to the lifetime of 'k' here
+  // CHECK-NEXT: int j = 4, k = 5;
+  // CHECK-NEXT:            ~
+  // CHECK: note: Lifetime of 'k' ended here
+  // CHECK-NEXT: int j = 4, k = 5;
+  // CHECK-NEXT:            ~
+}

>From 40660e25ed980beaded53f99b654b50d7d212bec Mon Sep 17 00:00:00 2001
From: benedekaibas <kaibas01 at allegheny.edu>
Date: Thu, 13 Aug 2026 10:32:01 +0200
Subject: [PATCH 2/3] Remove strict whitespace indentations.

---
 clang/test/Analysis/lifetime-bound.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/test/Analysis/lifetime-bound.cpp b/clang/test/Analysis/lifetime-bound.cpp
index 47c83ef9a5383..a8ebe28b327ea 100644
--- a/clang/test/Analysis/lifetime-bound.cpp
+++ b/clang/test/Analysis/lifetime-bound.cpp
@@ -430,10 +430,10 @@ int test_multi_param_highlight() {
 
   // CHECK: note: Value's lifetime bound to the lifetime of 'local_one' here
   // CHECK: return multi_params_annotated(&local_one, &local_two);
-  // CHECK-NEXT:                          ^~~~~~~~~~
+  // CHECK-NEXT: ^~~~~~~~~~
   // CHECK: note: Value's lifetime bound to the lifetime of 'local_two' here
   // CHECK: return multi_params_annotated(&local_one, &local_two);
-  // CHECK-NEXT:                                      ^~~~~~~~~~
+  // CHECK-NEXT: ^~~~~~~~~~
 }
 
 int test_multi_local_bound_to_param_highlight() {
@@ -452,14 +452,14 @@ int test_multi_local_bound_to_param_highlight() {
   
   // CHECK: note: Value's lifetime bound to the lifetime of 'j' here
   // CHECK-NEXT: int j = 4, k = 5;
-  // CHECK-NEXT:     ~
+  // CHECK-NEXT: ~
   // CHECK: note: Lifetime of 'j' ended here
   // CHECK-NEXT: int j = 4, k = 5;
-  // CHECK-NEXT:     ~
+  // CHECK-NEXT: ~
   // CHECK: note: Value's lifetime bound to the lifetime of 'k' here
   // CHECK-NEXT: int j = 4, k = 5;
-  // CHECK-NEXT:            ~
+  // CHECK-NEXT: ~
   // CHECK: note: Lifetime of 'k' ended here
   // CHECK-NEXT: int j = 4, k = 5;
-  // CHECK-NEXT:            ~
+  // CHECK-NEXT: ~
 }

>From 99586f75316d2c41aaa5a535f151b711a8b513ae Mon Sep 17 00:00:00 2001
From: benedekaibas <kaibas01 at allegheny.edu>
Date: Thu, 13 Aug 2026 15:56:57 +0200
Subject: [PATCH 3/3] Strict whitespace matching applied.

---
 clang/test/Analysis/lifetime-bound.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/clang/test/Analysis/lifetime-bound.cpp b/clang/test/Analysis/lifetime-bound.cpp
index a8ebe28b327ea..7d77da614d646 100644
--- a/clang/test/Analysis/lifetime-bound.cpp
+++ b/clang/test/Analysis/lifetime-bound.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UseAfterLifetimeEnd,debug.DebugLifetimeModeling \
 // RUN:   -analyzer-config cfg-lifetime=true -analyzer-output=text -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UseAfterLifetimeEnd,debug.DebugLifetimeModeling \
-// RUN:   -analyzer-output=text %s 2>&1 | FileCheck %s
+// RUN:   -analyzer-output=text %s 2>&1 | FileCheck --strict-whitespace %s
 struct A {};
 
 struct Pair {
@@ -430,10 +430,10 @@ int test_multi_param_highlight() {
 
   // CHECK: note: Value's lifetime bound to the lifetime of 'local_one' here
   // CHECK: return multi_params_annotated(&local_one, &local_two);
-  // CHECK-NEXT: ^~~~~~~~~~
+  // CHECK-NEXT:{{\|                                 \^~~~~~~~~~$}}
   // CHECK: note: Value's lifetime bound to the lifetime of 'local_two' here
   // CHECK: return multi_params_annotated(&local_one, &local_two);
-  // CHECK-NEXT: ^~~~~~~~~~
+  // CHECK-NEXT:{{\|                                             \^~~~~~~~~~$}}
 }
 
 int test_multi_local_bound_to_param_highlight() {
@@ -449,17 +449,17 @@ int test_multi_local_bound_to_param_highlight() {
   // expected-warning at -6 {{Returning value bound to 'k' that will go out of scope}}
   // expected-note at -7    {{Value's lifetime bound to the lifetime of 'k' here}}
   // expected-note at -8    {{Lifetime of 'k' ended here}}
-  
+
   // CHECK: note: Value's lifetime bound to the lifetime of 'j' here
   // CHECK-NEXT: int j = 4, k = 5;
-  // CHECK-NEXT: ~
+  // CHECK-NEXT:{{\|       ~$}}
   // CHECK: note: Lifetime of 'j' ended here
   // CHECK-NEXT: int j = 4, k = 5;
-  // CHECK-NEXT: ~
+  // CHECK-NEXT:{{\|       ~$}}
   // CHECK: note: Value's lifetime bound to the lifetime of 'k' here
   // CHECK-NEXT: int j = 4, k = 5;
-  // CHECK-NEXT: ~
+  // CHECK-NEXT:{{\|              ~$}}
   // CHECK: note: Lifetime of 'k' ended here
   // CHECK-NEXT: int j = 4, k = 5;
-  // CHECK-NEXT: ~
+  // CHECK-NEXT:{{\|              ~$}}
 }



More information about the llvm-branch-commits mailing list