[clang] [experimental] Detect return-stack-addr using CFG (PR #124133)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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