Skip to content

Commit

Permalink
[analyzer][StackAddrEscapeChecker] Fix assert failure for alloca regi…
Browse files Browse the repository at this point in the history
…ons (#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`.
  • Loading branch information
necto authored Sep 23, 2024
1 parent d479849 commit be0b114
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
4 changes: 4 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
33 changes: 32 additions & 1 deletion clang/test/Analysis/stack-addr-ps.cpp
Original file line number Diff line number Diff line change
@@ -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}}
Expand Down Expand Up @@ -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

0 comments on commit be0b114

Please sign in to comment.