================ @@ -315,16 +342,54 @@ bool BlockInCriticalSectionChecker::isBlockingInCritSection( void BlockInCriticalSectionChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { if (isBlockingInCritSection(Call, C)) { + // 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") { + const auto *Arg = Call.getArgExpr(0); + if (!Arg) + return; + + SVal SV = C.getSVal(Arg); + if (const auto *IntValue = SV.getAsInteger()) { + if (*IntValue == -1) + return; + } + + SymbolRef SR = C.getSVal(Arg).getAsSymbol(); + if (SR && C.getState()->contains<NonBlockFileDescriptor>(SR)) { + return; + } + } reportBlockInCritSection(Call, C); } else if (std::optional<MutexDescriptor> LockDesc = checkDescriptorMatch(Call, C, /*IsLock=*/true)) { handleLock(*LockDesc, Call, C); } else if (std::optional<MutexDescriptor> UnlockDesc = checkDescriptorMatch(Call, C, /*IsLock=*/false)) { handleUnlock(*UnlockDesc, Call, C); + } else if (OpenFunction.matches(Call)) { + handleOpen(Call, C); } } +void BlockInCriticalSectionChecker::checkDeadSymbols(SymbolReaper &SymReaper, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + + // Remove the dead symbols from the NonBlockFileDescriptor set. + NonBlockFileDescriptorTy Tracked = State->get<NonBlockFileDescriptor>(); + for (SymbolRef SR : Tracked) { + if (SymReaper.isDead(SR)) { + State = State->remove<NonBlockFileDescriptor>(SR); + } + } + + C.addTransition(State); +} + ---------------- steakhal wrote:
Well, I guess this is the price for using the approach of storing the symbols of non blocking FDs. If we hadn't done that, but rather just use the Bug visitor to walk to the `open` and then get the sval of the second arg of the open and check if it fits the mask, then we wouldn't need this trait, thus we wouldn't need to clean it up. I'm fine how it looks btw. I'm just thinking loud here. https://github.com/llvm/llvm-project/pull/127049 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits