[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