[clang] [clang][analyzer] Teach the BlockInCriticalSectionChecker about O_NONBLOCK streams (PR #127049)

via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 17 04:06:40 PST 2025


================
@@ -337,6 +391,28 @@ void BlockInCriticalSectionChecker::reportBlockInCritSection(
      << "' inside of critical section";
   auto R = std::make_unique<PathSensitiveBugReport>(BlockInCritSectionBugType,
                                                     os.str(), ErrNode);
+  // for 'read' and 'recv' call, check whether it's file descriptor(first
+  // argument) is
+  // created by 'open' API with O_NONBLOCK flag or is equal to -1, they will
+  // not cause block in these situations, don't report
+  StringRef FuncName = Call.getCalleeIdentifier()->getName();
+  if (FuncName == "read" || FuncName == "recv") {
+    SVal SV = Call.getArgSVal(0);
+    SValBuilder &SVB = C.getSValBuilder();
+    ProgramStateRef state = C.getState();
+    ConditionTruthVal CTV =
+        state->areEqual(SV, SVB.makeIntVal(-1, C.getASTContext().IntTy));
+    if (CTV.isConstrainedTrue())
+      return;
+
+    if (SymbolRef SR = SV.getAsSymbol()) {
+      if (!O_NONBLOCKValue)
+        O_NONBLOCKValue = tryExpandAsInteger(
----------------
flovent wrote:

there will not be a unwrap empty option operation, `O_NONBLOCKValue`'s type is `std::optional<std::optional<int>>` right now, for just calling `tryExpandAsInteger` once.
so  `O_NONBLOCKValue` is definitely not empty after `tryExpandAsInteger` no matter it fails or not, and `*O_NONBLOCKValue` will only be true when `tryExpandAsInteger` success, then `**O_NONBLOCKValue` is ok to get the final marco value.

https://github.com/llvm/llvm-project/pull/127049


More information about the cfe-commits mailing list