Skip to content

Commit

Permalink
[analyzer][StackAddrEscapeChecker] Fix assert failure for alloca regions
Browse files Browse the repository at this point in the history
Fixes llvm#107852

Make it explicit that the checker skips alloca regions to avoid the risc
of producing false positives for code that has advnaced 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 committed Sep 23, 2024
1 parent 8b4b7d2 commit b69749a
Show file tree
Hide file tree
Showing 2 changed files with 32 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
29 changes: 28 additions & 1 deletion clang/test/Analysis/stack-addr-ps.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// 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,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;

Expand Down Expand Up @@ -846,3 +851,25 @@ void top(char **p) {
foo(); // no-warning FIXME: p binding is reclaimed before the function end
}
} // namespace early_reclaim_dead_limitation

using size_t = decltype(sizeof(int));
void * malloc(size_t size);
void free(void*);

namespace alloca_region_pointer {
void callee(char **pptr) {
char local;
*pptr = &local;
}

void top_alloca_no_crash() {
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 b69749a

Please sign in to comment.