[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-08 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 6600371b2948e9c0227a1ef0072a8cdf5c983005 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 7 Feb 2025 17:08:56 +
Subject: [PATCH] CFG-based lifetime analysis using existing annotations

---
 .../Analysis/Analyses/DanglingReference.h |  27 +
 clang/include/clang/Basic/DiagnosticGroups.td |   7 +
 .../clang/Basic/DiagnosticSemaKinds.td|  19 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 876 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |  49 +
 clang/test/Sema/Inputs/lifetime-analysis.h|   2 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 609 
 .../Sema/warn-lifetime-analysis-nocfg.cpp | 104 ++-
 9 files changed, 1662 insertions(+), 32 deletions(-)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 000..2a6f5c88ed7341f
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,27 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+namespace clang {
+class DanglingReferenceReporter {
+public:
+  DanglingReferenceReporter() = default;
+  virtual ~DanglingReferenceReporter() = default;
+
+  virtual void ReportReturnLocalVar(const Expr *RetExpr,
+const Decl *LocalDecl) {}
+  virtual void ReportReturnTemporaryExpr(const Expr *TemporaryExpr) {}
+  virtual void ReportDanglingReference(const VarDecl *VD) {}
+  virtual void SuggestLifetimebound(const ParmVarDecl *PVD,
+const Expr *RetExpr) {}
+};
+
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac,
+  DanglingReferenceReporter *reporter);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d61..600dca0e4a96441 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,13 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def SuggestLifetimeboundCFG : DiagGroup<"suggest-lifetimebound-cfg">;
+def DanglingReferenceCFG : DiagGroup<"dangling-reference-cfg">;
+def DanglingCFG
+: DiagGroup<"dangling-cfg", [ReturnStackAddressCFG, DanglingReferenceCFG,
+ SuggestLifetimeboundCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1ccb..62da2db4a1c66eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,25 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg
+: Warning<"returning reference to a stack variable">,
+  InGroup,
+  DefaultIgnore;
+def note_local_variable_declared_here
+: Note<"reference to this stack variable is returned">;
+def warn_ret_stack_temporary_ref_cfg
+: Warning<"returning reference to a temporary object">,
+  InGroup,
+  DefaultIgnore;
+def warn_dangling_reference_cfg : Warning<"reference to local object dangles">,
+  InGroup,
+  DefaultIgnore; // TODO: add note on loc of
+def warn_suggest_lifetimebound_cfg
+: Warning<"param should be marked lifetimebound">,
+  InGroup,
+  DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/li

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-08 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 5f9375e0a9f491952fed8edf1d383e3f6feccdc6 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 7 Feb 2025 17:08:56 +
Subject: [PATCH] CFG-based lifetime analysis using existing annotations

---
 .../Analysis/Analyses/DanglingReference.h |  27 +
 clang/include/clang/Basic/DiagnosticGroups.td |   7 +
 .../clang/Basic/DiagnosticSemaKinds.td|  19 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 876 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |  49 +
 clang/test/Sema/Inputs/lifetime-analysis.h|   2 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 609 
 .../Sema/warn-lifetime-analysis-nocfg.cpp | 104 ++-
 9 files changed, 1662 insertions(+), 32 deletions(-)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 000..2a6f5c88ed7341f
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,27 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+namespace clang {
+class DanglingReferenceReporter {
+public:
+  DanglingReferenceReporter() = default;
+  virtual ~DanglingReferenceReporter() = default;
+
+  virtual void ReportReturnLocalVar(const Expr *RetExpr,
+const Decl *LocalDecl) {}
+  virtual void ReportReturnTemporaryExpr(const Expr *TemporaryExpr) {}
+  virtual void ReportDanglingReference(const VarDecl *VD) {}
+  virtual void SuggestLifetimebound(const ParmVarDecl *PVD,
+const Expr *RetExpr) {}
+};
+
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac,
+  DanglingReferenceReporter *reporter);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d61..600dca0e4a96441 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,13 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def SuggestLifetimeboundCFG : DiagGroup<"suggest-lifetimebound-cfg">;
+def DanglingReferenceCFG : DiagGroup<"dangling-reference-cfg">;
+def DanglingCFG
+: DiagGroup<"dangling-cfg", [ReturnStackAddressCFG, DanglingReferenceCFG,
+ SuggestLifetimeboundCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1ccb..62da2db4a1c66eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,25 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg
+: Warning<"returning reference to a stack variable">,
+  InGroup,
+  DefaultIgnore;
+def note_local_variable_declared_here
+: Note<"reference to this stack variable is returned">;
+def warn_ret_stack_temporary_ref_cfg
+: Warning<"returning reference to a temporary object">,
+  InGroup,
+  DefaultIgnore;
+def warn_dangling_reference_cfg : Warning<"reference to local object dangles">,
+  InGroup,
+  DefaultIgnore; // TODO: add note on loc of
+def warn_suggest_lifetimebound_cfg
+: Warning<"param should be marked lifetimebound">,
+  InGroup,
+  DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/li

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-08 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 52028aeb5acc9a23c21c96d1fe9729031f61a7bc Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 7 Feb 2025 17:08:56 +
Subject: [PATCH] CFG-based lifetime analysis using existing annotations

---
 .../Analysis/Analyses/DanglingReference.h |  27 +
 clang/include/clang/Basic/DiagnosticGroups.td |   7 +
 .../clang/Basic/DiagnosticSemaKinds.td|  19 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 876 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |  49 +
 clang/test/Sema/Inputs/lifetime-analysis.h|   2 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 596 
 .../Sema/warn-lifetime-analysis-nocfg.cpp | 104 ++-
 9 files changed, 1649 insertions(+), 32 deletions(-)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 000..2a6f5c88ed7341f
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,27 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+namespace clang {
+class DanglingReferenceReporter {
+public:
+  DanglingReferenceReporter() = default;
+  virtual ~DanglingReferenceReporter() = default;
+
+  virtual void ReportReturnLocalVar(const Expr *RetExpr,
+const Decl *LocalDecl) {}
+  virtual void ReportReturnTemporaryExpr(const Expr *TemporaryExpr) {}
+  virtual void ReportDanglingReference(const VarDecl *VD) {}
+  virtual void SuggestLifetimebound(const ParmVarDecl *PVD,
+const Expr *RetExpr) {}
+};
+
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac,
+  DanglingReferenceReporter *reporter);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d61..600dca0e4a96441 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,13 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def SuggestLifetimeboundCFG : DiagGroup<"suggest-lifetimebound-cfg">;
+def DanglingReferenceCFG : DiagGroup<"dangling-reference-cfg">;
+def DanglingCFG
+: DiagGroup<"dangling-cfg", [ReturnStackAddressCFG, DanglingReferenceCFG,
+ SuggestLifetimeboundCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1ccb..62da2db4a1c66eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,25 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg
+: Warning<"returning reference to a stack variable">,
+  InGroup,
+  DefaultIgnore;
+def note_local_variable_declared_here
+: Note<"reference to this stack variable is returned">;
+def warn_ret_stack_temporary_ref_cfg
+: Warning<"returning reference to a temporary object">,
+  InGroup,
+  DefaultIgnore;
+def warn_dangling_reference_cfg : Warning<"reference to local object dangles">,
+  InGroup,
+  DefaultIgnore; // TODO: add note on loc of
+def warn_suggest_lifetimebound_cfg
+: Warning<"param should be marked lifetimebound">,
+  InGroup,
+  DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/li

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-08 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From c69aef83bfbb219ba07b578d78919a522569a59a Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 7 Feb 2025 17:08:56 +
Subject: [PATCH] CFG-based lifetime analysis using existing annotations

---
 .../Analysis/Analyses/DanglingReference.h |  27 +
 clang/include/clang/Basic/DiagnosticGroups.td |   7 +
 .../clang/Basic/DiagnosticSemaKinds.td|  19 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 878 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |  49 +
 clang/test/Sema/Inputs/lifetime-analysis.h|   2 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 548 +++
 .../Sema/warn-lifetime-analysis-nocfg.cpp | 104 ++-
 9 files changed, 1603 insertions(+), 32 deletions(-)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 000..2a6f5c88ed7341f
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,27 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+namespace clang {
+class DanglingReferenceReporter {
+public:
+  DanglingReferenceReporter() = default;
+  virtual ~DanglingReferenceReporter() = default;
+
+  virtual void ReportReturnLocalVar(const Expr *RetExpr,
+const Decl *LocalDecl) {}
+  virtual void ReportReturnTemporaryExpr(const Expr *TemporaryExpr) {}
+  virtual void ReportDanglingReference(const VarDecl *VD) {}
+  virtual void SuggestLifetimebound(const ParmVarDecl *PVD,
+const Expr *RetExpr) {}
+};
+
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac,
+  DanglingReferenceReporter *reporter);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d61..600dca0e4a96441 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,13 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def SuggestLifetimeboundCFG : DiagGroup<"suggest-lifetimebound-cfg">;
+def DanglingReferenceCFG : DiagGroup<"dangling-reference-cfg">;
+def DanglingCFG
+: DiagGroup<"dangling-cfg", [ReturnStackAddressCFG, DanglingReferenceCFG,
+ SuggestLifetimeboundCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1ccb..62da2db4a1c66eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,25 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg
+: Warning<"returning reference to a stack variable">,
+  InGroup,
+  DefaultIgnore;
+def note_local_variable_declared_here
+: Note<"reference to this stack variable is returned">;
+def warn_ret_stack_temporary_ref_cfg
+: Warning<"returning reference to a temporary object">,
+  InGroup,
+  DefaultIgnore;
+def warn_dangling_reference_cfg : Warning<"reference to local object dangles">,
+  InGroup,
+  DefaultIgnore; // TODO: add note on loc of
+def warn_suggest_lifetimebound_cfg
+: Warning<"param should be marked lifetimebound">,
+  InGroup,
+  DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-08 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From cec28dbf72a389b80bead9e1184d2bc8b1c1e894 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 7 Feb 2025 17:08:56 +
Subject: [PATCH] CFG-based lifetime analysis using existing annotations

---
 .../Analysis/Analyses/DanglingReference.h |  27 +
 clang/include/clang/Basic/DiagnosticGroups.td |   7 +
 .../clang/Basic/DiagnosticSemaKinds.td|  19 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 878 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |  49 +
 clang/test/Sema/Inputs/lifetime-analysis.h|   1 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 480 ++
 .../Sema/warn-lifetime-analysis-nocfg.cpp | 104 ++-
 9 files changed, 1534 insertions(+), 32 deletions(-)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 000..2a6f5c88ed7341f
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,27 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+namespace clang {
+class DanglingReferenceReporter {
+public:
+  DanglingReferenceReporter() = default;
+  virtual ~DanglingReferenceReporter() = default;
+
+  virtual void ReportReturnLocalVar(const Expr *RetExpr,
+const Decl *LocalDecl) {}
+  virtual void ReportReturnTemporaryExpr(const Expr *TemporaryExpr) {}
+  virtual void ReportDanglingReference(const VarDecl *VD) {}
+  virtual void SuggestLifetimebound(const ParmVarDecl *PVD,
+const Expr *RetExpr) {}
+};
+
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac,
+  DanglingReferenceReporter *reporter);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d61..600dca0e4a96441 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,13 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def SuggestLifetimeboundCFG : DiagGroup<"suggest-lifetimebound-cfg">;
+def DanglingReferenceCFG : DiagGroup<"dangling-reference-cfg">;
+def DanglingCFG
+: DiagGroup<"dangling-cfg", [ReturnStackAddressCFG, DanglingReferenceCFG,
+ SuggestLifetimeboundCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1ccb..62da2db4a1c66eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,25 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg
+: Warning<"returning reference to a stack variable">,
+  InGroup,
+  DefaultIgnore;
+def note_local_variable_declared_here
+: Note<"reference to this stack variable is returned">;
+def warn_ret_stack_temporary_ref_cfg
+: Warning<"returning reference to a temporary object">,
+  InGroup,
+  DefaultIgnore;
+def warn_dangling_reference_cfg : Warning<"reference to local object dangles">,
+  InGroup,
+  DefaultIgnore; // TODO: add note on loc of
+def warn_suggest_lifetimebound_cfg
+: Warning<"param should be marked lifetimebound">,
+  InGroup,
+  DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-08 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 9076d28fbf8d7ee7042b9301b8b6fc7dc80c0a7b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 7 Feb 2025 17:08:56 +
Subject: [PATCH] CFG-based lifetime analysis using existing annotations

---
 .../Analysis/Analyses/DanglingReference.h |  27 +
 clang/include/clang/Basic/DiagnosticGroups.td |   7 +
 .../clang/Basic/DiagnosticSemaKinds.td|  20 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 878 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |  49 +
 clang/test/Sema/Inputs/lifetime-analysis.h|   1 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  |  17 +
 .../Sema/warn-lifetime-analysis-nocfg.cpp | 104 ++-
 9 files changed, 1072 insertions(+), 32 deletions(-)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 000..2a6f5c88ed7341f
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,27 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+namespace clang {
+class DanglingReferenceReporter {
+public:
+  DanglingReferenceReporter() = default;
+  virtual ~DanglingReferenceReporter() = default;
+
+  virtual void ReportReturnLocalVar(const Expr *RetExpr,
+const Decl *LocalDecl) {}
+  virtual void ReportReturnTemporaryExpr(const Expr *TemporaryExpr) {}
+  virtual void ReportDanglingReference(const VarDecl *VD) {}
+  virtual void SuggestLifetimebound(const ParmVarDecl *PVD,
+const Expr *RetExpr) {}
+};
+
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac,
+  DanglingReferenceReporter *reporter);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d61..a097167486ac5f5 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,13 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def SuggestLifetimeboundCFG : DiagGroup<"suggest-lifetimebound-cfg">;
+def DanglingReferenceCFG : DiagGroup<"dangling-reference-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG,
+ DanglingReferenceCFG,
+ SuggestLifetimeboundCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1ccb..5ea6a69f9507599 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,26 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg
+: Warning<"returning reference to a stack variable">,
+  InGroup,
+  DefaultIgnore;
+def note_local_variable_declared_here
+: Note<"reference to this stack variable is returned">;
+def warn_ret_stack_temporary_ref_cfg
+: Warning<"returning reference to a temporary object">,
+  InGroup,
+  DefaultIgnore;
+def warn_dangling_reference_cfg
+: Warning<"reference to local object dangles">,
+  InGroup,
+  DefaultIgnore; // TODO: add note on loc of 
+def warn_suggest_lifetimebound_cfg
+: Warning<"param should be marked lifetimebound">,
+  InGroup,
+  DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analys

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-07 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From d4ccc6ce7e2b7af1eeb5164f6a1e47f57fe93cd8 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Fri, 7 Feb 2025 17:08:56 +
Subject: [PATCH] CFG-based lifetime analysis using existing annotations

---
 .../Analysis/Analyses/DanglingReference.h |  26 +
 clang/include/clang/Basic/DiagnosticGroups.td |   5 +
 .../clang/Basic/DiagnosticSemaKinds.td|  16 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 866 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |  42 +
 clang/test/Sema/Inputs/lifetime-analysis.h|   1 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 450 +
 .../Sema/warn-lifetime-analysis-nocfg.cpp | 104 ++-
 9 files changed, 1479 insertions(+), 32 deletions(-)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 000..ce87137619a9604
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,26 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+namespace clang {
+class DanglingReferenceReporter {
+public:
+  DanglingReferenceReporter() = default;
+  virtual ~DanglingReferenceReporter() = default;
+
+  virtual void ReportReturnLocalVar(const Expr *RetExpr,
+const Decl *LocalDecl) {}
+  virtual void ReportReturnTemporaryExpr(const Expr *TemporaryExpr) {}
+  virtual void SuggestLifetimebound(const ParmVarDecl *PVD,
+const Expr *RetExpr) {}
+};
+
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac,
+  DanglingReferenceReporter *reporter);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d61..70ae031b159fedd 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,11 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def SuggestLifetimeboundCFG : DiagGroup<"suggest-lifetimebound-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG,
+ SuggestLifetimeboundCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1ccb..2c5fcc03abec5a0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,22 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg
+: Warning<"returning reference to a stack variable">,
+  InGroup,
+  DefaultIgnore;
+def note_local_variable_declared_here
+: Note<"reference to this stack variable is returned">;
+def warn_ret_stack_temporary_ref_cfg
+: Warning<"returning reference to a temporary object">,
+  InGroup,
+  DefaultIgnore;
+def warn_suggest_lifetimebound_cfg
+: Warning<"param should be marked lifetimebound">,
+  InGroup,
+  DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef95..d6ea1e907e7f09b 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalP

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-07 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/3] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 000..c9f5753eed070e6
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d61..eeddd6eb82a3019 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1ccb..846cf6b3d45f8a8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef95..d6ea1e907e7f09b 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 000..2602cc597a36b86
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (au

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-04 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/3] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-02 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/3] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 000..c9f5753eed070e6
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d61..eeddd6eb82a3019 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1ccb..846cf6b3d45f8a8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef95..d6ea1e907e7f09b 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 000..2602cc597a36b86
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (au

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-01 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 edited https://github.com/llvm/llvm-project/pull/124133
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-02-01 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/3] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-01-26 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/3] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-01-26 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/3] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-01-26 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/3] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-01-26 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/3] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-01-24 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/3] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-01-23 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/2] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-01-23 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/2] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-01-23 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/124133

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH 1/2] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD =

