Skip to content

Commit be0b114

Browse files
authored
[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`.
1 parent d479849 commit be0b114

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

Diff for: clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@ static std::optional<std::string> printReferrer(const MemRegion *Referrer) {
337337
// warn_bind_ref_member_to_parameter or
338338
// warn_init_ptr_member_to_parameter_addr
339339
return std::nullopt;
340+
} else if (isa<AllocaRegion>(Referrer)) {
341+
// Skip alloca() regions, they indicate advanced memory management
342+
// and higher likelihood of CSA false positives.
343+
return std::nullopt;
340344
} else {
341345
assert(false && "Unexpected referrer region type.");
342346
return std::nullopt;

Diff for: clang/test/Analysis/stack-addr-ps.cpp

+32-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
1-
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s -Wno-undefined-bool-conversion
1+
// RUN: %clang_analyze_cc1 \
2+
// RUN: -analyzer-checker=core,debug.ExprInspection \
3+
// RUN: -verify %s \
4+
// RUN: -Wno-undefined-bool-conversion
5+
// RUN: %clang_analyze_cc1 \
6+
// RUN: -analyzer-checker=core,debug.ExprInspection,unix.Malloc \
7+
// RUN: -verify %s \
8+
// RUN: -Wno-undefined-bool-conversion
9+
// unix.Malloc is necessary to model __builtin_alloca,
10+
// which could trigger an "unexpected region" bug in StackAddrEscapeChecker.
211

312
typedef __INTPTR_TYPE__ intptr_t;
413

514
template <typename T>
615
void clang_analyzer_dump(T x);
716

17+
using size_t = decltype(sizeof(int));
18+
void * malloc(size_t size);
19+
void free(void*);
20+
821
const int& g() {
922
int s;
1023
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) {
846859
foo(); // no-warning FIXME: p binding is reclaimed before the function end
847860
}
848861
} // namespace early_reclaim_dead_limitation
862+
863+
namespace alloca_region_pointer {
864+
void callee(char **pptr) {
865+
char local;
866+
*pptr = &local;
867+
} // no crash
868+
869+
void top_alloca_no_crash_fn() {
870+
char **pptr = (char**)__builtin_alloca(sizeof(char*));
871+
callee(pptr);
872+
}
873+
874+
void top_malloc_no_crash_fn() {
875+
char **pptr = (char**)malloc(sizeof(char*));
876+
callee(pptr);
877+
free(pptr);
878+
}
879+
} // namespace alloca_region_pointer

0 commit comments

Comments
 (0)