[clang] be0b114 - [analyzer][StackAddrEscapeChecker] Fix assert failure for alloca regions (#109655)

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 23 07:47:39 PDT 2024


Author: Arseniy Zaostrovnykh
Date: 2024-09-23T16:47:35+02:00
New Revision: be0b1142df7733633354ef1f73d0379bcd2ccb54

URL: https://github.com/llvm/llvm-project/commit/be0b1142df7733633354ef1f73d0379bcd2ccb54
DIFF: https://github.com/llvm/llvm-project/commit/be0b1142df7733633354ef1f73d0379bcd2ccb54.diff

LOG: [analyzer][StackAddrEscapeChecker] Fix assert failure for alloca regions (#109655)

Fixes #107852

Make it explicit that the checker skips `alloca` regions to avoid the
risk of producing false positives for code with advanced memory
management.
StackAddrEscapeChecker already used this strategy when it comes to
malloc'ed regions, so this change relaxes the assertion and explicitly
silents the issues related to memory regions generated with `alloca`.

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
    clang/test/Analysis/stack-addr-ps.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index d8c52941b19366..a76639bb86b208 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -337,6 +337,10 @@ static std::optional<std::string> printReferrer(const MemRegion *Referrer) {
       // warn_bind_ref_member_to_parameter or
       // warn_init_ptr_member_to_parameter_addr
       return std::nullopt;
+    } else if (isa<AllocaRegion>(Referrer)) {
+      // Skip alloca() regions, they indicate advanced memory management
+      // and higher likelihood of CSA false positives.
+      return std::nullopt;
     } else {
       assert(false && "Unexpected referrer region type.");
       return std::nullopt;

diff  --git a/clang/test/Analysis/stack-addr-ps.cpp b/clang/test/Analysis/stack-addr-ps.cpp
index 35f38fbbfbefdc..73e9dbeca460f6 100644
--- a/clang/test/Analysis/stack-addr-ps.cpp
+++ b/clang/test/Analysis/stack-addr-ps.cpp
@@ -1,10 +1,23 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s -Wno-undefined-bool-conversion
+// RUN: %clang_analyze_cc1 \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -verify %s \
+// RUN:   -Wno-undefined-bool-conversion
+// RUN: %clang_analyze_cc1 \
+// RUN:   -analyzer-checker=core,debug.ExprInspection,unix.Malloc \
+// RUN:   -verify %s \
+// RUN:   -Wno-undefined-bool-conversion
+// unix.Malloc is necessary to model __builtin_alloca,
+// which could trigger an "unexpected region" bug in StackAddrEscapeChecker.
 
 typedef __INTPTR_TYPE__ intptr_t;
 
 template <typename T>
 void clang_analyzer_dump(T x);
 
+using size_t = decltype(sizeof(int));
+void * malloc(size_t size);
+void free(void*);
+
 const int& g() {
   int s;
   return s; // expected-warning{{Address of stack memory associated with local variable 's' returned}} expected-warning{{reference to stack memory associated with local variable 's' returned}}
@@ -846,3 +859,21 @@ void top(char **p) {
   foo(); // no-warning FIXME: p binding is reclaimed before the function end
 }
 } // namespace early_reclaim_dead_limitation
+
+namespace alloca_region_pointer {
+void callee(char **pptr) {
+  char local;
+  *pptr = &local;
+} // no crash
+
+void top_alloca_no_crash_fn() {
+  char **pptr = (char**)__builtin_alloca(sizeof(char*));
+  callee(pptr);
+}
+
+void top_malloc_no_crash_fn() {
+  char **pptr = (char**)malloc(sizeof(char*));
+  callee(pptr);
+  free(pptr);
+}
+} // namespace alloca_region_pointer


        


More information about the cfe-commits mailing list