[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)

2025-01-23 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 created 
https://github.com/llvm/llvm-project/pull/124133

None

>From 22990789b61e9f9d22e88a6b008eb3166fd1cb56 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Thu, 23 Jan 2025 15:47:39 +
Subject: [PATCH] [experimental] Detect return-stack-addr using CFG

---
 .../Analysis/Analyses/DanglingReference.h |  14 +
 clang/include/clang/Basic/DiagnosticGroups.td |   3 +
 .../clang/Basic/DiagnosticSemaKinds.td|   8 +
 clang/lib/Analysis/CMakeLists.txt |   1 +
 clang/lib/Analysis/DanglingReference.cpp  | 351 ++
 clang/lib/Sema/AnalysisBasedWarnings.cpp  |   8 +
 .../test/Sema/warn-lifetime-analysis-cfg.cpp  | 136 +++
 7 files changed, 521 insertions(+)
 create mode 100644 clang/include/clang/Analysis/Analyses/DanglingReference.h
 create mode 100644 clang/lib/Analysis/DanglingReference.cpp
 create mode 100644 clang/test/Sema/warn-lifetime-analysis-cfg.cpp

diff --git a/clang/include/clang/Analysis/Analyses/DanglingReference.h 
b/clang/include/clang/Analysis/Analyses/DanglingReference.h
new file mode 100644
index 00..c9f5753eed070e
--- /dev/null
+++ b/clang/include/clang/Analysis/Analyses/DanglingReference.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
+#include "clang/AST/DeclBase.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+void runDanglingReferenceAnalysis(const DeclContext &dc, const CFG &cfg,
+  AnalysisDeclContext &ac, Sema &S);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_DANGLING_REFERENCE_H
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 594e99a19b64d6..eeddd6eb82a301 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -472,6 +472,9 @@ def Dangling : DiagGroup<"dangling", [DanglingAssignment,
   DanglingInitializerList,
   DanglingGsl,
   ReturnStackAddress]>;
