[clang] 3a6ee4f - [analyzer][StackAddressEscape] Tie warnings to the diagnostic checkers rather then core.StackAddrEscapeBase
Kirstóf Umann via cfe-commits
cfe-commits at lists.llvm.org
Tue May 19 17:26:52 PDT 2020
Author: Kirstóf Umann
Date: 2020-05-20T02:26:40+02:00
New Revision: 3a6ee4fefec0bc97a0340ddc33e7a8ffd4590ad5
URL: https://github.com/llvm/llvm-project/commit/3a6ee4fefec0bc97a0340ddc33e7a8ffd4590ad5
DIFF: https://github.com/llvm/llvm-project/commit/3a6ee4fefec0bc97a0340ddc33e7a8ffd4590ad5.diff
LOG: [analyzer][StackAddressEscape] Tie warnings to the diagnostic checkers rather then core.StackAddrEscapeBase
Differential Revision: https://reviews.llvm.org/D78101
Added:
Modified:
clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
clang/test/Analysis/incorrect-checker-names.cpp
clang/test/Analysis/incorrect-checker-names.mm
Removed:
################################################################################
diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index 237053df7e44..49ab25eca2dd 100644
--- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -78,13 +78,16 @@ class BuiltinBug : public BugType {
const char *description)
: BugType(checker, name, categories::LogicError), desc(description) {}
+ BuiltinBug(class CheckerNameRef checker, const char *name)
+ : BugType(checker, name, categories::LogicError), desc(name) {}
+
BuiltinBug(const CheckerBase *checker, const char *name)
: BugType(checker, name, categories::LogicError), desc(name) {}
StringRef getDescription() const { return desc; }
};
-} // end ento namespace
+} // namespace ento
} // end clang namespace
#endif
diff --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index 21fc65a8e4f1..b5c9356322fc 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -43,6 +43,7 @@ class StackAddrEscapeChecker
};
DefaultBool ChecksEnabled[CK_NumCheckKinds];
+ CheckerNameRef CheckNames[CK_NumCheckKinds];
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
@@ -156,7 +157,8 @@ void StackAddrEscapeChecker::EmitStackError(CheckerContext &C,
return;
if (!BT_returnstack)
BT_returnstack = std::make_unique<BuiltinBug>(
- this, "Return of address to stack-allocated memory");
+ CheckNames[CK_StackAddrEscapeChecker],
+ "Return of address to stack-allocated memory");
// Generate a report for this bug.
SmallString<128> buf;
llvm::raw_svector_ostream os(buf);
@@ -195,7 +197,8 @@ void StackAddrEscapeChecker::checkAsyncExecutedBlockCaptures(
continue;
if (!BT_capturedstackasync)
BT_capturedstackasync = std::make_unique<BuiltinBug>(
- this, "Address of stack-allocated memory is captured");
+ CheckNames[CK_StackAddrAsyncEscapeChecker],
+ "Address of stack-allocated memory is captured");
SmallString<128> Buf;
llvm::raw_svector_ostream Out(Buf);
SourceRange Range = genName(Out, Region, C.getASTContext());
@@ -218,7 +221,8 @@ void StackAddrEscapeChecker::checkReturnedBlockCaptures(
continue;
if (!BT_capturedstackret)
BT_capturedstackret = std::make_unique<BuiltinBug>(
- this, "Address of stack-allocated memory is captured");
+ CheckNames[CK_StackAddrEscapeChecker],
+ "Address of stack-allocated memory is captured");
SmallString<128> Buf;
llvm::raw_svector_ostream Out(Buf);
SourceRange Range = genName(Out, Region, C.getASTContext());
@@ -277,7 +281,7 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,
// The CK_CopyAndAutoreleaseBlockObject cast causes the block to be copied
// so the stack address is not escaping here.
- if (auto *ICE = dyn_cast<ImplicitCastExpr>(RetE)) {
+ if (const auto *ICE = dyn_cast<ImplicitCastExpr>(RetE)) {
if (isa<BlockDataRegion>(R) &&
ICE->getCastKind() == CK_CopyAndAutoreleaseBlockObject) {
return;
@@ -333,7 +337,8 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
if (!BT_stackleak)
BT_stackleak = std::make_unique<BuiltinBug>(
- this, "Stack address stored into global variable",
+ CheckNames[CK_StackAddrEscapeChecker],
+ "Stack address stored into global variable",
"Stack address was saved into a global variable. "
"This is dangerous because the address will become "
"invalid after returning from the function");
@@ -371,14 +376,13 @@ bool ento::shouldRegisterStackAddrEscapeBase(const CheckerManager &mgr) {
#define REGISTER_CHECKER(name) \
void ento::register##name(CheckerManager &Mgr) { \
- StackAddrEscapeChecker *Chk = \
- Mgr.getChecker<StackAddrEscapeChecker>(); \
+ StackAddrEscapeChecker *Chk = Mgr.getChecker<StackAddrEscapeChecker>(); \
Chk->ChecksEnabled[StackAddrEscapeChecker::CK_##name] = true; \
+ Chk->CheckNames[StackAddrEscapeChecker::CK_##name] = \
+ Mgr.getCurrentCheckerName(); \
} \
\
- bool ento::shouldRegister##name(const CheckerManager &mgr) { \
- return true; \
- }
+ bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
REGISTER_CHECKER(StackAddrEscapeChecker)
REGISTER_CHECKER(StackAddrAsyncEscapeChecker)
diff --git a/clang/test/Analysis/incorrect-checker-names.cpp b/clang/test/Analysis/incorrect-checker-names.cpp
index 3519e1509d10..9854a503fc4f 100644
--- a/clang/test/Analysis/incorrect-checker-names.cpp
+++ b/clang/test/Analysis/incorrect-checker-names.cpp
@@ -5,9 +5,16 @@
int* stack_addr_escape_base() {
int x = 0;
// FIXME: This shouldn't be tied to a modeling checker.
- return &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned to caller [core.StackAddrEscapeBase]}}
+ return &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned to caller [core.StackAddressEscape]}}
// expected-note-re at -1{{{{^Address of stack memory associated with local variable 'x' returned to caller$}}}}
// Just a regular compiler warning.
// expected-warning at -3{{address of stack memory associated with local variable 'x' returned}}
}
+char const *p;
+
+void f0() {
+ char const str[] = "This will change";
+ p = str;
+} // expected-warning{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
+// expected-note at -1{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
diff --git a/clang/test/Analysis/incorrect-checker-names.mm b/clang/test/Analysis/incorrect-checker-names.mm
index 11b6a21a14a9..861f81e98eb1 100644
--- a/clang/test/Analysis/incorrect-checker-names.mm
+++ b/clang/test/Analysis/incorrect-checker-names.mm
@@ -1,5 +1,6 @@
-// RUN: %clang_analyze_cc1 -fblocks -verify %s -Wno-objc-root-class \
+// RUN: %clang_analyze_cc1 -fblocks -fobjc-arc -verify %s -Wno-objc-root-class \
// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=alpha.core.StackAddressAsyncEscape \
// RUN: -analyzer-checker=nullability \
// RUN: -analyzer-checker=osx
@@ -126,3 +127,32 @@ void use_out_param_leak() {
// FIXME: This shouldn't be tied to a modeling checker.
write_into_out_param_on_success(&obj); // expected-warning{{Potential leak of an object stored into 'obj' [osx.cocoa.RetainCountBase]}}
}
+
+typedef struct dispatch_queue_s *dispatch_queue_t;
+typedef void (^dispatch_block_t)(void);
+void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
+typedef long dispatch_once_t;
+void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
+typedef long dispatch_time_t;
+void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
+void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);
+
+extern dispatch_queue_t queue;
+extern dispatch_once_t *predicate;
+extern dispatch_time_t when;
+
+dispatch_block_t get_leaking_block() {
+ int leaked_x = 791;
+ int *p = &leaked_x;
+ return ^void(void) {
+ *p = 1;
+ };
+ // expected-warning at -3 {{Address of stack memory associated with local variable 'leaked_x' \
+is captured by a returned block [core.StackAddressEscape]}}
+}
+
+void test_returned_from_func_block_async() {
+ dispatch_async(queue, get_leaking_block());
+ // expected-warning at -1 {{Address of stack memory associated with local variable 'leaked_x' \
+is captured by an asynchronously-executed block [alpha.core.StackAddressAsyncEscape]}}
+}
More information about the cfe-commits
mailing list