[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