+def ReturnStackAddressCFG : DiagGroup<"return-stack-address-cfg">;
+def DanglingCFG : DiagGroup<"dangling-cfg", [ReturnStackAddressCFG]>;
+
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
 def DllexportExplicitInstantiationDecl : 
DiagGroup<"dllexport-explicit-instantiation-decl">;
 def ExcessInitializers : DiagGroup<"excess-initializers">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8be4f946dce1cc..846cf6b3d45f8a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10169,6 +10169,14 @@ def 
err_lifetimebound_implicit_object_parameter_void_return_type : Error<
   "parameter of a function that returns void; "
   "did you mean 'lifetime_capture_by(X)'">;
 
+// CFG based lifetime analysis.
+def warn_ret_stack_variable_ref_cfg : Warning<
+  "returning reference to a stack variable">, InGroup, 
DefaultIgnore;
+def note_local_variable_declared_here : Note<"reference to this stack variable 
is returned">;
+
+def warn_ret_stack_temporary_ref_cfg : Warning<
+  "returning reference to a temporary object">, 
InGroup, DefaultIgnore;
+
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr_ref : Warning<
   "%select{address of|reference to}0 stack memory associated with "
diff --git a/clang/lib/Analysis/CMakeLists.txt 
b/clang/lib/Analysis/CMakeLists.txt
index 7914c12d429ef9..d6ea1e907e7f09 100644
--- a/clang/lib/Analysis/CMakeLists.txt
+++ b/clang/lib/Analysis/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangAnalysis
   ConstructionContext.cpp
   Consumed.cpp
   CodeInjector.cpp
+  DanglingReference.cpp
   Dominators.cpp
   ExprMutationAnalyzer.cpp
   IntervalPartition.cpp
diff --git a/clang/lib/Analysis/DanglingReference.cpp 
b/clang/lib/Analysis/DanglingReference.cpp
new file mode 100644
index 00..2602cc597a36b8
--- /dev/null
+++ b/clang/lib/Analysis/DanglingReference.cpp
@@ -0,0 +1,351 @@
+#include "clang/Analysis/Analyses/DanglingReference.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/DiagnosticSema.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+namespace {
+
+template  static bool isRecordWithAttr(QualType Type) {
+  auto *RD = Type->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  bool Result = RD->hasAttr();
+
+  if (auto *CTSD