Index: cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -160,6 +160,26 @@ return InEH->count(D); } + bool isSuppressed(SourceRange R) { + SourceManager &SMgr = Ctx.getSourceManager(); + SourceLocation Loc = R.getBegin(); + if (!Loc.isValid()) + return false; + + FileID FID = SMgr.getFileID(Loc); + bool Invalid = false; + StringRef Data = SMgr.getBufferData(FID, &Invalid); + if (Invalid) + return false; + + // Files autogenerated by DriverKit IIG contain some dead stores that + // we don't want to report. + if (Data.startswith("/* iig generated from")) + return true; + + return false; + } + void Report(const VarDecl *V, DeadStoreKind dsk, PathDiagnosticLocation L, SourceRange R) { if (Escaped.count(V)) @@ -175,6 +195,9 @@ if (!reachableCode->isReachable(currentBlock)) return; + if (isSuppressed(R)) + return; + SmallString<64> buf; llvm::raw_svector_ostream os(buf); const char *BugType = nullptr; Index: cfe/trunk/test/Analysis/deadstores-driverkit.cpp =================================================================== --- cfe/trunk/test/Analysis/deadstores-driverkit.cpp +++ cfe/trunk/test/Analysis/deadstores-driverkit.cpp @@ -0,0 +1,24 @@ +/* iig generated from SomethingSomething.iig */ + +// The comment above is the whole point of the test. +// That's how the suppression works. +// It needs to be on the top. +// Run-lines can wait. + +// RUN: %clang_analyze_cc1 -w -triple x86_64-apple-driverkit19.0 \ +// RUN: -analyzer-checker=deadcode -verify %s + +// expected-no-diagnostics + +#include "os_object_base.h" + +class OSSomething { + kern_return_t Invoke(const IORPC); + void foo(OSDispatchMethod supermethod) { + kern_return_t ret; + IORPC rpc; + // Test the DriverKit specific suppression in the dead stores checker. + if (supermethod) ret = supermethod((OSObject *)this, rpc); // no-warning + else ret = ((OSObject *)this)->Invoke(rpc); // no-warning + } +}; Index: cfe/trunk/test/Analysis/os_object_base.h =================================================================== --- cfe/trunk/test/Analysis/os_object_base.h +++ cfe/trunk/test/Analysis/os_object_base.h @@ -19,6 +19,9 @@ using size_t = decltype(sizeof(int)); +typedef int kern_return_t; +struct IORPC {}; + struct OSMetaClass; struct OSMetaClassBase { @@ -37,8 +40,13 @@ virtual void free(); virtual ~OSMetaClassBase(){}; + + kern_return_t Invoke(IORPC invoke); }; +typedef kern_return_t (*OSDispatchMethod)(OSMetaClassBase *self, + const IORPC rpc); + struct OSObject : public OSMetaClassBase { virtual ~OSObject(){}