llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Balázs Benics (steakhal)

<details>
<summary>Changes</summary>

Node creation (addTransition, addSink, generateNonFatalErrorNode) returns null 
when the node already exists or the state is overconstrained. Several callers 
dereferenced or reported against the result unchecked.

Fixes:
- MPIChecker: 3 sites (double nonblocking, unmatched/missing wait)
- NullabilityChecker: reportBugIfInvariantHolds got null from 4 callers and 
from its own addTransition
- DynamicTypeChecker, DynamicTypePropagation, PutenvStackArrayChecker
- Unit test checkers that fed addSink() into a bug report unchecked

Fixes #<!-- -->64647
Authored-By: Claude

---
Full diff: https://github.com/llvm/llvm-project/pull/238414.diff


8 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp (+4-2) 
- (modified) clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp 
(+2-2) 
- (modified) clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp (+6) 
- (modified) clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp (+4) 
- (modified) clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp (+2) 
- (modified) clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp 
(+2) 
- (modified) clang/unittests/StaticAnalyzer/CheckLifetimeEndTest.cpp (+1-1) 
- (modified) clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp 
(+3-2) 


``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
index 40941f09df511b..7a60f37ef35278 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
@@ -72,8 +72,10 @@ void DynamicTypeChecker::reportTypeError(QualType 
DynamicType,
   QualType::print(StaticType.getTypePtr(), Qualifiers(), OS, C.getLangOpts(),
                   llvm::Twine());
   OS << "'";
-  auto R = std::make_unique<PathSensitiveBugReport>(
-      BT, OS.str(), C.generateNonFatalErrorNode());
+  ExplodedNode *N = C.generateNonFatalErrorNode();
+  if (!N)
+    return;
+  auto R = std::make_unique<PathSensitiveBugReport>(BT, OS.str(), N);
   R->markInteresting(Reg);
   R->addVisitor(std::make_unique<DynamicTypeBugVisitor>(Reg));
   R->addRange(ReportedNode->getSourceRange());
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp 
b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 6eb57698102124..c5587c1a146557 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -887,8 +887,8 @@ void DynamicTypePropagation::checkPreObjCMessage(const 
ObjCMethodCall &M,
     // Warn when argument is incompatible with the parameter.
     if (!ASTCtxt.canAssignObjCInterfaces(ParamObjectPtrType,
                                          ArgObjectPtrType)) {
-      ExplodedNode *N = C.generateNonFatalErrorNode(State);
-      reportGenericsBug(ArgObjectPtrType, ParamObjectPtrType, N, Sym, C, Arg);
+      if (ExplodedNode *N = C.generateNonFatalErrorNode(State))
+        reportGenericsBug(ArgObjectPtrType, ParamObjectPtrType, N, Sym, C, 
Arg);
       return;
     }
   }
diff --git a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
index 2932cc1336571c..903a6b9586a3e3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
@@ -43,6 +43,8 @@ void MPIChecker::checkDoubleNonblocking(const CallEvent 
&PreCallEvent,
   // double nonblocking detected
   if (Req && Req->CurrentState == Request::State::Nonblocking) {
     ExplodedNode *ErrorNode = Ctx.generateNonFatalErrorNode();
+    if (!ErrorNode)
+      return;
     BReporter.reportDoubleNonblocking(PreCallEvent, *Req, MR, ErrorNode,
                                       Ctx.getBugReporter());
     Ctx.addTransition(ErrorNode->getState(), ErrorNode);
@@ -82,6 +84,8 @@ void MPIChecker::checkUnmatchedWaits(const CallEvent 
&PreCallEvent,
     if (!Req) {
       if (!ErrorNode) {
         ErrorNode = Ctx.generateNonFatalErrorNode(State);
+        if (!ErrorNode)
+          return;
         State = ErrorNode->getState();
       }
       // A wait has no matching nonblocking call.
@@ -113,6 +117,8 @@ void MPIChecker::checkMissingWaits(SymbolReaper &SymReaper,
 
         if (!ErrorNode) {
           ErrorNode = Ctx.generateNonFatalErrorNode(State);
+          if (!ErrorNode)
+            return;
           State = ErrorNode->getState();
         }
         BReporter.reportMissingWait(Req.second, Req.first, ErrorNode,
diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
index e1c7f7ec62150c..fd82fa2ff92a58 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
@@ -477,6 +477,8 @@ void NullabilityChecker::reportBugIfInvariantHolds(
     StringRef Msg, ErrorKind Error, const BugType &BT, ExplodedNode *N,
     const MemRegion *Region, CheckerContext &C, const Stmt *ValueExpr,
     bool SuppressPath) const {
+  if (!N)
+    return;
   ProgramStateRef OriginalState = N->getState();
 
   if (checkInvariantViolation(OriginalState, N, C))
@@ -484,6 +486,8 @@ void NullabilityChecker::reportBugIfInvariantHolds(
   if (SuppressPath) {
     OriginalState = OriginalState->set<InvariantViolated>(true);
     N = C.addTransition(OriginalState, N);
+    if (!N)
+      return;
   }
 
   reportBug(Msg, Error, BT, N, Region, C.getBugReporter(), ValueExpr);
diff --git a/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp
index 69913d92d23c4f..a1bf32239f3f30 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PutenvStackArrayChecker.cpp
@@ -59,6 +59,8 @@ void PutenvStackArrayChecker::checkPostCall(const CallEvent 
&Call,
   StringRef ErrorMsg = "The 'putenv' function should not be called with "
                        "arrays that have automatic storage";
   ExplodedNode *N = C.addSink();
+  if (!N)
+    return;
   auto Report = std::make_unique<PathSensitiveBugReport>(BT, ErrorMsg, N);
 
   // Track the argument.
diff --git a/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp 
b/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp
index b757777a4a8070..3e13222f38ca8d 100644
--- a/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp
+++ b/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp
@@ -98,6 +98,8 @@ void InterestingnessTestChecker::handleCheck(const CallEvent 
&Call,
 void InterestingnessTestChecker::handleBug(const CallEvent &Call,
                                            CheckerContext &C) const {
   ExplodedNode *N = C.addSink();
+  if (!N)
+    return;
   C.emitReport(
       std::make_unique<PathSensitiveBugReport>(BT_TestBug, "test bug", N));
 }
diff --git a/clang/unittests/StaticAnalyzer/CheckLifetimeEndTest.cpp 
b/clang/unittests/StaticAnalyzer/CheckLifetimeEndTest.cpp
index 03185f63b5fc83..59e6b5dbaa1488 100644
--- a/clang/unittests/StaticAnalyzer/CheckLifetimeEndTest.cpp
+++ b/clang/unittests/StaticAnalyzer/CheckLifetimeEndTest.cpp
@@ -41,7 +41,7 @@ class LifetimeEndReporter : public 
Checker<check::LifetimeEnd> {
                                      D->getDeclName().getAsString(), Count);
 
     ExplodedNode *Node = C.generateNonFatalErrorNode(State);
-    EXPECT_TRUE(Node != nullptr);
+    ASSERT_TRUE(Node != nullptr);
 
     auto Report = std::make_unique<PathSensitiveBugReport>(
         LifetimeEndNode, Description.str(), Node);
diff --git a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp 
b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
index 12c0387de6ae9c..9a55d156962701 100644
--- a/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
+++ b/clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
@@ -93,8 +93,9 @@ class CheckerRegistrationOrderPrinter
 
 public:
   void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
-    ExplodedNode *N = nullptr;
-    N = C.addSink();
+    ExplodedNode *N = C.addSink();
+    if (!N)
+      return;
     llvm::SmallString<200> Buf;
     llvm::raw_svector_ostream OS(Buf);
     C.getAnalysisManager()

``````````

</details>


https://github.com/llvm/llvm-project/pull/238414
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to